又只做了两道水题,太久没打了,啥都不会了qaq
0x0. glass - Reverse
拿到一个 apk 文件,先反编译。
经过checkFlag
函数检查,对就输出right!
这个函数是 native 函数,在 libnative-lib.so 文件里,用 7z 提取出来拖进 IDA。
checkFlag
函数就是这样,v3
是用户输入,检查长度为 39,然后传入了sub_1088
。进去sub_FFC
和sub_1088
可以认出是 RC4 加密,前者初始化 S 盒,后者加密:
密钥就是checkFlag
函数里面那串12345678
。RC4 结束后再给sub_10D4
处理,进里面看下。
分上下两个循环处理,第一个循环以三个字符为一组(组密码),加密产生新串,第一、三字符异或得到新串第一字符,三字符一起异或得到新串第二字符,第二、三字符异或得到新串第三字符,如下(新串第二个字符少画了个异或符号):
第二个循环就是每个字符自己一组异或(流密码),解密直接和加密算法相同。第一个循环的解密需要改一下代码。以下是这整个函数的解密代码:
|
|
result
数组是从checkFlag
函数最后memcmp
的参数提取出来的。
运行得到:
f8 ba 6a 97 47 ca e8 91 c5 7 6e f7 92 b 39 92 14 a8 af 7e aa 50 45 8d 6d 2d b6 86 6e 9f 86 5e df b3 1e 52 a6 62 6a
拿去 RC4 解密一下,密钥 12345678
,就得到 flag:
\[ CISCN\{6654d84617f627c88846c172e0f4d46c\} \]
0x1. baby_bc - Reverse
拿到一个 .bc 后缀文件,搜索一下,是 LLVM bitcode,用llvm-dis
工具反汇编成 LLVM IR,然后再用 GitHub 上面一个叫llvm2c
的工具转成 C 代码,丢进 IDE 里改一改就可以编译出可执行文件。(5/17 更新:看了其他师傅 writeup,.bc 文件可以用llc
直接生成目标文件再用gcc
链接,这里画蛇添足了)再拖进 IDA 分析。
主函数先检查输入长度为 25,然后检查每个字符必须是数字 0-5。
进入fill_number
看下。
里面基本都是这个结构,就是按照输入在填充map
这个矩阵,输入 25 字符对应矩阵的五行五列,map
里面本身在第三行第三列和第四行第四列填好了数字,输入的对应位置必须是 0,否则检查不通过。
最后进入docheck
看下。
里面分三部分,第一部分检查矩阵的每行每列没有重复数字,第二部分和第三部分对行列上填写的数字做了一些大小的约束。实际上这个程序就类似在解数独,只是加了一些约束条件。
根据条件解数独,得出结果如上,所以最后正确的输入就是 1425353142350212150442315,flag 就是 CISCN{这串字符的MD5}。 \[ CISCN\{8a04b4597ad08b83211d3adfa1f61431\} \]