从gyctf_2020_some_thing_exceting复习double free机制(glibc-2.23源码分析向

前言

本文主要记录在double free攻击的时候碰到了非预期的错误,第一次尝试进行逐步分析,同时继续理解ELF的文件结构和glibc源码。
欢迎各位师傅交流、指正。

gyctf_2020_some_thing_exceting题目漏洞分析

ida查看可以看到,程序在一开始执行的时候就将flag文件读入了内存当中。同时byte_6020a0处设置了0x60的大小,这一点让我们可以构造fakechunk。
在这里插入图片描述
另外在free chunk的时候存在UAF漏洞,马上就可以想到利用double free操作修改fastbin链表来获得flag 附近内存的控制。
在这里插入图片描述

exp

题目详细分析文章地址, 我们截取开头一部分的exp。
可以看到首先进行了两次申请,后面马上做了double free的攻击,此处的double free是正常的。
在这里插入图片描述
但是当修改exp如下的时候,就会遇到double free的错误了。

add_heap(0x10,fake_rbp,0x50,"bbbb")
debug()
free_heap(0)
free_heap(1)
pause()
free_heap(0)
pause()

运行脚本,可以看到有了double free or corruption (out)的错误。只是修改了一下申请chunk的size,并没有修改double free的过程,怎么会产生错误呢?(当时反复思考也不知道是什么问题。于是就询问了一下xia0ji233大师傅。
在这里插入图片描述

double free错误分析

通过报错,我们可以选择相应版本的malloc源码进行搜索。在源码里可以看到,报错的是在3981行的位置。对应错误的原因是当前被free chunk的下一个chunk ,超出了top chunk的边界。(???怎么回事,我free一个正常的fast chunk 怎么可能超过top chunk的边界?)同时此处的检查是针对fastbin之外的chunk进行的检查,也不符合我们free chunk的大小。
在这里插入图片描述
后面接着查看报错的调用栈。可以看到是malloc.c 的3874 行调用了malloc_printerr输出报错的。(这里因为多次调试,具体地址与上面的对不上
在这里插入图片描述
再回到源码查看,3874行进行的检查,虽然检查会产生的错误结果不同,但确实是对释放chunl 的size进行了一个检查,而且最后的double free报错也是对除fast chunk之外的chunk进行的检查,所以我们进一步进行动态调试,在_int_free处下断点。(这里为了方便查看程序运行到何处,选择了自行编译源码进行调试,具体编译方法在后面讲。
在这里插入图片描述
可以看到,在3874行附近,被free的chunk 的size变成了一个很大很大的数,所以就没有进入fastbin 的free当中了,而是成为了其他的chunk。
在这里插入图片描述
那为什么会识别出那么大的size呢?我们查看一下当前被freechunk ($rdi = 0x86e250)附近的内存。0x86e250 + 8,也就是chunk的size字段是一个超级大的数值,其实也就是题目中的控制chunk里面的第二个成员指针。
在这里插入图片描述
至此,基本也就清楚了为什么会修改exp时产生了非fastbin的check的报错。还是回到ida的free操作中,第一次free的时候,是通过ptr管理指针找到需要被free的chunk。但是在进行了free_heap(0) free_heap(1)操作之后,ptr管理块也成了fastbin中的一员,也就修改了fd位置指针的值,从mem态变成了chunk态(指针减小了0x10),后面我们再次执行free(0)的时候,程序会把chunk态当作mem态,重新进行一次mem2chunk的转化,又让chunk指针减小了0x10。此外因为ptr管理chunk总大小是0x20,最后的0x8存储着chunk指针,因此这里的指针就会被当作size,所以就会比top chunk的边界要大得多了。
在这里插入图片描述

总结

当我们进行double free攻击的时候,如果有一个管理堆块存储着多个下级chunk的指针,那么需要特别注意和管理chunk同样大小的chunk的申请和释放,因为free fastbin chunk的时候,会对其fd指针进行修改,从而导致程序寻找的堆块出现偏差。

Glibc源码调试编译

搬运文章:编译可调试的libc.so文件

  • 下载需要版本的glibc源码并解压
  • 进入解压的目录执行命令 configure CFLAGS="-Og -g -g3 -ggdb -gdwarf-4" CXXFLAGS="-Og -g -g3 -ggdb -gdwarf-4" --disable-werror --prefix = <dir> 其中dir可以修改成存储编译文件的目录。
  • 最后make一下就ok了。make && make install
  • 调试之前patch一下程序链接的libc和ld文件

ELF程序符号表(题外话

搬运文章:so文件符号表
另外还有一篇好文章: 关于不同版本 glibc 更换的一些问题

1.动态链接库的符号表

动态链接库(shared object library)在linux里以.so结尾,是elf(Executable and Linkable Format)文件的一种,有两个符号表:“.symtab”和“.dynsym”。

.symtab: 包含大量的信息(包括全局符号global symbols)
.dynsym: 只保留“.symtab”中的全局符号
故“.dynsym”可看作“.symtab”的子集,命令strip会去掉elf文件中“.symtab”,但不会去掉“.dynsym”。

2.如何查看符号表?

未被strip的so库:
执行nm libbinder.so即可(默认查看.symtab符号表)。
被strip的so库:
由于.symtab符号表被移出,需要加上-D参数,如nm -Do libbinder.so。否则使用nm时提示no symbol。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值