WeChall - Towers of Hanoi (Java, Cracking)
Challenge
Java applet 实现汉诺塔,10 个盘子从左柱移到右柱,限 60 秒。无法在现代浏览器直接运行(Java applet 已被弃用),需要逆向 jar 文件离线算出答案。
Solution
Step 0: 获取 JAR
JAR 文件在挑战页面的 <applet> 标签中通过
archive="hanoi2.jar" 引用,与页面同目录:
1 | $ wget https://www.wechall.net/challenge/Z/hanoi/hanoi2.jar |
Step 1: 逆向分析
1 | $ jar xf hanoi2.jar |
反编译关键发现:
- 每次合法拖拽后,
mouseUp()构造last_tower + new_tower(如"a" + "b"="ab"),调用Tower.query(move) query()向/challenge/Z/hanoi/?query=<move>发 HTTP 请求,读取服务器返回的 2 字符响应,追加到solution字符串- 所有 10 盘移到右柱(
win=true)时,对solution做 SHA-512,导航到?solution=<hash> - 60 秒超时(
javax.swing.Timer),移动超过 1023 步自动重置
Step 2: 获取 6 种 query 的返回值
服务器对每种合法移动返回固定 2 字符令牌:
| Move | Response |
|---|---|
| ab | we |
| ac | ch |
| ba | lr |
| bc | al |
| ca | ul |
| cb | z! |
这些值可通过实际运行 applet 抓包或直接 curl 逐个获取:
1 | $ curl -s 'https://www.wechall.net/challenge/Z/hanoi/?query=ab' |
Step 3: 生成最优序列
10 盘汉诺塔最优解需要 2^10 − 1 = 1023 步。经典的递归解法:
1 | import hashlib |
输出的 SHA-512 即为答案。
Step 4: 提交
1 | $ curl "https://www.wechall.net/challenge/Z/hanoi/index.php?solution=<sha512>" |
服务器返回 "Correct!" 即通过。
注意: 该 hash 是确定性的(固定响应表 + 最优路径 = 固定 result),所以可以直接用提交的方式跳过 applet。如服务器已有提交记录,会提示 "Your answer is correct but you have already solved this challenge."
feb3a1f6e5e259f381f42a4e72aceaea204403fab7eec9a2d3d0bcff076a647be88f6f6caeeb1b6295aabba9807f1a2260b466f9f0512498fb50300703eb2552