CISCN2025
vvvmmm #
DIE 查壳,有 UPX 壳,没有魔改对抗,直接 upx -d
readelf -p .comment vvvmmm 查编译器信息可以看到
GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
因为是静态链接,下载 ubuntu24.04 的镜像
docker run –name test -it –rm ubuntu:24.04
apt update apt install libc6-dev
拷贝 docker cp test:/usr/lib/x86_64-linux-gnu/libc.a libc.a
然后 pelf libc.a
解决 pattern 冲突之后 sigmake libc.pat libc.sig(这步你可以不做,我已经把sig做好了,你导入就行)
在 IDA 导入 FLIRT signature 即可还原静态链接的 libc 的符号,可以看到还有一大堆没有识别的,推测还静态链接了别的库
主函数有一点平坦化和 data 解密的内容,可以使用调试来 dump 这些数据,在 puts 下断点
我建议你复现的时候截图,因为我 IDA 的主题肯定和你的不一样
可以看到比较关键的数据是 0x64c3f0 的 662 字节数据和 0x64C6C0 的 32 字节字符串,点进下面的疑似进入 vm 的函数 sub_4099D0 可以看到字符串 timeout,再点进去,可以看到 qemu_thread_create 字串引用
搜索字符串 qemu 有 riscv 相关字串
大胆猜测 662 字节的数据是 riscv 字节码,调试 dump 出来
算法比较容易,但是这里有个坑,最后一个基本块因为没有 ret 函数,没有反编译出来
它实际上就是把上面 32 字节的字符串(key)用哈希压缩,然后通过不断的 13 次方生成 12 个 4 字节数,和 48 字节的输出逐个异或,最后比较
比较的方法是 xor,试图检测 xor 完是否为 0
最后一个没反编译出来的基本块正好有 12 个 xor,但这里有一些间接的计算,直接把汇编拖到 AI 中让它输出 12 个常数即可
最后包裹上 flag{}
详情你可以用 ida 打开我的 ida 数据库,都发给你了