首页 > 其他分享 >第二届BMZCTF公开赛-easymisc

第二届BMZCTF公开赛-easymisc

时间:2023-06-19 22:02:33浏览次数:98  
标签:15 BMZCTF open hex 公开赛 wav easymisc data math



文章目录

  • 题目设计
  • 解题步骤(Writeup)



题目附件请自取:
链接:https://pan.baidu.com/s/1u8jiXfpD7HvoQTCe4fW80w 
提取码:4whw

题目设计

  • 考察知识点:数据处理wav文件头高低振幅转换LSB隐写
  • 题目思路:逆序字节流数据->wav文件->高低振幅转换->LSB隐写->异或测试

以下是设计题目时所用到的脚本

文件转换二进制01数据

from binascii import *

with open('1.png', 'rb') as f:#需要转换的文件
	with open('bin.txt', 'w') as f1:
		hex_data = hexlify(f.read()).decode()
		for i in range(0, len(hex_data), 2):
			data = '{:08b}'.format(int(hex_data[i:i+2], 16))
			f1.write(data)

二进制数据转换wav高低振幅

import wave,struct,random

sampleRate = 44100.0
obj = wave.open('sound.wav','w')
obj.setnchannels(1)
obj.setsampwidth(2)
obj.setframerate(sampleRate)

with open('bin.txt', 'r') as f:
    bin_data = f.read()
    for i in bin_data:
        if i == '1':
            if random.randint(0,1) == 1:
                obj.writeframesraw(struct.pack('<h', random.randint(30000, 32000)))
            else:
                obj.writeframesraw(struct.pack('<h', random.randint(-32000, -30000)))
        elif i == '0':
            if random.randint(0,1) == 1:
                obj.writeframesraw(struct.pack('<h', random.randint(18000, 20000)))
            else:
                obj.writeframesraw(struct.pack('<h', random.randint(-20000, -18000)))
        else:
            break
obj.close()

逆序文件字节流

from binascii import *

with open('sound.wav', 'rb') as f:
	hex_data = hexlify(f.read()).decode()[::-1]
	with open('sound', 'wb') as f1:
		for i in range(0, len(hex_data), 2):
			data = hex_data[i:i+2][::-1]
			f1.write(unhexlify(data))

对文件整体进行异或

from binascii import *

with open('qrcode.png', 'rb') as f:
	all_data = f.read()
	with open('data', 'wb') as f1:
		for i in range(len(all_data)):
			f.seek(i)
			data = int(hexlify(f.read(1)), 16)
			xor_data = '{:02x}'.format(data ^ 0x7f)
			f1.write(unhexlify(xor_data))

解题步骤(Writeup)

what文件开头并不是什么类型的文件头

第二届BMZCTF公开赛-easymisc_数据


文件尾发现端倪,RIFF、 WAVE、fmt等字样,很明显这是wav文件的文件头

第二届BMZCTF公开赛-easymisc_ci_02


使用Python简单处理、反转字节流数据等到正确的wav文件

from binascii import *

with open('what', 'rb') as f:
	hex_data = hexlify(f.read()).decode()[::-1]
	with open('data.wav', 'wb') as f1:
		for i in range(0, len(hex_data), 2):
			data = hex_data[i:i+2][::-1]
			f1.write(unhexlify(data))

得到的wav文件使用Audacity分析

第二届BMZCTF公开赛-easymisc_数据_03


第二届BMZCTF公开赛-easymisc_BMZCTF_04


通过分析不难发现,每一帧高低频区别明显,高频在一定的范围内,低频也在一定的范围内

首先来简单分析下振幅的规律

import wave

obj = wave.open('data.wav', 'r')
frames = obj.getnframes()
print("All Frames: {}".format(frames))
frames_data = obj.readframes(20).hex()#提取出前20帧的数据
for i in range(0, len(frames_data), 4):
	data = frames_data[i:i+4]
	real_data = int(data[2:] + data[:2], 16)
	data1 = data[2:] + data[:2]
	print("第{:<2}帧: {} => {}  真实数据值: {}".format(int((i+4)/4), data,data1 , real_data))

提取出来的每一帧的数据大小为两字节,且存储方式为小端存储,所以需要高字节位和低字节位换一下,然后转换成数值

第二届BMZCTF公开赛-easymisc_BMZCTF_05


先分析正振幅的数据值,通过多次尝试分析,基本就可以确认高振幅范围为:30000-32000,低振幅范围为:18000-20000

PS:分析高低振幅取值范围可以提升提取出来的帧数来进行更精确的判断

而负振幅数据无论高振幅还是低振幅,为什么都看起来都不在这个范围之内呢,明明从Audacity中观察到的波形的高低范围和正振幅范围都应该是一样的,而得到的数值确大相径庭呢?

我们知道如果是带符号的2字节整型的取值范围是:[-2^(15)] ~ [2^(15)-1]也就是-32768至32767之间

那么就能解释负振幅数据的问题了,很明显发生了溢出;需要对数值进行一个转换处理即可得到在范围内的正常的数据

>>> import math
>>> math.pow(2,15)-(45650-math.pow(2,15))
19886.0#第二帧
>>> math.pow(2,15)-(47417-math.pow(2,15))
18119.0#第三帧
>>> math.pow(2,15)-(33915-math.pow(2,15))
31621.0#第五帧
>>> math.pow(2,15)-(35258-math.pow(2,15))
30278.0#第十二帧

OK,这样就解决了负振幅数据转换的问题
接下来就直接使用Python简单处理,将高低振幅转换成二进制数据即可;然后将得到的二进制数据写成字节流转成文件

import wave, math, struct
from binascii import *

obj = wave.open('data.wav', 'r')
frames = obj.getnframes()
frames_data = obj.readframes(frames).hex()

bin_data = ''
for idx in range(0, len(frames_data), 4):
	data = frames_data[idx:idx+4]
	data = data[2:] + data[:2]
	if int(data, 16) <= 20000:
		bin_data += '0'
	elif int(data, 16) > 20000 and int(data, 16) <= 32000:
		bin_data += '1'
	elif int(data, 16) > math.pow(2, 15):
		overflow_data = math.pow(2, 15) - (int(data, 16) - math.pow(2, 15))
		if overflow_data > 20000 and overflow_data <= 32000:
			bin_data += '1'
		elif overflow_data <= 20000:
			bin_data += '0'

hex_data = ''
for idx in range(0, len(bin_data), 8):
	hex_data += '{:02x}'.format(int(bin_data[idx:idx+8], 2))

with open('data', 'wb') as f1:
	f1.write(unhexlify(hex_data))

第二届BMZCTF公开赛-easymisc_数据_06


得到一张PNG图片,从binwalk分析来看,文件尾附加了内容

第二届BMZCTF公开赛-easymisc_数据_07


第二届BMZCTF公开赛-easymisc_ci_08


附加内容直接看不出来什么,尝试对图片分析,发现存在无密码的LSB隐写

第二届BMZCTF公开赛-easymisc_BMZCTF_09

hint: xor [00-ff] which one?

提示异或一个范围内的一个值,即可猜测附加的数据是经过异或的;可以尝试提取开头的几个字节进行异或看看结果是否为常见文件类型的文件头;Python简单处理即可

head_bytes = 'F6 2F 31 38'
for n in range(0xff):
	hex_data = head_bytes.split(" ")
	xor_data = ''
	for data in hex_data:
		data = int(data, 16) ^ n
		xor_data += ' {:02x}'.format(data)
	print("XOR {:02x}: {}".format(n, xor_data))

从结果中可以发现出现了PNG文件头

第二届BMZCTF公开赛-easymisc_数据_10


将附加数据提取出来,使用010 Editor打开工具->十六进制运算->二进制异或

第二届BMZCTF公开赛-easymisc_数据_11


第二届BMZCTF公开赛-easymisc_ci_12


得到一张二维码,扫描即可得到flag

第二届BMZCTF公开赛-easymisc_ci_13

BMZCTF{755f3d5c-4817-4610-a377-68743f09e60a}


标签:15,BMZCTF,open,hex,公开赛,wav,easymisc,data,math
From: https://blog.51cto.com/u_16159500/6517856

相关文章

  • BUUCTF NewStarCTF 公开赛赛道Week2 Writeup
    文章目录WEEK2WEBWord-For-You(2Gen)IncludeOneUnserializeOneezAPIMISCYesecnodrumsticks2Coldwinds'sDesktop奇怪的二维码qsdz'sgirlfriend2WEEK2WEBWord-For-You(2Gen)题目描述哇哇哇,我把查询界面改了,现在你们不能从数据库中拿到东西了吧哈哈(不过为了调试的代码似乎忘......
  • BMZCTF:hitcon_2017_ssrfme
    http://bmzclub.cn/challenges#hitcon_2017_ssrfme<?php$sandbox="sandbox/".md5("orange".$_SERVER["REMOTE_ADDR"]);@mkdir($sandbox);@chdir($sandbox);$data=shell_exec("GET".escapeshe......
  • BMZCTF:suspicion
    http://bmzclub.cn/challenges#suspicionvolatility-fmem.vmemimageinfovolatility-fmem.vmem--profile=WinXPSP2x86pslist将可疑进程TrueCrypt.exe进程dump出来volatility-fmem.vmem--profile=WinXPSP2x86memdump-p2012-D./使用EFDD打开,具体操作步骤如下查看E盘......
  • BMZCTF:2020sdnisc-左上角的秘密
    http://bmzclub.cn/challenges#2020sdnisc-%E5%B7%A6%E4%B8%8A%E8%A7%92%E7%9A%84%E7%A7%98%E5%AF%86enc.py#encoding=utf-8flag_enc=open("flag_enc.hex","wb")deffile_encode(flag):i=1whileTrue:byte_str=flag.read(1)......
  • BMZCTF:2018 HEBTUCTF 你可能需要一个wireshark
    http://bmzclub.cn/challenges#2018%20HEBTUCTF%20%E4%BD%A0%E5%8F%AF%E8%83%BD%E9%9C%80%E8%A6%81%E4%B8%80%E4%B8%AAwiresharkyoujun.pcapng打开直接尝试搜索关键字tcpcontains"flag"追踪流找到一个flag.txt解码这串base64得到flagPSC:\Users\Administrator>php-r"var_d......
  • BMZCTF:insomniteaser_2019_l33t_hoster
    http://bmzclub.cn/challenges#insomniteaser_2019_l33t_hoster文件上传,/?source回显源码<?phpif(isset($_GET["source"]))die(highlight_file(__FILE__));session_start();if(!isset($_SESSION["home"])){$_SESSION["home"]=......
  • BMZCTF:2018 redhat NotOnlyWireshark
    http://bmzclub.cn/challenges#2018%20redhat%20NotOnlyWiresharkNotOnlyWireshark.pcapngname中的值很明显是zip字节流数据,将这些长度426的URL中的name值提取出来tshark-rNotOnlyWireshark.pcapng-ehttp.request.uri-Tfields-Y'http.request.uri'|grep-P'name=[A-F0-......
  • BMZCTF:oldmodem
    http://bmzclub.cn/challenges#oldmodem使用file命令查看下,发现是wav文件但是修改后缀为wav后缀后并没有看出什么也没听出什么然后根据题目名称得知这是modem文件,装个minimoden去识别这个文件直接kali中:sudoapt-getinstallminimodem这个题目原来还有个提示没给就是这个modem......
  • BMZCTF:2020sdnisc-过去和现在
    http://bmzclub.cn/challenges#2020sdnisc-%E8%BF%87%E5%8E%BB%E5%92%8C%E7%8E%B0%E5%9C%A8flag{fc25cbb7b85959fe03738241a96bf23d}......
  • BMZCTF:网鼎杯 2018 minified
    http://bmzclub.cn/challenges#%E7%BD%91%E9%BC%8E%E6%9D%AF%202018%20minifiedflag_enc.png使用stegsolve打开,将每个色道的零通道取出来Alpha0Red0Green0Blue0将Alpha0和Green0进行ImageCombiner,当XOR时出现flagflag{7bb6db9f-d2eb-4e69-8dee-0002ce1e07f9}......