这是CTF杂项的一道题目,题目简介取,取证与安全杂项,番茄真的很好吃,可是,我的番茄怎么怪怪的,给我...
생성일: 2026년 8월 9일
답변에 사용된 모델 GPT-5.6 Thinking by Chat01
생성일: 2026년 8월 9일
답변에 사용된 모델 GPT-5.6 Thinking by Chat01
这是CTF杂项的一道题目,题目简介取,取证与安全杂项,番茄真的很好吃,可是,我的番茄怎么怪怪的,给我flag和wp
解出来了,这题不是传统 LSB/尾部藏文件,而是 “小番茄图片混淆”。
textmoectf{Tom@t0_i5_D3liciou5!}
我在你上传的 tomato.jpeg 上实际还原成功,flag 直接写在恢复后的番茄图片中间:
先做基础取证:
bashfile tomato.jpeg identify tomato.jpeg strings tomato.jpeg
附件是普通 JPEG,尺寸:
text1170 x 1553
没有直接从字符串、附加文件等位置拿到 flag。真正值得注意的是图像本身:看起来像大量红色小方块/矩形被重新排列,但每个区域内部仍然保持比较明显的连续纹理。
题目又一直提示:
番茄真的很好吃,可是,我的番茄怎么怪怪的
这里的“番茄”其实是在提示 小番茄图片混淆。
这个算法使用 Gilbert 空间填充曲线(广义 Hilbert curve) 把二维图片的所有像素变成一条一维遍历路径,然后沿路径循环平移像素;常见实现的偏移量使用黄金比例计算。开源实现的说明正是:
textoffset = round((sqrt(5) - 1) / 2 * 总像素数)
而且混淆和解混淆本质上是互逆的像素映射。(GitHub)
这张图片:
pythonwidth = 1170 height = 1553 total = 1170 * 1553 = 1817010
所以:
pythonoffset = round((sqrt(5)-1)/2 * 1817010) = 1122974
官方/衍生实现中可以把关系理解成:
textold_pos = curve[i] new_pos = curve[(i + offset) % total] 混淆: dst[new_pos] = src[old_pos] 解混淆: dst[old_pos] = src[new_pos]
这与公开的小番茄实现说明一致。(GitHub)
我分别测试了两个方向。
正常按“解混淆”方向移动时,图片仍然是乱的;反过来,对题图再执行一次混淆方向的偏移,马上恢复成正常的番茄照片。
关键代码其实就是:
pythoncoords = np.asarray(list(gilbert2d(w, h))) xs, ys = coords[:, 0], coords[:, 1] seq = img[ys, xs] offset = round((math.sqrt(5) - 1) / 2 * w * h) # 本题要走混淆方向 restored_seq = np.roll(seq, offset, axis=0) out = np.empty_like(img) out[ys, xs] = restored_seq
恢复以后中央可以直接看到:
textmoectf{Tom@t0_ i5_D3liciou5!}
拼起来即:
textmoectf{Tom@t0_i5_D3liciou5!}
运行我给你的脚本即可复现:
bashpip install pillow numpy python solve_tomato.py tomato.jpeg -o restored.png
得到的 restored.png 就是正常番茄图和 flag。