kcov
附件
附件里的 bzImage 和 rootfs.cpio.gz 很明显是个 Linux 内核文件和Linux文件系统. 看了一下 launch.sh 的文件内容就是一个 QEMU 的启动脚本, 直接运行试试.
发现运行后可以看到kcov程序运行, 但是输出了个文件无法打开的错误就退出了, 这种情况就直接从 rootfs.cpio.gz 里面找到 kcov 程序然后提取出来(7-Zip、tar命令都可以).
main
使用 IDA 打开, 定位到main函数, 且使用Findcrypt发现了AES.
1 | // main 函数 |
其中, sub_400BCD 函数是从文件中读取内容, 并没有找到使用键盘输入.
由于不需要键盘输入, kcov 运行后发现要读取的文件不存在就会自动退出, 动调的时候可以通过修改寄存器绕过 sub_400BCD 的判断.
然后在 sub_4017D2 中发现了有调用加密函数:
1 | unsigned __int64 __fastcall sub_4017D2(__int64 a1) |
for ( i = 0LL; i <= 0xF; ++i )
循环将 a1 进行了依次除 100 操作, 随后 sub_4015F8 对 a1 进行检查:
1 | _BOOL8 __fastcall sub_4015F8(__int64 a1) |
for ( i = 0LL; i <= 0xF; ++i )
循环将 a1 打乱放入 v3 中, 然后 sub_401503 将 v3 和 v4 进行计算, 计算结果放入 v5 . 且 v3 v4 v5 都是 16 个元素.
1 | __int64 __fastcall sub_401503(__int64 a1, __int64 a2, __int64 a3, unsigned __int8 a4) |
这个三层循环嵌套很像矩阵乘法的操作, 通过 https://gist.github.com/meagtan/dc1adff8d84bb895891d8fd027ec9d8c 可以看到和 GF(2^8) 上的矩阵乘法很像, 但是不同点是 GF(2^8) 在乘法时是 AND 0x80, kcov中是 AND 0x40, 所以这里应该是 GF(2^6), 并且最后有一个 MOD 91的操作.
1 | __int64 __fastcall sub_401465(char a1, unsigned __int8 a2) |
又根据 result = v5[10] + v5[5] + v5[0] + v5[15] == 4 && v5[10] * v5[5] * v5[0] * v5[15] == 1;
, 可以猜测 v5 最后需要是一个单位矩阵, 所以我们需要找到一个矩阵是 v4 的逆矩阵. 可以使用 matlab 计算一下:
计算完成后可以得到[0, 5, 5, 14, 21, 8, 9, 1, 10, 6, 12, 3, 6, 7, 12, 4]
, 此时还需要对上述的v3[4 * (i & 3) + (i >> 2)] = *(_QWORD *)(8 * i + a1);
打乱操作进行还原,最后可得:key = [0, 21, 10, 6, 5, 8, 6, 7, 5, 9, 12, 12, 14, 1, 3, 4]
.
然后回到 sub_4017D2 , 可以发现 sub_402D5A 是一个 AES_ECB 加密过程, 加密密钥就是上面的key .
解密脚本
1 | from Crypto.Cipher import AES |