pwn题堆利用的一些姿势 -- free_hook

pwn题堆利用的一些姿势 – malloc_hook
pwn题堆利用的一些姿势 – IO_FILE
pwn题堆利用的一些姿势 – setcontext
pwn题堆利用的一些姿势 – exit_hook

概述

  在做堆题的时候,经常会遇到保护全开的情况,其中对利用者影响最大的是PIE保护和Full RELRO,NX保护和栈保护对堆利用来说影响都不大,一般利用也不会往这方面靠。开了PIE保护的话代码段的地址会变,需要泄露代码段基地址才能利用存储在bss段上的堆指针;开了Full RELRO的话,则意味着我们无法修改got表,导致无法修改其它函数got表指向system,进一步获取到shell。因此也就有了我这一系列文章的目的,在got表无法被修改时,我们往往利用的就是下面的一些hook+onegadget来达到我们的目的。
  主要分为以下几个系列:malloc_hook --> free_hook --> IO_FILE --> setcontext。

初级必备姿势

  下面介绍free_hook的初级必备姿势,free_hook是调用free函数之前会执行的钩子函数,利用方式和malloc_hook大同小异,所以建议学习这种利用方式之前先看下malloc_hook。熟练掌握malloc_hook的利用方式后,再看free_hook会觉得十分轻松,基本上感觉是换汤不换药。当然一般利用先想malloc_hook,毕竟堆题肯定是有malloc函数的,但却不一定有free函数,另外free_hook往上的内存数据中不一定存在0x7f的字节数据来帮助我们实现fast bin attack。
  好,废话不多说,接下来以2019年ciscn_en_3的pwn题为例,介绍free_hook的利用姿势,远程环境可以在BUUCTF上找到。该题目环境为Ubuntu18,需要利用tcache机制中的double free,不熟悉的读者可以参见这篇博文,pwn题堆入门 – Tcache bin
  程序分析:该题目保护全开,64位程序,使用libc-2.27.so,程序本身去除了符号名,可以自己修复一下,接下来我们直接定位漏洞,其余不重要的细节此处不再赘述。如下图所示,程序主逻辑中开头中存在格式化字符串漏洞,但由于开启了FORTIFY保护,所以对利用方式有点影响。这里可以简单总结一下开了FORTIFY保护下的格式化字符串漏洞利用,首先这里无法再使用%n来实现任意地址写,然后是无法使用%d$p(d代表大于1的数字)进行地址泄露;但是可以像这样连续使用%p%p%p%p来泄露数据。具体利用方式参见下面的wp。
printf
  另外查阅了一下网上相关的wp,发现有前辈是利用了puts(s)函数的溢出,即如下图所示,栈上"aaaaaaaa"的部分即是s的位置,我们将此处填满到8字节,由于puts在打印时遇到"\x00"才会停止,所以会将紧邻的setbuffer函数的地址打印出来,这样我们也能获得libc的地址。
puts
  如下图所示,是程序主逻辑的地方,主要实现了增删查改四个功能,但其中edit和show并没有实现具体功能,然后add是正常实现了堆块的分配,不存在溢出,delete存在uaf漏洞,再下一张图即是delete功能的具体实现。
main
free
  漏洞利用:首先利用printf格式化字符串漏洞泄露libc地址,计算出free_hook地址,然后利用tcache的double free将堆块分配到free_hook上,填写为one_gadget。
  如下图所示,我们先看gdb调试的结果,首先是printf_chk的格式化利用,这里即将call的就是printf_chk,由于加了保护,所以该函数有两个参数,第一个参数0x1代表保护级别存入寄存器rdi,第二个参数才是我们输入的格式化利用字符串%p-%p-%p存入寄存器rsi。我们可以看到寄存器rcx存放的是read+17的地址,根据64位linux下前6个寄存器传参的习惯(rdi/rsi/rdx/rcx/r8/r9),此处已经用了两个寄存器,所以第二个%p将会打印出rcx存放的值。到这里我们就获取到了libc上的地址,再根据libc计算出基地址和free_hook的地址即可。
fmt
  如下图所示,第一张图展示了wp的执行结果,通过在wp中打印地址可以方便我们直接在gdb中进行断点调试和验证。第二张图展示了gdb的中结果,可以发现free_hook处已经被修改为了one_gadget的地址,当然这里运气不错,one_gadget的执行条件满足,接下来我们继续执行就可以获取到shell了。
res
gdb
  这里给出wp。

from pwn import *


ld_path = "/home/fanxinli/libc-so/libc-27/ld-2.27.so"
libc_path = "/home/fanxinli/libc-so/libc-2.27-64.so"
p = process([ld_path, "./ciscn_2019_en_3"
  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值