-
-
[原创] 第六题 PWN-noheap WriteUp
-
发表于: 2018-6-26 15:40 3046
-
这一个pwn题,感觉也还是比较偏逆向……
IDA载程序可以发现程序先做了一个proof of work验证,自己手写了一个简单的哈希函数,随机生成4个0x30 ~ 0x5B之间的字节,当成int32型做两次数学运算,然后再当成字符串生成哈希值。
算法:
写一个函数,爆破4个字节即可,注意输入的应该是4个字节被做两次数学运算后的8个字节。
进了程序流程以后可以看到控制流程的函数非常的诡异:
将BSS段的某几个值异或,某几个放在栈里,固定的一个jmp过去。
利用JumpToXref功能,寻找这几个值被引用的地方,发现在init_array中有初始化函数:
程序把主要的几个功能函数写入到了bss段里,并和随机数异或,到需要用到的时候再动态取出。
用于跳转的固定函数是个VM解析器,字节码被提前写入BSS段。
一开始习惯性的去找free函数的问题,发现只能free之前刚malloc的一块堆,并且free之后指针已经置零。show函数只能show一次,之后便会关闭stdout和stderr,这些地方似乎没有漏洞。
后来发现,add函数存在一个不太明显的整数溢出:
如果读入0,满足了unsigned int小于0x80的条件,malloc(0)可以正常返回,read_buf的第二个参数便会变成0 - 1 = 0xFF,超过了128,可以在BSS段溢出到VM的字节码。
经过一番分析,标了操作数和寄存器之后的VM函数:
// PC的内容当PC指针用,PC的地址当基址寄存器用……膜出题人……
原来的字节码对应的指令:
可以看到FUNC是从栈上直接取来的函数地址,可以跳过去执行。那么可以从栈上取到一个libc中的地址。
经过调试,发现栈上存在一个write+0x10的地址,在栈上的相对偏移为13,相对libc的偏移为0xf72c0,相距最近的有一个one_gadget,偏移为0xf1147,相对偏移是-0x6179.
那么可以写出如下的指令:
翻译成字节码,利用溢出来覆盖,再触发一次VM,得到一个shell。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)