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 |
|