2021美团高校挑战赛-pwn
本文最后更新于:2023年10月15日 晚上
babyrop


main函数中v6变量仅占24字节,但却允许输入25个字节,刚好可以泄露cookie的值
在main函数伪代码中,输入v5的值处,并不是让v5的值为"password",而是要v5的值为"password"的地址
vuln函数中存在栈溢出,但溢出数据长度较小, 仅能做到修改rip的值,所以要通过多次栈迁移构造payload
1 | |
bookshop




- 程序中仅允许创建
24个chunk - 每个
chunk只有在创建时才能写入 - 释放时,没有清空指针,存在
UAF
目标是向free_hook中写入system函数地址,要实现这个目标,仅利用tcache bin是不够的,需要同时利用unsorted bin,将多个伪造的chunk放入tcache bin中,然后修改tcache bin链表结构
1 | |
在libc2.31中对unsorted bin的检测已经较为完善了,所以我们需要在unsorted bin原先完整的双链表中添加成员,使其看起来正常,
1 | |
因为只要对应的tcache bin中没有存满,程序就会将chunk放入对应的tcache bin中,而且这里存在uaf,所以我们只要先将chunk_a放入unsorted bin中,然后通过获取chunk使tcache bin为未存满的状态,然后再释放chunk_a,这样chunk_a就会同时存在于tcache bin与unsorted bin中,当下次获取chunk时,就会优先从tcache bin中获取,在这时修改chunk_a的值,就可以修改unsorted bin的结构
1 | |
Blindbox





- 总结出来整个程序就是只能创建三种
chunk,三种chunk的size由用户指定,但size必须在0x88~0x233之间 - 程序在释放
chunk时,没有清空指针,所以存在UAF - 整个程序只能修改两次
chunk的数据,其中一次只能修改前0x10的数据,也就是fd,bk字段的数据,另一次会创建一个0xa0的chunk,并且写入0x90个字节的数据 - 程序只能输出
chunk的fd字段的数据
当获取到system函数的地址之后,可以利用pay函数获取shell
因为程序只能通过创建一个0xa0大小的chunk,而向某个地址中写入0x90个字节的数据,所以我们需要做的就是将0xa0大小的tcache bin的第一个成员设置为我们要修改的地址,而直接释放chunk,并修改其fd,bk字段,是达不到要求的。所以我们只能先将chunk放入small bin中,然后创建对应大小的chunk,这时程序会将对应的small bin中剩下的chunk逆序存满tcache bin,只要我们修改了small bin中后面的某一个chunk的bk字段,就可以达到我们想要的效果
在libc 2.31中,通过small bin获取chunk时,只会检测第一个成员,与第二个成员之间的双链表结构是否成立,然后就会将第一个成员返回给用户,让剩余的成员填满tcache bin,在将small bin中的chunk放入tcache bin时,会设置下一个成员的fd段为对应的small bin的地址
1 | |
所以下面的难点就在于如何修改smallbin,通过上面的描述我们知道,使用正常的释放操作,无法在tcache bin未存满的状态下存在chunk,那么方法只有一个,那就是通过分裂一个较大的chunk,来构造一个0xa0的chunk,使其存在于unsorted bin中,然后再创建一个较大的chunk,这时就会将unsorted bin中的chunk放入对应的small bin中,因为这里0xa0的chunk是由分裂产生的,并不是通过释放获取的,所以正常来说我们是没有这个0xa0大小的chunk的地址,无法修改其数据
这里我们以0xa0 0xc0 0x160大小的chunk举例
首先需要将0xc0 0x160大小对应的tcache bin填满,然后创建两个0xc0的chunk_a与chunk_b
将这两个chunk释放掉,这时chunk_a与chunk_b都会与top chunk合并,然后创建一个0x160的chunk(chunk_a),这里需要再次创建一个chunk(chunk_t),这是为了防止chunk a与top chunk合并,释放 chunk_a,这时在unsorted bin中存在一个0x160大小的chunk_a,这时在创建一个0xc0大小的chunk(chunk_a),地址也与a相同,并且分裂出一个0xa0大小的chunk(chunk_b)放在unsorted bin中,因为chunk_a与chunk_b之间地址相差0xc0,所以这个0xa0大小的chunk其实就是chunk_b,只要再创建一个较大的chunk_t1,就可以将chunk_b放入small bin中,只要我们没有覆盖原先指向chunk_b的指针,我们就可以更改small bin的结构,只要再重复几次前面的操作,就可以绕过small bin的检测,使我们构造的chunk进入tcache bin中
1 | |
1 | |
1 | |