0x01 赛题说明

0x02 曲折
题目很明显,就是一道 MP3的隐写题,按照常规思路,有三种思路:
- 直接右击txt打开,查找关键词 flag
- 查看该音频文件的波形图、频谱图,是否存在相关信息可以转化为摩斯电码
- 查看mp3 中是否含有隐藏文件,提取文件
第一种思路没报多大打算,果然没有:

第二个思路:
波形图:

频谱图

都没有任何有用的信息
第三种思路:使用MP3Steno提取 mp3 中可能存在的 TXT 文件,如下:

猜解出密码为icsc,提取成功:

就在我以为会有啥好结果出现的时候,打开文件:


这啥玩意?文件开头字节为 Yy,不是什么常见的文件格式,内容也基本上没有完整的有意义的字符串,一度陷入沉默……
想了半天没有结果,于是换思路。
Binwalk 发现:

存在一个 JPEG 文件,想了下,应该是专辑的封面,不确定是否有用,于是 strings:

发现有 PS 的痕迹,难道?
提取出图片:

尝试各种图片隐写的方法,均无果……遂放弃
0x03 题解(第四种)
赛后我问了一些师傅,最终知道了这题的解决方法。
首先回到题目里去,题目提示,通过某种 private 的方式传递信息
而当你用 010editor 打开该 Mp3 文件,并按照提示安装插件后,发现:

存在一个private bit
因此,只需要提取每一个 mf组中的该字节,组合起来,就是答案。
可以从图中看到 ms 开始位为1 C1B8H,即第 115128 字节

uint32 frame_sync : 12
uint32 mpeg_id : 1
uint32 layer_id : 2
uint32 protection_bit : 1
uint32 bitrate_index : 4
uint32 frequency_index : 2
uint32 padding_bit : 1
uint32 private_bit : 1
uint32 channel_mode : 2
uint32 mode_extension : 2
uint32 copyright : 1
uint32 original : 1
uint32 emphasis : 2
12+1+2+1+4+2+1+1+2+2+1+1+2=32
即 总共 4 字节,private_bit 为24,所在的字节为第 3 个字节
因此要从前一个,即第二个字节开始提取内容,该字节对应的地址为 115130
观察每一个 mf组

大小都为414h,即1044字节
因此可以得到以下脚本:
# coding:utf-8
import re
import binascii
n = 115130
result = ''
fina = ''
file = open('flag-woody.mp3','rb')
while n < 2222222 :
file.seek(n,0)
n += 1044
file_read_result = file.read(1)
read_content = bin(ord(file_read_result))[-1]
result = result + read_content
textArr = re.findall('.{'+str(8)+'}', result)
textArr.append(result[(len(textArr)*8):])
for i in textArr:
fina = fina + hex(int(i,2))[2:].strip('\n')
fina = fina.decode('hex')
print fina
最终得到 flag:

感谢Batsu师傅的帮助
De1CTF2020的 mc_easybgm也是第四种方法解答
访问页面,在源代码中找到 assets/bgm.mp3 路径,访问http://134.175.230.10/assets/bgm.mp3,右键查找页面信息,下载音频

编写脚本
import re import binascii n = 0x28a3 result = '' file = open('bgm.mp3','rb') file.seek(n, 0) def w(s): with open("1.txt", "a+") as f: f.write(s + "\n") for i in range(0, 3284): frame_hdr = file.read(4) hex_data = binascii.b2a_hex(frame_hdr).decode("utf8") bin_data = bin(int("0x" + hex_data,16)).replace("0b", "") w(bin_data) n += 0x1a1 file.seek(n, 0)
生成1.txt之后用notepad++打开按住Alt键向下拉动将第24比特(即第24列)复制出来,然后计算长度,选择最靠近的长度为336bit,多余的0删掉。得到
101111101000010010101110011010101000001001010110110011000010001011111010001000101000110001001110000011001110101011111010001011100110001000101100010010101100001011001100111011001001011010110010111110100000110000101110111110101100110010110110000011001100011010001100110011001110101011011110011000100010101011000010100011001010011000100010
反转得到
010001000110010100110001010000110101010001000110011110110101011100110011001100010110001100110000011011010011001101011111011101000011000001011111010011010110100100110111001100110100001101010010001101000100011001110100010111110101011100110000011100100011000101000100010111110100010000110011011010100100000101010110011101010010000101111101
最后转成ASCII码即可。
本文部分内容转自:https://www.cnpanda.net/ctf/342.html