程序用了UPX壳保护,通过upx –d脱壳后,拿到IDA里分析。

Delete以后没有清空指针,存在UAF,但是无法double free,因为程序中使用虚表调用,delete一次后,虚表对应位置已经被清空。因此第二次delete同一个chunk将进入else语句,进而崩溃。由于函数指针放在chunk里,因此,我们可以伪虚表指针,再利用UAF来执行。由于使用的是upx加壳,脱壳后,显示NX保护是关闭的,但是宿主是upx的壳,upx壳程序通过mmap映射出RWX的内存放置受保护的程序,因此,在这里堆栈是可执行的,也可以通过gdb调试查看。因此,我们在堆里布置下shellcode。
我们先申请两个堆释放
add(2,0x20/4,[-1])
add(3,0x20/4,[-1])
delete(2)
delete(3)
接下来我们触发malloc_cosolidate
add(4,0x100,[-1])
此时,2的fd伪造写上了main_arena 88的地址

因此,main_arena_88被当成一个虚表
Main_arena_88+0x10处指向2的头

Show功能取得正是vtable+0x10处的函数指针来执行

因此, Main_arena_88+0x10处的数据被当成一个函数指针,因此,我们只要利用堆的共用,在2的prev_size处布置一条jmp $xxxx的指令,然后通过show(2)就可以执行这个jmp,跳到主shellcode里。
1 | #coding:utf8 |