File tree Expand file tree Collapse file tree 4 files changed +37
-0
lines changed Expand file tree Collapse file tree 4 files changed +37
-0
lines changed Original file line number Diff line number Diff line change 94
94
| [ lyq1996] ( players/lyq1996/README.md ) | 总排名第 109, [ blog] ( https://lyq.blogd.club/2021/10/31/hackgame-2021-wp/ ) | 助力、Amnesia轻度失忆、Amnesia重度失忆、只读文件系统、catchGPA |
95
95
| [ lxdlam] ( players/lxdlam/README.md ) | 总排名第 67,[ blog] ( https://blog.lxdlam.com/post/f37e3945/ ) | 签到、进制十六——参上、去吧!追寻自由的电波、猫咪问答 Pro Max、卖瓜、透明的文件、旅行照片、FLAG 助力大红包、Amnesia、图之上的信息、Easy RSA、加密的 U 盘、赛博厨房(Level 0、Level 1)、助记词(第一顿大餐)、Co-Program(Co-Login)|
96
96
| [ Vifly] ( https://viflythink.com/Hackergame_2021_writeups/ ) | | 签到,进制十六——参上,猫咪问答 Pro Max,卖瓜,Amnesia (轻度失忆),图之上的信息,加密的 U 盘,赛博厨房(LEVEL 0、LEVEL 1) |
97
+ | [ tkmk] ( players/tkmk/ ) | 总排名第 9 名 | 赛博厨房(LEVEL 3 非预期) |
97
98
98
99
## 其他资源
99
100
Original file line number Diff line number Diff line change
1
+ # Writeup
2
+ 周四下午之后因为各种原因 AFK 了,等有空再回来的时候,大家已经陆续在分享各自的 writeup 了。阅读了一下** 赛博厨房** Level 3 的官方题解、以及另外两位 dalao mcfx & 4qwerty7 的题解(膜拜),发现自己做是** 非预期** ,于是也记录分享一下。
3
+ ### 赛博厨房
4
+ Level 0 和 1 我的做法和大家类似。在解 Level 2 时,我从 js map 恢复了前端代码,对题目生成随机种子和菜谱的方法进行了分析。抓包测试发现后端并不会对每一条程序进行合法性分析,于是我选择的是类似官方题解的方法,但是只生成 127 条固定的程序,最后一条直接枚举爆破递增的数字,就等菜谱落到我会做的范围。个人感觉不用修改程序容易一些,它们的 hash 也不用重复计算。
5
+ 至于 Level 3,爆破肯定是不可行的。鉴于本题在前端使用 TypeScript 封装了大量的模型和方法,推测前后端可能存在代码复用,即后端也使用的是 NodeJS。那么会不会存在一些类型上的问题呢?
6
+
7
+ 让我们来以 Level 1 为例,看一下提交答案的请求:
8
+
9
+ ![ ] ( ./images/1.png )
10
+
11
+ 后端读取要执行的程序,大概是类似这样的代码:` req.body.programs[req.body.executions[0]] ` 。
12
+
13
+ 现在试试把 ` programs ` 从数组改成对象:
14
+
15
+ ![ ] ( ./images/2.png )
16
+
17
+ 后端没有报什么大错,反而是非常贴心地告诉我们 seed 不对。把请求中的 seed 修正之后,顺利得到 Level 1 的 flag。
18
+
19
+ 这个 ` e3b0... ` 是哪里来的呢?搜一下就能发现,它是空字符串的 sha256。看一下前端的计算方法就知道了:
20
+
21
+ ``` typescript
22
+ public getInstrsHashes (programs : Array < string > ) {
23
+ let hashes = [];
24
+ for (let i = 0 ; i < programs .length ; i ++ ) {
25
+ const content = programs [i ].trim ();
26
+ const hash = CryptoJS .SHA256 (content ).toString (CryptoJS .enc .Hex );
27
+ hashes .push (hash );
28
+ }
29
+ let hashesConcat = hashes .join (' \n ' );
30
+ return CryptoJS .SHA256 (hashesConcat ).toString (CryptoJS .enc .Hex );
31
+ }
32
+ ```
33
+
34
+ 现在 ` programs ` 是个对象,` programs.length ` 为 ` undefined ` ,` 0<undefined ` 为假,于是并不会进入循环,最后一次 sha256 的输入就是空串。(当然乐意的话也可以给 ` programs ` 随意加个 ` length ` )
35
+
36
+ 有了固定的 seed,意味着固定的菜谱,后面怎么做就不用多说了吧。
You can’t perform that action at this time.
0 commit comments