NSSCTF vm_wo
NSSCTF vm_wo
第一部分
无壳,mac,拖进IDA看看,有一个明显的比较,直接拿到flag最后比较的data
1 | data = [0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD, 0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99, 0x87, 0xBF, 0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD] |
第二部分
接着点击myoperate函数看看,读代码发现,这直接告诉我们opcode了,即每一个8字节的十六进制拼接,注意要去掉最后一个因为他只是(v8 + 7)
1 | # hex_string = "020D01011903001A" |
注意IDA小端序存储,所以要倒序一下再拼接。
第三部分
点击interpretBytecode函数看看模拟器长什么样,发现有很多模拟指令,但是我们看我们的opcode只有这几个模拟的命令:
1 | 0 1 2 3 4 5 6 7 13 24 25 26 |
所以我们只用复现这几个命令即可
exp:
1 | opcode = [26, 0, 3, 25, 1, 1, 13, 2, 7, 24, 1, 2, 1, 0, 3, |
得到的汇编指令:
1 | 0 r[0] = 3 |
这里r[0] = 3分析后3应该是我们输入的flag,这里有个重点:
1 | case 24: |
case24时有两个奇怪的东西,看他们的地址:
1 | __bss:0000000100008001 byte_100008001 % 1 |
这里可以看出他们应该是同一个数组,且byte_100008001表示r[1],byte_100008002表示r[2],deadbeef = 0xBEEDBEEF;这个东西应该表示r[3]到r[6],这样和汇编出的r[]数组便对上了
使用我们可以开始写脚本了,exp:
1 | data = [0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD, 0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99, 0x87, 0xBF, 0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD] |
当然也可以用爆破直接跟他爆了,这里附上好兄弟的本题爆破解法链接
1 | https://www.pri87.vip/posts/b22e135.html |
评论