位置:/home/kita/code/blog/source/_drafts/CodeShell/
CTF
workspace:/home/kita/ctf/workspace/challenges/codeshell/
最后更新:2026-09-21
https://codeshell.kr/0 / 33);登录名不写入本文件/challenges/<slug>/,普通题表单字段
answer;Ten Gates 是分阶段 gate 表单manifest.json原合并稿 codeshell-writeup.md 已按题拆成 33
个单题文件,命名
<ctfname>-<challenge-slug>.md (slug 取站点 URL
的最后一段,如
codeshell-time3.md、codeshell-infinity-parallax.md),
每篇自带
frontmatter(title: CodeShell.kr - <题名>、tags、categories: - ctf、
mathjax、date、spoiler.hover)、### Challenge(题面双语
blockquote + 题目 URL) 与
### Solution,正文末尾贴出实际运行过的 solver 全文。
未有确定答案的 5 题(Fried Egg、Residual、Reversal、Sixteen Plates、Obsidian)不写 spoiler,正文只写 已确认的结构与已排除的假设;Fried Egg 的候选只在正文中明确标注,不把候选当作答案。
拆分由 solvers/build_blog_writeups.py
生成(可重跑);合并稿备份在
/home/kita/ctf/workspace/challenges/codeshell/writeup-combined-backup.md。
QA 用技能自带脚本:
1 | $ uv run python ~/.hermes/skills/security/ctf-challenge-solving/scripts/qa_writeups.py \ |
solvers/preflight_audit.py 把 28
个答案与题目页要求逐条对照,结论:
CodeShell{...}
形式,格式无歧义。CodeShell{...} 包裹: fold →
FOLDED_MIRROR、keyring →
AMBERMOONCIRCUIT、 misc-offset →
AFTERHOURS、misc-relay →
BACKTRACK。Submit answer
表单; 只有 phase-between-words 与
quiet-frame 在题面里明写
CodeShell{...},
说明这是站点通行约定,裸词题按同样约定包裹。提交字段为 answer;不触碰 hint / 评分 / gate
接口。提交会改变站点计分状态, 需用户明确授权后执行。28
题的提交串已由审计脚本输出,可直接逐行取用。
| 题目 | 类别 | 答案 | 本地验证方式 |
|---|---|---|---|
| Opcode Picnic | Reversing | CodeShell{branching_is_data} |
二进制回 accepted(GDB 逐轮对齐模型) |
| Switchyard | Reversing | CodeShell{switches_hide_state} |
二进制回 accepted |
| Glass Register | Reversing | CodeShell{registers_leave_traces} |
二进制回 accepted;33 轮唯一解 + 链式判据 |
| Time 3 | Stegano | CodeShell{third_time_was_the_charm_7f2a} |
多次一密,明文自洽 |
| Quiet Frame | Stegano | CodeShell{QUIET_PIXELS} |
B 通道 LSB,偏移 0 处明文 |
| Crossfeed | Stegano | CodeShell{THE_QUIET_CHANNEL_BURNS} |
三遍多数票 + CRC32 自洽 + payload CRC 通过 |
| Keyring | Crypto | AMBERMOONCIRCUIT |
环 XOR 闭合 + 冗余边校验 |
| Fold | Crypto | FOLDED_MIRROR |
置换 sha256 唯一 + PKCS#7 填充合法 |
| Errata | Crypto | CodeShell{ERRORS_ARE_EVIDENCE} |
Berlekamp–Welch 三条 lane 均 96/128 匹配 |
| Palindrome | Crypto | CodeShell{6b33161830abff17282d493514bea5ec3753c5b6305c8b0c2edf1165fb0c297d} |
Franklin-Reiter;12/12 完美匹配 + 机制自测 3/3 |
| Relay | Misc | BACKTRACK |
Received 链倒序 |
| Offset | Misc | AFTERHOURS |
UTC 归一后排序 |
| No Show | Misc | CodeShell{NOSHOW} |
611 事件重放 + 点阵字体 |
| Undo History | Misc | CodeShell{THELASTWORDWINS} |
不动点 + 降序贪心交叉验证 |
| Terminal | Misc | CodeShell{THE_LAST_PACKET_CAME_FIRST} |
血缘链回溯,目标包明文为 } |
| Check-in | Misc | CodeShell{GPKTEOQBSCDLMINFAHJR} |
两套独立 DP 同为 227 步 |
| Palimpsest | Misc | CodeShell{8f652d071f0f642acdbbe83b1a82853721c233456ff0ff1e0edd23b9115d6089} |
有缓存/无缓存两套重放同结果 |
| Mosaic | Misc | CodeShell{CORNERS_REMEMBER_THE_WHOLE} |
24×24 全部填满;9 种子 OCR 共识 + 逐行像素宽度自校验(32.4/33.0/32.8 px/char) |
| Blackbox VM | Reversing | CodeShell{blackbox_state_machine} |
二进制回 accepted(37 轮内层,GDB 对齐) |
| Threaded Echo | Reversing | CodeShell{threads_share_secrets} |
二进制回 accepted(通用模板求解器,17 轮) |
| Dead Branches | Reversing | CodeShell{dead_code_is_not_dead} |
二进制回 accepted(通用模板求解器,23 轮) |
| Involution | Reversing | CodeShell{a2abc1aad4440dc013b94271569f21985e344d930e97d8a304b6909aca12c331} |
二进制回 yes(4096 条字节码反向执行) |
| Fractured Loom | Reversing | CodeShell{812da7912a92b2daccdf6d16afe683e02c719bdfe9a4604288b4aa4366c9502b} |
二进制回 accepted(8192 条 loom 指令反向执行) |
| Phase Between Words | Stegano | CodeShell{MIRROR} |
过零率取样本级音段;800 样本/符号 FSK;四个通道解出同一结果 |
| Marginalia | Crypto | CodeShell{the_lamp_kept_its_secret} |
列 IC 定长 22 + 卡方;词表逐列精修两法收敛同一明文 |
| Ten Gates | Crypto | CodeShell{OBSERVATIONSEPARATESHYPOTHESES} |
三个内置校验全过:候选数 6 == 期望、手册 SHA-256 逐位相符、长度 30 |
| Afterglow | Crypto | CodeShell{19527f1fabf4d87f2039f509} |
公钥 g^x mod p == y;解释 68/80 行,12
行污染与边界算术预测一致 |
| Parallax | Stegano | CodeShell{f7f7b273c2e227d1e2566d8f647241cb48a4049f1afcad683427df85639db053} |
INFINITY 前缀 + 流末尾 SHA256 自洽 + 896
边配对无歧义 |
GODS,未验证)1 | /home/kita/ctf/workspace/challenges/codeshell/ |
answer),不调用 hint / gate
解锁接口。GODS(footer 第 3
个按钮 → YouTube 标题,yt-dlp + oEmbed 双源核验)。未提交、未写
spoiler;内嵌韩文封面疑为第二个“太阳”(诱饵),已排除。p=1 需 1.0e12 候选 ≈ 124
小时,p=2 ≈ 480 小时;Bcol[]
增量维护再优化可到约 40 小时。Stern
已验算无效(2l+p=w=35 两种取法总代价都超
2^67)。已交付两个正确的 C
实现(solvers/obsidian_isd.c
全量消元、solvers/obsidian_inc.c
增量),都在合成实例上精确恢复真值 + H·e==s
通过。结论:需要 40–124 小时算力,或 MMT/BJMM 级实现 ——
属资源决策,等用户定。踩过的坑见
findings/obsidian.md(行变换必须同步变换 RHS 等 4 条)。song[71.4..90.4],见
findings/reversal.md 与 writeup Step
2-4)。卡在短语读出:whisper
对倒放音乐只产幻觉(失败模式已记录:时间戳超长、退化成 ,,
重复、短句循环、通顺的通用英文句)。下一步:细分辨率包络找 0.3-1.5s
孤立强瞬态、只倒放那一小段;或先做人声分离(Demucs)再转写;或换官方音源(本次用的是
알파 频道歌词视频)。不要再整段转写。B bit0 只有
0.0038),995 个奇数-B 像素精确构成旋转半色调网点阵(32 条带 × 16
网点位,网点列 (5−b+32p) mod 512,每条带 5
行)。四轮验证全部否定:① 995
个点全部精确落在格点上(位置偏差 {0:995})→ 位置不承载数据;② 5
行窗口只有 24/32 种掩码(bit4 置位则 bit0 必不置位)→ offsets 0-3
是干净的 4-bit 字段、offset 4 是独立的 144-bit 通道,但四种窗口宽度 × 5
种读取顺序全部 0 命中;③ filter 序列与网点值统计独立(一致率
112/512);④ present 平面占
94.5%,阈值变体均非文字。下一步:把 offsets 0-3 与
offset 4 分开处理;按有序抖动矩阵反解 5 级灰度;或把 5
个行偏移当同一数据的 5 份渲染两两求差。glass-register
还有一条反相的最终判据(je rejected),只匹配期望表会误判。.rodata 里的常量,且 yes/no
字符串顺序与 cmovne 的方向相反 ——
必须先读实际字符串内容再判断哪个分支是成功。(Q1>>3)&0x38 vs
((Q1>>3)&7)*8),只有把 GDB 的连续 59
条指令状态与 Python 逐一比对才定位到第 5
条。只比对最终结果会得到一个"看起来合理但错误"的输入。cp 到 /tmp
后 chmod +x,或用
/lib64/ld-linux-x86-64.so.2 <bin> <args>。findings/<slug>.md,主代理汇总复核,效率最高;但子代理有
600s 超时,重计算任务要先拆小。2π·f·hop/fr 精确扣除,否则残差呈斜率会被误判成调制。expected_candidate_count、book_plaintext_sha256、各段
plaintext_length)。先把它们列出来,每跑通一个再往下走。关键教训:长度校验挡不住内容错误
—— Bifid 反解写错时输出长度依然正确,只有手册 SHA-256
抓到了它。遇到「长度对但内容不对」,要去找一个能覆盖内容的校验值。sage <file> [args]
可能静默无输出(exit 0、stdout 空、stderr 空)。用
sage -c "exec(open(path).read())"
才可靠;把「无输出」当成「已失败」会浪费整轮排查。g^x mod p == y 逐个验候选,而不是靠「吻合行数」打分(打分在
19/80 这种噪声水平上完全不可靠)。有强 oracle 时一定要用它。k < q 且
q/2^153 = 73.31 ⇒ top7 > 73 必然被污染,80
行里直接抓出 5 行。污染率还能从这 5 行反推:128
个取值里只有 74 个合法,随机坏值约 42%
落在非法区,5/0.42 ≈ 12 与实测的 12 行完全一致。isd PyPI 包不是 Information Set
Decoding:它是 Integrated Surface
Database(气象数据)的解析器,只含
Batch/Record,没有求解器。别被名字骗了。C(n,w)/C(n−k,w−p) 在 p=0/1/2 时是
238.02/239.87/2^41.77 —— 更大。允许 p
个错误落在信息集里会降低「其余错误全在奇偶位」的概率,而枚举 C(k,p)
的开销并不抵消。别默认「更复杂的 ISD 一定更快」,先算清楚。(5−b+32p) mod 512 的斜向点阵,每点是 1..4
行高的竖短段,值域恰好 5 级。识别特征:点列间距恒定 +
每条带的列偏移随带号线性递减(旋转半色调屏的签名)。先
dump 原始点图,不要只看渲染后的位图 ——
低分辨率渲染会把斜向点阵误读成普通网格。