TexSAW 2026 Writeup
TexSAW 2026 Writeup
本文整理 TexSAW 2026 中两道题的解题过程。图片和附件本身没有随文章保存,因此只保留可以复现的文字、命令和代码。
题目索引
Secret Word
解法
题目附件是一个 DOCX 文件。DOCX 本质上是一个 ZIP 容器,直接解压即可查看其中的文件:
1 | unzip challenge.docx -d challenge |
找到 secret.txt 后,对其内容进行 Base64 解码:
1 | base64 -d challenge/secret.txt |
解码后的内容就是题目需要提交的 secret word。
A Different Side Channel
题目分析
题目提供了:
- 500 条功耗轨迹,
traces.npy的形状为500 × 100; - 与轨迹对应的明文,
plaintexts.npy的形状为500 × 16; - 一个 64 字节的加密 flag。
这是一个典型的相关功耗分析(Correlation Power Analysis,CPA)场景。攻击 AES 第一轮的中间值:
功耗模型采用汉明重量:
对每个字节枚举 k 的 256 种可能值,计算假设功耗和真实轨迹之间的皮尔逊相关系数。相关系数绝对值最大的候选就是该字节最可能的密钥值。
CPA 脚本
下面是整理并修正缩进后的脚本。AES S-Box 使用标准的 256 项查找表:
1 | import numpy as np |
解密过程
加密文件长度为 64 字节,其中前 16 字节可以作为 IV,剩下 48 字节是 AES-CBC 密文。恢复 16 字节密钥后,使用 CBC 模式解密并去除 PKCS#7 padding 即可得到 flag。
题目材料给出了运行结果:
1 | texsaw{d1ffer3nti&!*p0w3r*@n4!y51s} |
Docker-ception
解题思路
后端会执行类似 ping admin 的操作,输入没有被正确限制,因此可以从主机名或参数位置尝试命令注入。利用注入读取 /home/ctfer 目录,找到其中保存的 flag。
原始材料没有记录具体的 Payload 和最终 flag,因此这里只保留攻击方向。
Lost my keys
题目提供了两张看起来完全相同的 PNG。将两张图片逐像素比较,把不同像素转换成二进制序列,再按 ASCII 解码即可得到 flag。
图片附件没有随文章保存,因此没有在文章中添加图片引用;原始材料也没有记录解码后的具体 flag。
Broken Quest
状态机分析
这是一个“任务”模拟器。玩家通过 0 到 8 号操作改变一个包含 8 个整数的状态数组,满足目标状态后执行 turn_in。
关键函数如下:
| 函数 | 作用 |
|---|---|
turn_in |
用 memcmp 比较状态前 8 字节,要求 state[0] == 2、state[1] == 6,通过后调用 handle_flag。 |
handle_flag |
使用完整状态作为密钥,通过置换矩阵和 8 种运算解密数据。 |
transform |
对密文逐字节执行 key_byte XOR enc_byte。 |
calc_val |
循环调用 op0 到 op7,生成每个字节的密钥。 |
从 main 中提取出的目标状态为:
1 | [2, 6, -4, 6, 0, 4, -3, 1] |
解密
将 8 个状态值按置换矩阵展开为 8×8 矩阵,然后分成 8 段解密,每段使用不同的行、偏移和长度。最终得到:
1 | texsaw{1t_ju5t_work5_m0r3_l1k3_!t_d0e5nt_w0rk} |
💬 评论与讨论
分享你的想法和见解