是32位程序,Partial RELRO表明可以劫持got表,没有开canary和pie,开了NX栈不可执行
可以看出是典型的菜单题,打印menu,根据选项调用add_note,del_note,print_note和exit函数跟main函数看到的流程差不多,有add,delete,print三个功能可以看出notelist添加的的上限是6个,之后首先malloc一个0x8大小的chunk(记为chunk_note)存入notelist数组,接着 **((_DWORD **)¬elist + i) = print_note_content;这里是将chunk_note数据部分的前0x4个字节存放puts函数的地址,chunk_note的后0x4个字节用来存放用户想要申请的chunk,这个chunk的大小是用户自定义的。notelist运行一次add_note的情况如下图
可以看到该函数在free两个chunk时,没有将对应值置为null,这会导致uaf即use after free从前面可以知道每调用一次add_note函数,就会产生两个chunk,记为chunk0,chunk1,chunk1的size可以自定义,print_note函数就是用chunk0的前0x4个字节puts函数来打印chunk1的数据部分。程序还给了一个后门函数,只要我们能够成功调用这个函数就行了。利用uaf将chunk1的前0x4个字节存放的puts函数的地址修改为magic函数的地址,使得在执行print_note功能时,却是调用magic函数。我们可以先调用三个add_note,设置chunk1的size分别为0x8,0x8,0x16之后free第1和第2个note,我用notelisst[下标].chunk0|1来表示每个chunk,此时fastbin中数据部分只有0x8大小的链表是fastbin -> notelist[2].chunk0 -> nostlist[1].chunk0 -> notelist[1].chunk1
数据部分0x16大小的fastbin -> notelist[2].chunk1再接着调用add_note就可以使得分配得到的notelist[3].chunk1和notelist[1].chunk0是一致的,因此我们也就能修改notelist[1].chunk0,也就将puts_addr改成magic的地址,接着执行print_note函数,最终执行magic函数,拿到shell。
最后大概是这样子,图有点丑。。。
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-289227.htm
[原创][buuctf刷题记录]hitcontraining_uaf
185 浏览
0 回复
暂无回复,快来抢沙发吧!