[BUUCTF]洞拐洞拐洞洞拐
[BUUCTF] 洞拐洞拐洞洞拐
问题链接:https://buuoj.cn/challenges#洞拐洞拐洞洞拐
问题附件是一张图片。
一. 图片分析
查看图片,发现是由有规律的黑白像素构成的PNG图片,用Python脚本尝试以黑色为1,白色为0分别按行读取,发现00xxxxxx00.......的规律,按照char 型读取,发现都是可打印字符,读取及转换代码如下:
#使用:.\hb黑白像素块10.py 2239f085-4e8c-425b-9e8e-793c982c42f5.png
#author:CHTXRT
from PIL import Image
import sys
img = Image.open(sys.argv[1])
temp = ''
n = 0
for x in range(320):
for y in range(320):
n+=1
if(img.getpixel((x,y))==(255,255,255)):
temp += '0'
else:
temp += '1'
if(n==8):
n = 0
print(chr(int(temp,2)),end='')
temp = ''
img.close()
得到结果:
52494646FC18000057415645666D742010000000010001000A000000140000000200100064617461D8........(以下省略n行)
二. 音频分析
上边那串数据看起来像个文件,把它扔到编辑器里面,发现 .wav文件头。

改名2333.wav 保存,用Audacity 打开如图所示:

是个单声道音频(important),观察音频,列出部分音阶:
-0.5 -0.5 0.5 -0.5 0 -0.25 -0.5 -0.25 1.0 -0.5 -0.75 ......(以后省略n项)
发现每段只有 8 种可能:-0.75 -0.5 -0.25 0.0 0.25 0.5 0.75 1.0
盲猜一波八进制,转换前半部分得到 115132127107 ,如果按3个拆分,可以得到 77 90 87 71 ,都属于Ascii 可打印字符,用Python 脚本进行转换,代码如下:
#使用:.\wv音频处理.py 2333.wav
#author: CHTXRT
import sys
import wave
import struct
wav = wave.open(sys.argv[1],'r')
frame = wav.getnframes()
data = wav.readframes(frame)
h = [0]*(len(data)//2)
for i in range(len(data)//2):
h[i] = (struct.unpack('<h',data[i*2:i*2+2]))[0]
hmax = 32767
temp = ''
for i in range(0,len(h),10):
temp += str(round(h[i]/hmax*4)+3)
if(len(temp)==3):
print(chr(int(temp,8)),end='')
temp = ''
#其中 wave 转换采用的相关 wav 格式知识见下文第四节。
得到一段数据如下:
MZWGCZ33G44GGNRTHE3DEMZSGQ4TQMZQMY2WCNRZGZSDCOBYHBRGMMZUMFSWIMZSGVRTQY3DGIZWIZDBO5SDKML2PJYXUMRTGMZTGYLBPU
三. 编码分析
上边那段文字看起来像段密文,如果是做题做多了或者熟悉Base系列的同学可能会一眼盯真,看出前四个字正是flag的 Base32 编码,不熟悉的同学可以使用相关枚举脚本查看(懒得写了,以后可能补),解密明文如下:
flag{78c639623249830f5a696d1888bf34aed325c8cc23ddawd51zzqz23333aa}
四. wav 分析
本节作为补充知识,勉强算是我在编写上述脚本时学习的记录吧。
对于 wav 文件来说,它的音频由许多采样点构成,每个采样点占用 2 或 4 个字节(单声道音频就是 2 字节,双声道就是 4 个字节,高八位是左声道,第八位是右声道),每个声道的采样数据是一个短整数(int_8),同时我们还应该着重注意的是,wav 文件的数据是小端存储的,所以我们应该先读后四位,再读前四位 [1]。
#使用:.\wv音频处理.py 2333.wav
#author: CHTXRT
import sys
import wave
import struct
wav = wave.open(sys.argv[1],'r')
frame = wav.getnframes()
data = wav.readframes(frame)
h = [0]*(len(data)//2)
for i in range(len(data)//2):
h[i] = (struct.unpack('<h',data[i*2:i*2+2]))[0] #[1] unpack方法中的第一个参数中,‘<’代表小端存储读取
hmax = 32767
temp = ''
for i in range(0,len(h),10):
temp += str(round(h[i]/hmax*4)+3)
if(len(temp)==3):
print(chr(int(temp,8)),end='')
temp = ''
以上内容仅供参考,水平不高,大佬见笑。
下一篇文章:对如何在博客园中添加音乐播放器及设置自动播放的研究 ——CSDN
作者:CHTXRT
出处:https://www.cnblogs.com/chtxrt/
本站使用「CC BY-SA 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。
[BUUCTF]洞拐洞拐洞洞拐的更多相关文章
- 三维网格补洞算法(Poisson Method)
下面介绍一种基于Poisson方程的三角网格补洞方法.该算法首先需要根据孔洞边界生成一个初始化补洞网格,然后通过法向估算和Poisson方程来修正补洞网格中三角面片的几何形状,使其能够适应并与周围的原 ...
- TCP打洞和UDP打洞的区别 (转)
为什么网上讲到的P2P打洞基本上都是基于UDP协议的打洞?难道TCP不可能打洞?还是TCP打洞难于实现? 假设现在有内网客户端A和内网客户端B,有公网服务端S. 如果A和B想要进行UD ...
- UDP 打洞 原理解释
终于找到了一份满意的UDP打洞原理解释,附上正文,自己整理了一下源码 3.3. UDP hole punching UDP打洞技术 The third technique, and the one o ...
- [转]UDP/TCP穿越NAT的P2P通信方法研究(UDP/TCP打洞 Hole Punching)
[转]UDP/TCP穿越NAT的P2P通信方法研究(UDP/TCP打洞 Hole Punching) http://www.360doc.com/content/12/0428/17/6187784 ...
- 【转】NAT路由器打洞原理
什么是打洞,为什么要打洞 由于Internet的快速发展 IPV4地址不够用,不能每个主机分到一个公网IP 所以使用NAT地址转换. 下面是我在网上找到的一副图 一般来说都是由私网内主机(例如上图中“ ...
- APUE学习笔记(2):lseek()练习与文件洞
对于lseek函数早在大一的C语言课上就有接触,但是几乎没有使用过,只记得是和文件偏移操作相关的 看了APUE上的示例,又使用od工具查看了内容,果然很神奇,很新鲜 figure3.2.c [c] # ...
- p2p 打洞技术
根据通信双方所处网络环境不同,点对点通信可以划分成以下三类:i> 公网:公网ii>公网:内网iii>内网:内网前两种容易实现,我们这里主要讨论第三种.这其中会涉及到NAT和NAPT的 ...
- P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...
- NAT穿透(UDP打洞)
1.NAT(Network Address Translator)介绍 NAT有两大类,基本NAT和NAPT. 1.1.基本NAT 静态NAT:一个公网IP对应一个内部IP,一对一转换 动态NAT:N ...
- UDP打洞原理及代码
来源:http://www.fenbi360.net/Content.aspx?id=1021&t=jc UDP"打洞"原理 1. NAT分类 根据Stun协议 ...
随机推荐
- Elasticsearch rest-high-level-client 基本操作
Elasticsearch rest-high-level-client 基本操作 本篇主要讲解一下 rest-high-level-client 去操作 Elasticsearch , 虽然这个客户 ...
- React实现一个简易版Swiper
背景 最近在公司内部进行一个引导配置系统的开发中,需要实现一个多图轮播的功能.到这时很多同学会说了,"那你直接用swiper不就好了吗?".但其实是,因为所有引导的展示都是作为np ...
- 基于Spring的发布订阅模式 EventListener
基于Spring的发布订阅模式 在我们使用spring开发应用时,经常会碰到要去解耦合一些依赖调用,比如我们在做代码的发布流程中,需要去通知相关的测试,开发人员关注发布中的错误信息.而且通知这个操作又 ...
- R数据分析:孟德尔随机化实操
好多同学询问孟德尔随机化的问题,我再来尝试着梳理一遍,希望对大家有所帮助,首先看下图1分钟,盯着看将下图印在脑海中: 上图是工具变量(不知道工具变量请翻之前的文章)的模式图,明确一个点:我们做孟德尔的 ...
- 【笔记】CF1714F Build a Tree and That Is It 及相关
题目传送门 细节较多的构造题. 解决思路 题目中虽然说是无根树,但我们可以钦定这棵树的根为 1,方便构造,这是不影响结果的. 以下记给定的三段长度为 \(a,b,c\) . 先考虑无解的情况. 首先, ...
- 2.mysql-库表行管理
1.数据库管理 1.1 SQL语句 1.1.1 查看当前所有的数据库 show databases; 1.1.2 创建数据库 create database 数据库名; create databse ...
- Go语言基础-从菜鸟到火鸡
课程介绍: 1.概述和环境搭建 2.程序开发 3.数据类型 4. 指针 5. 标志符 6. 运算符 7. 进制介绍 8.流程控制 9.循环控制 10.break与continue 11.函数 12.g ...
- dlv远端调试go的问题
1.golang采用dlv 时提示 "could not launch process: could not open debug info " 在用dlv 远程debug 代码时 ...
- Spark通过打jar包形式提交任务
idea构建项目 创建一个maven项目,配置pom依赖,以及scala编译插件. 注意一定要保证,你的scala版本和spark版本和要提交的集群版本一致,要不很多莫名其妙的问题,scala如果你在 ...
- C ++:树
C++:树 树的概念: 所谓"树"是输就结构的一种,树大概可以分为两大类: 有根树 和 无根树 有根树使有一个确定的根节点,反之为无根树 · 子节点:从树根开始,通过树边向下扩展的 ...