下午要考六级,考完之后立马收拾东西赶飞机去了,导致只有早上有空做题。只有
SMB,whiteout,The_Rogue_Beacon是赛中做的,其余为赛后复现。
Misc
SMB
Challenge
Do you know SMB?
Solution
使用在线工具 https://apackets.com/upload 提取 NTLMv2 哈希
参考 SwampCTF 2025 的 MuddyWater,我之前写的 WriteUp:https://www.aristore.top/posts/SwampCTF2025/#%F0%9F%94%81Planetary-Storage

用 hashcat 爆破哈希,密码本用 rockyou

得到密码 12megankirwin12
回到 Wireshark ,编辑 -> 首选项 -> NTLMSSP 填入密码

文件 -> 导出对象 -> SMB 将 letter.zip 导出
letter.zip 的加密算法是 ZipCrypto,因此可以尝试明文攻击
bkcrack.exe -C letter.zip -c letter.exe -x 0 4D5A -x 64 0E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000bkcrack 1.7.1 - 2024-12-21[10:04:22] Z reduction using 56 bytes of known plaintext100.0 % (56 / 56)[10:04:22] Attack on 141108 Z values at index 71Keys: 68cc45ab 864060ce ac958caa75.7 % (106781 / 141108)Found a solution. Stopping.You may resume the attack with the option: --continue-attack 106781[10:07:22] Keys68cc45ab 864060ce ac958caa得到 Keys 为 68cc45ab 864060ce ac958caa
运行 bkcrack -C letter.zip -c letter.exe -k 68cc45ab 864060ce ac958caa -d letter.exe 解压缩
逆向工程 letter.exe 发现程序在地址 0x1400A22A8 存储了 19 字节的加密数据,使用了异或加密,XOR key 是 0x42,密文是 24 2e 23 25 39 0c 72 35 1d 17 6f 14 73 21 36 2d 30 3b 3f

FLAG
flag{N0w_U-V1ctory}whiteout
Challenge
一份离线备份的 Docker 镜像。
Solution
镜像是为 arm64 架构构建的,但 Kali 是 amd64 架构
先安装 QEMU 用户模式模拟器
sudo apt updatesudo apt install -y qemu-user-static qemu-user binfmt-support然后重启系统服务
sudo systemctl restart systemd-binfmt.servicesudo systemctl restart docker验证安装是否成功
ls /proc/sys/fs/binfmt_misc/ | grep qemu-aarch64看到 qemu-aarch64 的输出说明已成功配置
以交互模式运行容器
docker run --platform linux/arm64 -it --name whiteout_container misc_docker_whiteoutroot@08e66dc2317c:/opt/app# lsdecode.py log.txtroot@08e66dc2317c:/opt/app# cat decode.py# decode.pyKEY = 0x37 def decode(path): with open(path, "rb") as f: data = f.read() return bytes(b ^ KEY for b in data) if __name__ == "__main__": print(decode("/opt/.data/.logs/syslog.bin"))root@08e66dc2317c:/opt/app# cat log.txtcleanup doneroot@08e66dc2317c:/opt/app# ls -ah /opt/.data/.logs. ..在 Docker 中 whiteout 是一种删除文件的机制,文件在容器层中被标记为已删除,实际数据可能仍存在于下层镜像中,因此可以尝试恢复 /opt/.data/.logs/syslog.bin
在宿主机查找镜像层存储位置
┌──(root㉿kali)-[~]└─# docker inspect misc_docker_whiteout | grep -A 10 "LowerDir" "LowerDir": "/var/lib/docker/overlay2/baea9fd8e87c332fd0252c7d0244ce33d764a776186af5d3cd6e0a90f4a0f2e7/diff:/var/lib/docker/overlay2/0307dc3238f0a22adbbec6b0c9014846164f3da11ea10aeda872d446937a77c3/diff:/var/lib/docker/overlay2/ab17a839c8b202fca45d45f3acb2284a82f5c3de316f4de4f32e91d63856566f/diff:/var/lib/docker/overlay2/92b6636503fa03f103c0c737a634e3ab0225df9cc125f8355ecf3a035de9f97b/diff:/var/lib/docker/overlay2/f71662a75b1dd27faf57b4ec3205795ff6dca31240dda9c0d02ca3a0d5db7dc9/diff:/var/lib/docker/overlay2/d75503f05017f8d71d5cd479c9c9b384a20fb33d96fa9679bf0025abcff27c23/diff", "MergedDir": "/var/lib/docker/overlay2/b01d7efeb8cd62c830ebf157dcdfec628aad47a86a924c641da123057f73781a/merged", "UpperDir": "/var/lib/docker/overlay2/b01d7efeb8cd62c830ebf157dcdfec628aad47a86a924c641da123057f73781a/diff", "WorkDir": "/var/lib/docker/overlay2/b01d7efeb8cd62c830ebf157dcdfec628aad47a86a924c641da123057f73781a/work" }, "Name": "overlay2" }, "RootFS": { "Type": "layers", "Layers": [ "sha256:b3f74c31dcaee85c6efbb1c8b30081ee1e7f2b11e841d4492217caa7d1681539",在宿主机逐个搜索每个层目录寻找 syslog.bin
find /var/lib/docker/overlay2/baea9fd8e87c332fd0252c7d0244ce33d764a776186af5d3cd6e0a90f4a0f2e7/diff -name "syslog.bin" 2>/dev/nullfind /var/lib/docker/overlay2/0307dc3238f0a22adbbec6b0c9014846164f3da11ea10aeda872d446937a77c3/diff -name "syslog.bin" 2>/dev/nullfind /var/lib/docker/overlay2/ab17a839c8b202fca45d45f3acb2284a82f5c3de316f4de4f32e91d63856566f/diff -name "syslog.bin" 2>/dev/nullfind /var/lib/docker/overlay2/92b6636503fa03f103c0c737a634e3ab0225df9cc125f8355ecf3a035de9f97b/diff -name "syslog.bin" 2>/dev/nullfind /var/lib/docker/overlay2/f71662a75b1dd27faf57b4ec3205795ff6dca31240dda9c0d02ca3a0d5db7dc9/diff -name "syslog.bin" 2>/dev/nullfind /var/lib/docker/overlay2/d75503f05017f8d71d5cd479c9c9b384a20fb33d96fa9679bf0025abcff27c23/diff -name "syslog.bin" 2>/dev/null┌──(root㉿kali)-[~]└─# find /var/lib/docker/overlay2/ab17a839c8b202fca45d45f3acb2284a82f5c3de316f4de4f32e91d63856566f/diff -name "syslog.bin" 2>/dev/null/var/lib/docker/overlay2/ab17a839c8b202fca45d45f3acb2284a82f5c3de316f4de4f32e91d63856566f/diff/opt/.data/.logs/syslog.bin将文件复制到宿主机
┌──(root㉿kali)-[~]└─# cp /var/lib/docker/overlay2/ab17a839c8b202fca45d45f3acb2284a82f5c3de316f4de4f32e91d63856566f/diff/opt/.data/.logs/syslog.bin /home/kali/Desktop ┌──(root㉿kali)-[~]└─# cd /home/kali/Desktop/ ┌──(root㉿kali)-[/home/kali/Desktop]└─# hexdump -C syslog.bin00000000 51 5b 56 50 4c 53 58 54 5c 52 45 68 40 5f 5e 43 |Q[VPLSXT\REh@_^C|00000010 52 58 42 43 68 51 58 45 52 59 44 5e 54 44 68 5e |RXBChQXERYD^TDh^|00000020 44 68 51 42 59 4a |DhQBYJ|00000026用 Docker 容器中的 decode.py 解密即可
FLAG
flag{docker_whiteout_forensics_is_fun}The_Rogue_Beacon
Challenge
某自动驾驶初创公司的测试车在进行极限速度测试时发生了数剧中断。竞争对手截获了测试期间的 CAN 总线广播数据。我们需要评估这辆原型车的动力性能极限。附件是一个.pcap 文件,记录了底盘动力域(Chassis Domain)的所有通信。请剥离出干扰数据,锁定车速信号,并向总部报告车辆达到的峰值速度发生的确切位置。
Solution
流量数据包带有空格在命令行可能出现问题,重命名为 The_Rogue_Beacon.pcapng
用 tshark 导出 CAN 数据
tshark -r The_Rogue_Beacon.pcapng -Y can -T fields -e frame.number -e can.id -e data > can_data.txt这是一个 CAN 总线数据分析问题
-
干扰数据识别逻辑:
- 在 CAN 总线中正常底盘数据是周期性的
- 干扰数据通常具有统计异常性,要么发送频率极低,要么发送间隔极度不规律
- 统计每个 ID 的出现频率,频率显著低于平均水平且 ID 孤立的判定为干扰帧
-
车速信号识别逻辑:
- 排除控制/开关量:控制指令只有几种状态(0/1,开/关),数值种类极少
- 排除循环计数器:计数器数值随时间呈锯齿状线性增长,但由于其位数短,唯一值数量远少于物理量
- 锁定物理模拟量:车速是一个高频变化的物理值,在测试中它是唯一一个不重复数值比例最高且数值分布呈现单峰平滑变化的信号
import osfrom collections import Counter def can_analysis(file_path): if not os.path.exists(file_path): print(f"Error: {file_path} not found.") return # 1. 原始数据解析 raw_packets = [] id_list = [] with open(file_path, 'r', encoding='utf-8') as f: for line in f: parts = line.strip().split() if len(parts) < 3: continue try: raw_packets.append({ 'line': int(parts[0]), 'id': parts[1], 'hex': parts[2], 'val': int(parts[2], 16) }) id_list.append(parts[1]) except ValueError: continue # 2. 统计每个 ID 的出现频率 id_counts = Counter(id_list) avg_freq = sum(id_counts.values()) / len(id_counts) # 3. 锁定干扰数据 # 干扰数据通常是发送次数最少,或者明显偏离正常周期频率的 ID # 这里我们取出现频率最低的 ID sorted_by_freq = sorted(id_counts.items(), key=lambda x: x[1]) interference_id = sorted_by_freq[0][0] # 4. 锁定车速信号 # 物理信号 ID 拥有最多的“唯一数值数量” # 因为它在加速和减速过程中几乎每一帧产生的物理值都不同 id_uniqueness = {} for packet in raw_packets: if packet['id'] == interference_id: continue # 排除干扰帧 if packet['id'] not in id_uniqueness: id_uniqueness[packet['id']] = set() id_uniqueness[packet['id']].add(packet['hex']) # 找到不重复数值最多的 ID speed_id = max(id_uniqueness, key=lambda k: len(id_uniqueness[k])) # 5. 在锁定的车速信号中寻找峰值 speed_packets = [p for p in raw_packets if p['id'] == speed_id] peak_packet = max(speed_packets, key=lambda x: x['val']) # --- 输出结论 --- print(f"[*] 发现干扰数据 ID : {interference_id}") print(f" (判定依据: 该 ID 出现频率最低,共 {id_counts[interference_id]} 次)") print(f"[*] 锁定车速信号 ID : {speed_id}") print(f" (判定依据: 数据熵最高,拥有 {len(id_uniqueness[speed_id])} 个独立物理状态)") print("-" * 50) print(f"[*] 车辆达到的极限峰值 : {peak_packet['val']}") print(f"[*] 峰值数据原始载荷 : {peak_packet['hex']}") print(f"[*] 峰值发生的行位置 : 第 {peak_packet['line']} 行") if __name__ == "__main__": can_analysis('can_data.txt')得到数据包序号为 12149
结果格式为 flag{sha256(数据包序号)}
FLAG
flag{9db878fd06dd7587a91c0fb600e0e9f7c3ea310e75f36253ef57ac2d92dd8c29}ZipCracker
Challenge
do u know zip and fm?
Solution
拿到压缩包的第一件事当然是试试是不是伪加密了,事实证明确实是
首先用 foremost 从 something in it.jpg 里提取出一个压缩包,里面有文件 flag1.txt 和 flag2.txt
接着看 do u know it,这是一个看起来像是配置文件的东西,直接拿去问 AI 就能判断出这是什么

从题目描述里的 fm 就能猜到 AI 给的答复应该没什么大问题
根据正向逻辑编写脚本还原输入的音频文件 password.wav
import numpy as npfrom scipy.io import wavfilefrom scipy import signal def restore_audio(): print("[-] Loading raw data files...") # GNU Radio File Sink 保存的是 raw binary float32 try: i_data = np.fromfile('flag1.txt', dtype=np.float32) q_data = np.fromfile('flag2.txt', dtype=np.float32) except FileNotFoundError: print("[!] Error: flag1.txt or flag2.txt not found.") return # 确保两个文件长度一致 min_len = min(len(i_data), len(q_data)) i_data = i_data[:min_len] q_data = q_data[:min_len] print(f"[-] Data loaded. Samples: {min_len}") # 1. 组合 I/Q 信号 (Complex IQ) # Z = I + jQ iq_signal = i_data + 1j * q_data print("[-] Demodulating FM signal...") # 2. FM 解调 (Quadrature Demodulation) # 原理: FM 信号的信息包含在瞬时频率中。 # 离散域中,瞬时频率与相邻采样点的相位差成正比。 #通过计算 sample[n] * conj(sample[n-1]) 的角度来获得相位差。 # 将信号错位 1 位进行共轭相乘 # angle( Z[n] * Z[n-1]* ) demodulated_signal = np.angle(iq_signal[1:] * np.conj(iq_signal[:-1])) # 3. 降采样 (Decimation) # 流图参数: # USRP Rate = 576k # IF Rate (quad_rate) = 576k / 3 = 192k (这是 flag 文件的采样率) # Audio Rate (samp_rate) = 48k # 因此需要进行 192k -> 48k 的降采样,因子为 4。 # 使用 scipy.signal.decimate 可以自动进行低通滤波防止混叠。 print("[-] Decimating (192kHz -> 48kHz)...") decimation_factor = 4 audio_output = signal.decimate(demodulated_signal, decimation_factor) # 4. 去加重 (Optional but Recommended) # NBFM 发射端通常有预加重 (Pre-emphasis),接收端应该去加重 (De-emphasis)。 # 这里可以简单地使用一个低通滤波器,或者如果不做也能听清内容。 # 为了简化,这里我们只依靠 decimate 自带的滤波,通常足够还原语音。 # 5. 归一化并保存 # 归一化到 -1.0 到 1.0 之间,防止爆音 print("[-] Normalizing and saving...") audio_output = audio_output / np.max(np.abs(audio_output)) # 写入 WAV 文件 (48kHz) output_filename = 'password.wav' wavfile.write(output_filename, 48000, audio_output.astype(np.float32)) print(f"[+] Audio saved to {output_filename}") if __name__ == '__main__': restore_audio()很明显的摩斯电码,用在线工具 Morse Code World 解密

结果的最后一位有问题,但不难看出是 114514350234114514
用这个字符串作为密码解压缩 flag.zip
flag.zip 里的 flag.txt 内容是 flag{Y0u*****************!!!}
flag.zip 里的 flag.zip 里的 flag.txt 使用的加密算法是 ZipCrypto,压缩方法是 Store,原始大小是 29(与 flag{Y0u*****************!!!} 长度一致),已知前 8 字节和后 4 字节,满足已知连续 8 字节以及总共已知 12 字节的要求,很显然是明显得不能再明显的明文攻击了
bkcrack.exe -C flag.zip -c flag.txt -x 0 666c61677b593075 -x 25 2121217dbkcrack 1.7.1 - 2024-12-21[00:46:51] Z reduction using 1 bytes of known plaintext100.0 % (1 / 1)[00:46:52] Attack on 2555904 Z values at index 6Keys: 33b19021 93c4a78d 9ceed93113.3 % (339321 / 2555904)Found a solution. Stopping.You may resume the attack with the option: --continue-attack 339321[00:51:55] Keys33b19021 93c4a78d 9ceed931bkcrack -C flag.zip -c flag.txt -k 33b19021 93c4a78d 9ceed931 -d flag.txtbkcrack 1.7.1 - 2024-12-21[00:53:11] Writing deciphered data flag.txtWrote deciphered data (not compressed).FLAG
flag{Y0u_r_th3_Z1p_k1ng!!!!!}Hidden
Challenge
我们从一名嫌疑人的硬盘中恢复了这张图片。我们认为它不仅仅是一张普通的图片。对文件属性的初步分析没有结果,但我们怀疑需要一个密码才能解开秘密。请找出其中隐藏的数据。
Solution
zsteg 看看有没有 LSB 隐写先
zsteg treasure.bmp[.] treasure.bmpimagedata .. text: "z`}~`}~_"b2,lsb,bY .. text: "$,7#F,`f"b1,rgb,lsb,xY .. text: "PixelWhisper"b3,g,msb,xY .. text: "$@IR\"Kr\""b4,r,lsb,xY .. text: "gwvfgvgfgwvg"b4,r,msb,xY .. text: "UUUUUUUUU"b4,g,lsb,xY .. text: "\"\"\"\"#DEUDVUUfwffeeDC3"b4,b,lsb,xY .. text: "FDETUDEETDEEV"b4,rgb,lsb,xY .. text: "iGugVthG"b4,bgr,lsb,xY .. text: "IewWdvHd"拿到明显有语义的字符串 PixelWhisper
题目描述说“需要一个密码才能解开秘密”,猜测这个密码指的就是 PixelWhisper,那么这个图片就有可能还用到了别的隐写,并且还是支持加密的,首先试试常见的 steghide
steghide extract -sf treasure.bmp -p PixelWhisperwrote extracted data to "flag.txt".FLAG
flag{a9a3c2872e428b6d859a0e63458a43f8}blue
Challenge
蓝色的世界。
Solution

勾选整个蓝色位平面会发现藏了一个 Zip 压缩包,需要间隔一位提取出来,编写脚本:
import numpy as npfrom PIL import Image img = Image.open('blue.png')img_array = np.array(img)blue_channel = img_array[:, :, 2]blue_bytes = blue_channel.tobytes() high_nibbles = []for byte in blue_bytes: high_nibble = (byte >> 4) & 0x0F high_nibbles.append(high_nibble) combined_bytes = bytearray()for i in range(0, len(high_nibbles) - len(high_nibbles) % 2, 2): combined_byte = (high_nibbles[i] << 4) | high_nibbles[i + 1] combined_bytes.append(combined_byte) with open('blue.zip', 'wb') as f: f.write(combined_bytes)内有 xor.png,压缩包的加密算法是 ZipCrypto,使用明文攻击
bkcrack -C blue.zip -c xor.png -x 0 89504E470D0A1A0A0000000D49484452bkcrack 1.7.1 - 2024-12-21[22:32:15] Z reduction using 9 bytes of known plaintext100.0 % (9 / 9)[22:32:16] Attack on 707085 Z values at index 6Keys: 68cc45ab 864060ce ac958caa29.1 % (206111 / 707085)Found a solution. Stopping.You may resume the attack with the option: --continue-attack 206111[22:34:01] Keys68cc45ab 864060ce ac958caa bkcrack -C blue.zip -k 68cc45ab 864060ce ac958caa -D blue_.zipbkcrack 1.7.1 - 2024-12-21[22:35:03] Writing decrypted archive blue_.zip100.0 % (1 / 1)Zip error: could not find end of central directory record.直接解压缩发现有问题,用 foremost 分离出两张图片

先用 StegSolve 的 Analyse - Image Combiner - XOR 将 00000000.png 与 00010969.png 合成得到 xor.bmp
双图盲水印,这里用到的项目是 chishaxie/BlindWaterMark 原图是 00000000.png,有盲水印的图是 xor.bmp
python bwmforpy3.py decode 00000000.png xor.bmp output.pngimage<00000000.png> + image(encoded)<xor.bmp> -> watermark<output.png>[ WARN:0@4.538] global loadsave.cpp:848 cv::imwrite_ Unsupported depth image for selected encoder is fallbacked to CV_8U.
FLAG
flag{a5e2ffeb-133e-4eb0-9855-d4d0078326ee}PunkFace
Challenge
look。
Solution
直接用 Word 打开会卡退,所以把后缀改成 zip 之后看里面的数据
document.xml 格外地大,先分析这个吧
前面是正常的内容,后面出现了大量的 <w:r> 标签,结构如下:
<w:r> <w:rPr> <w:color w:val="1A23A5"/> </w:rPr> <w:t xml:space="preserve"> </w:t></w:r>这里每一个 <w:r> 代表文档中的一个字符:
- 内容:
<w:t xml:space="preserve"> </w:t>说明这个字符只是一个空格 - 颜色:
<w:color w:val="XXXXXX"/>说明这个空格被赋予了特定的 十六进制颜色代码
很明显接下来需要提取 w:val 值,将它们视为 RGB 颜色值,然后拼接还原成一张图片
import refrom PIL import Imageimport math def get_closest_dimensions(total): root = int(math.sqrt(total)) for w in range(root, 0, -1): if total % w == 0: h = total // w return w, h return 1, total def main(): try: with open('document.xml', 'r', encoding='utf-8') as f: content = f.read() except FileNotFoundError: return # 提取被单独封装在一个 Run 里的彩色空格 pattern = r'<w:r><w:rPr><w:color w:val="([0-9A-Fa-f]{6})"/></w:rPr><w:t xml:space="preserve"> </w:t></w:r>' colors = re.findall(pattern, content) total_pixels = len(colors) if total_pixels == 0: return # 计算宽高 w_base, h_base = get_closest_dimensions(total_pixels) dimensions = [(w_base, h_base)] if w_base != h_base: dimensions.append((h_base, w_base)) for _, (width, height) in enumerate(dimensions): img = Image.new('RGB', (width, height)) for i in range(total_pixels): hex_color = colors[i] r = int(hex_color[0:2], 16) g = int(hex_color[2:4], 16) b = int(hex_color[4:6], 16) x = i % width y = i // width img.putpixel((x, y), (r, g, b)) img.save('result.png') if __name__ == '__main__': main()
没看懂是何意味
然后在搜 wp 的时候找到了这篇博客 2025 第五届 “鹏城杯” 联邦网络靶场协同攻防演练(初赛)个人 Writeup | GamerNoTitle
这篇 wp 里面说 word/media/image1.png 的 4 通道有东西(也不知道是怎么找到的,暂且先用着吧)

Save Bin 导出图片

OCR 识别文字得到:
4e 65 74 77 6f 72 6b 20 73 65 63 75 72 69 74 79 20 69 73 20 61 6e 20 75 6d 62 7265 6c 6c 61 20 74 65 72 6d 20 74 6f 20 64 65 73 63 72 69 62 65 20 73 65 63 75 7269 74 79 20 63 6f 6e 74 72 6f 6c 73 2c 20 70 6f 6c 69 63 69 65 73 2c 20 70 72 6f 6365 73 73 65 73 20 61 6e 64 20 70 72 61 63 74 69 63 65 73 20 61 64 6f 70 74 65 6420 74 6f 20 70 72 65 76 65 6e 74 2c 20 64 65 74 65 63 74 20 61 6e 64 20 6d 6f 6e 6974 6f 72 20 75 6e 61 75 74 68 6f 72 69 7a 65 64 20 61 63 63 65 73 73 2c 20 6d 69 7375 73 65 2c 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e 2c 20 6f 72 20 64 65 6e 69 61 6c20 6f 66 20 61 20 63 6f 6d 70 75 74 65 72 20 6e 65 74 77 6f 72 6b 20 61 6e 64 20 6e65 74 77 6f 72 6b 2d 61 63 63 65 73 73 69 62 6c 65 20 72 65 73 6f 75 72 63 65 73 2e4e 65 74 77 6f 72 6b 20 73 65 63 75 72 69 74 79 20 69 6e 76 6f 6c 76 65 73 20 74 6865 20 61 75 74 68 6f 72 69 7a 61 74 69 6f 6e 20 6f 66 20 61 63 63 65 73 73 20 74 6f20 64 61 74 61 20 69 6e 20 61 20 6e 65 74 77 6f 72 6b 20 76 65 72 61 63 72 79 7074 2c 20 77 68 69 63 68 20 69 73 20 63 6f 6e 74 72 6f 6c 6c 65 64 20 62 79 20 74 6865 20 6e 65 74 77 6f 72 6b 20 61 20 69 73 20 36 3f 2c 20 62 20 69 73 20 3f 37 2c 2073 20 69 73 20 3f 2c 20 61 64 6d 69 6e 69 73 74 72 61 74 6f 72 2e 20 55 73 65 72 7320 63 68 6f 6f 73 65 20 6f 72 20 61 72 65 20 61 73 73 69 67 6e 65 64十六进制转字符得到:
Network security is an umbrella term to describe security controls, policies, processes and practices adopted to prevent, detect and monitor unauthorized access, misuse, modification, or denial of a computer network and network-accessible resources.Network security involves the authorization of access to data in a network veracrypt, which is controlled by the network a is 6?, b is ?7, s is ?, administrator. Users choose or are assigned其中有一个关键信息 a is 6?, b is ?7, s is ?
联想到这个文档的另一张图片 image2.png,这个很明显是猫变换的参数,掩码攻击即可
用这个参数爆破得到的图片没一张是对的,经过 Alexander 师傅的提醒得知 a 和 b 是反的
经过爆破得到参数是 a is 68, b is 77, s is 8
(这里爆破使用的工具是 aristorechina/arnold_decoder,如果觉得好用的话还请点点 star)

得到 CCC35EF6EC2A7F5C67B2A3DA51C78DBB
接下来参考 Lunatic 师傅的博客进行复现:2025 鹏城杯联邦网络靶场协同攻防演练 Misc Writeup - ⚡Lunatic BLOG⚡
接上前面 document.xml 提取出的正方形图片,把每个像素的 hex 值提取并拼接起来,拼接顺序是 RGB
from PIL import Image input_filename = 'result.png'output_filename = 'result' try: with Image.open(input_filename) as img: img = img.convert('RGB') pixels = list(img.getdata()) total_pixels = len(pixels) print(f"原始图片总像素数: {total_pixels}") hex_parts = [] # 遍历有效的像素 for r, g, b in pixels: # 拼接顺序 R, G, B hex_r = format(r, '02x') hex_g = format(g, '02x') hex_b = format(b, '02x') hex_parts.append(hex_r) hex_parts.append(hex_g) hex_parts.append(hex_b) full_hex_string = "".join(hex_parts) binary_data = bytes.fromhex(full_hex_string) with open(output_filename, 'wb') as f_out: f_out.write(binary_data) except Exception as e: print(f"处理过程中发生错误: {e}")将得到的文件作为 VC 容器挂载,挂载密码为 CCC35EF6EC2A7F5C67B2A3DA51C78DBB
容器内有一张图:

拼图题,拆散重新拼

FLAG
flag{0671b07f6b7908bd718dc969b056ab26}