写在前面

真真正正在机房通宵打的CTF比赛,打到四五点的时候昏过去了()

虽然是初赛但是强度也不一般。。

谍影重重6.0

拿到data.pcap后wireshark打开发现全是udp,根据题目描述:被捕前布置的监听设备中的加密信息,也就是说这个流量是跟音频相关的。

参考:SUCTF2025 WriteUp - Z3n1th Blog,在 分析 - 启用的协议 里面搜索rtp并且勾上 RTP_UDP 。然后 电话- RTP -RTP流,就能看到许多的数据了。

1760817252731

这些数据都是一些电话的数据,我们选中一个 play streams - 再在下面一栏选中对应的流,export - from cursor就可以导出了。

1760817494080

当然,我们实际导出之后就发现声音非常之小,在au里面增幅一下听的比较清楚。当然这种导出方法还是太繁琐了。

我们可以搜索一下怎么从pcap导出wav

1760832738182

参考从pcap文件提取转wav语音文件 | 洞香春

先转化成pcap,raw和txt

1
rtpbreak -r Data.pcap -g -m -d ./

会形成很多个文件,需要跑一会。

利用脚本都转化为wav,并且自动增幅一些,不然声音太小了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import os
import subprocess
import re

# 获取当前目录下所有文件
files = os.listdir(".")

# 匹配形如 rtp.0.X.raw 的文件
pattern = re.compile(r"rtp\.0\.(\d+)\.raw")

for file in files:
match = pattern.match(file)
if match:
num = match.group(1)
output_wav = f"{num}.wav"
print(f"[*] 正在转换并自动增幅:{file} -> {output_wav}")

try:
# 使用 sox 自动归一化增幅 (-n)
subprocess.run([
"sox", "-r8000", "-c1", "-t", "ul", file,
"-t", "wav", output_wav,
"gain", "-n"
], check=True)
except subprocess.CalledProcessError as e:
print(f"[!] 处理失败:{file},错误:{e}")

print("[✅] 所有文件已转换并自动增幅完成!")

利用ai语音转文字脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import whisper
import os

# ✅ 指定 ffmpeg 的路径
ffmpeg_path = r"E:\CTF\misc\3音频\ffmpeg\bin"
os.environ["PATH"] += os.pathsep + ffmpeg_path

# ✅ 指定 wav 文件所在文件夹
folder = r"E:\CTF\output"

print(f"[i] 当前工作目录: {os.getcwd()}")
print(f"[i] 目标文件夹: {folder}")
print(f"[i] ffmpeg 路径: {ffmpeg_path}")

# ✅ 检查 ffmpeg 是否可用
os.system("ffmpeg -version")

# ✅ 加载 Whisper 模型
print("[+] 正在加载 Whisper 模型...")
model = whisper.load_model("large-v3")

# ✅ 输出文件路径
output_file = os.path.join(folder, "output.txt")

with open(output_file, "w", encoding="utf-8") as f:
for i in range(1, 2602):
filename = os.path.join(folder, f"{i}.wav")

if not os.path.exists(filename):
print(f"[!] 跳过:{filename} 不存在")
f.write(f"{i}.wav: [文件不存在]\n")
continue

try:
print(f"[+] 正在处理 {filename} ...")
result = model.transcribe(filename, language="zh")
text = result["text"].strip()

# ✅ 同时输出到终端与文件
print(f"[✓] {i}.wav 转写结果:{text}")
f.write(f"{i}.wav: {text}\n")

except Exception as e:
print(f"[!] {filename} 转写失败: {e}")
f.write(f"{i}.wav: [识别失败]\n")

print(f"✅ 所有文件处理完毕,结果已保存到 {output_file}")

输出到output.txt,查看一番发现大多都是无意义的文字(误导性的文字)

1760872281436

往下翻看到:

1760872356364

发现有一条出现神秘的长串数字,回听一下

长串数字:

651 466 3145 1427 1616 6142 1466 0701 4566 6160 1411 4514 2607 1146 6660 1421 4371 6565 1421 4470

当然这串数字直接解密7z是解不开的,

我们仔细观察一下这串字符,便可以发现这串字符里面没有八,都是0-7以内的。

也就是说这串字符很可能是八进制串,我们重新二二三三分类一下65 146 63 145 142 71 61 66 142 146 60 70 145 66 61 60 141 145 142 60 71 146 66 60 142 143 71 65 65 142 144 70,随波逐流一下发现有:

1760832824116

5f3eb916bf08e610aeb09f60bc955bd8这个就可以解密7z了

解密出来是一段音频和一个txt

音频内容:

1
2
3
4
5
6
7
8
9
10
11
表兄近日可好?上回托您带的廿四旦秋茶,家母嘱咐务必在辰时正过三刻前送到,切记用金丝锦盒装妥。此处潮气重,莫让干货受了霉,若赶的及时,可赶的菊花开前,便可让铺子开张。

一切安好,我会按照要求准备好秋茶。我该送到何地?

送至双鲤湖西岸南山茶铺。放右边第二个橱柜,莫放错。

我已知悉你在哪边,可还安好?

一切安好,希望你我二人早日相见。

指日可待,茶叶送到了,但是晚了时日,茶铺看来只能另寻良辰吉日了。你在哪边?千万保重。

得到很多信息:

地点:双鲤湖西岸南山茶铺

日期:廿四->24

时间:辰时正过三刻,辰时正->8点,三刻->45分,即8点45分

但由于年份我们还不得知,hint中提醒我们要用到真实事件地点,于是问一遍ai,得知:

1760820151136

最后:1949年10月24日8时45分于双鲤湖西岸南山茶铺

flag:2a97dec80254cdb5c526376d0c683bdd

BlackPearl

拿到一个1200000_fc.raw,询问ai得知:

1760852795513

原始PCM数据,搜索得知跟采样率,无线电相关,1200000像是跟value有关。

我们使用gnuradio来raw转wav看看

1760863791456

注意这里variable的value的值需要改成1200000。

转wav看到

1760863960026

再看频谱图,往下拉,再放大一些,可以看到

1760864428469

一看就是摩斯密码,我们对照着手敲一下:

1
-.- .--- --.- -..- . .. .. ..--- .- ....- .- --.- .- -- ....- ... .-- -..- ... --.- ..- .- .. ..-. .- -.-- .- .- -.- .- .. -... --.- -.-. .- .- -... .... ..-. -.- . ....- ... ..-. -.- .- --.- -.. .... ... -.-- .- .- -... ..-. -.- .- .- --.- .- -.-. -- -..- .-- -.. ..--- .- .- --. .- .- .. -- --.. .-- --. -.-. --.. --.. --- --- .-. ....- .... .. -- .- -... .- .- -... --.- --... ...-- -..- ..- -.-. .--- --. -.- -..- --.. --.- .-. --. -.-. -... ...- --. --... .... --.- ..-. --- .-. .-- ....- .-- --. -.... -.. -..- -.- .- -.. -.-. -.- .-- ..-. .-. -- .-. ....- --- .. ...- .-. .... . -. ....- .... --.- -... -.- .--. --. -.. .-. . .--- .. -.-- . -... . --.- .--- ... -.-. .-.. --. -..- --.- ..- .- -.-- -.-. --.. -... .-- --- .--- ..... -... -.... ..-. .-.. --- .- -.-. -- .-- .--- --.. --... --... ...- ..-. ..-. ...-- .-- .-. .--- . ...-- .-- -..- ... -- .-.. . -..- .--- .- ..- -.-- --... -.... .-.. .... --.. -.-. .-- -.... .--- .--. -- --- --... -.... -.-. --. .... -.... -... .... . -... ... .--- -... .... --- ..... --. .- .... .... -. -... --. .. ..--- .- ....- --... -. -. -..- .-. --.- ..-. --.. ...-- ..--- .- --.- --- -..- --- ...- ... .-. .- -- -.-. --.- .. .- .-

放厨子里摩斯密码解密一下,再base32转化一下可以发现:

1760864574813

可以看到是rar文件。结果发现要密码。我们回到频谱图,往最后拉,大概在右上角的位置可以大概看到一串神秘数字:

1760864887226

大概在这个位置,能隐约看到数字,我们朝着这个地方细细调节一下:

bf5b757d22464865874bcc027854e3fb

可以看到大概:1d3 c8 cy582dd,有些地方看不太清打上掩码爆破一下1d3c8c??82d?

1760865363919

得到密码:1d3c8c7582dd,直接打开拿到flag

flag{fa61cde1c174b-79a8-5cb9-3ea464e3dbca}