2016-Asis-books_writeup

本文详细分析了一道64位全保护堆题,通过堆利用技术泄露Libc并篡改malloc_hook获取shell。介绍了程序功能、漏洞利用思路以及exp的编写,特别讨论了off-by-null漏洞的利用方法,包括如何通过mmap泄露Libc地址和利用edit功能实现任意地址写入。
摘要由CSDN通过智能技术生成

wiki上的一道经典例题,写wp的目的一方面是wiki上一些细节讲的有点不太清楚,一方面是自己巩固一下做过的题目,看是否是真的掌握。

首先提供题目二级制文件链接:books

预览:

拿到题目先看基本信息:

可以看到题目是64位文件,所有保护全开,一般这种题目是堆题,且看到full relro则大概率是篡改malloc_hook。

然后运行一下,找到程序运行入口,然后放入ida里看反汇编码:

准备功能分析:(不要忽视,做的题多了会发现有时候这里可能存在关键漏洞)

这里因为我已经做过了,所以函数名和一些变量名已经被我改成了对应的功能,可以看到程序开头先打印欢迎语,然后让我们输入作者(字符串储存在bss段,是可控的),这里的输入函数存在off-by-null漏洞,当输入32个字符时,既可以用来change,又可以用来leak(因为字符串后面没有‘\x00’,所以可以泄露authername这个字符串之后的内容直到’\x00’,这也是常见的套路。。。)

input_authorname函数

my_input_leak函数

程序主功能分析:

程序有五个功能:1.create 2.delete 3.edit 4.print 5.change_authorname,大致的整体功能实现就是用户申请书本,然后书的名字和内容大小都由我们自己来定,并将它们的内容存放在堆上,然后创建一个大小固定的Book结构体来储存被创建的book的信息,其也放在堆上,创建一个book以后堆上的结构和bss段的联系大概如下图所示:

create one book

紧接着删除功能删除booklist中的Book指针,并且将指针归0,没有uaf漏洞

然后edit功能就是将Book的des重新输入,没有漏洞

然后是print功能,打印书的ID,name,des和书的作者,这个漏洞之前提过,分析bss段的结构就可以发现打印作者使可以泄露第一个book指针,这里需要注意,因为之后的所有chunk大小我们都可以自己控制,所以经过简单的计算,就等于我们泄露了所有的book指针和name,des指针!!!这是解题的一个关键之处。

再之后是change_authorname功能,就是更改作者的名字,当输入32个字节时依然存在off-by-null漏洞(因为是off-by-null,不是off-by-one,所以难度会有所加大)。

漏洞利用思路:

leak:

  1. 在前面已经提过,利用authorname最后一个字符’\x00’被book指针覆盖所以可以泄露book1指针的值,从而泄露之后所有的指针。
  2. 难点在于怎样泄露Libc,这里有一种新的方法,适用于chunk大小我们自己可控并且其地址可以泄露的情况,我们把book2的name和des申请的大于128KB(0x20000),则ptmalloc2将会用mmap来为我们分配内存,然而mmap的地址和libc的地址相对偏移不变(经过一次调试就能确定偏移),所以我们只要泄露了book2的name地址就等于泄露了libc,那再思考怎样泄露book2的name地址呢?现阶段我们只能利用程序自带的打印功能,他将打印所选的book的name指针和des指针所指向的内容,由book1指针已经由于off-by-null而最后一个字节被变为00,其之前肯定大于0,因为内存的分页分配机制,所以想让其被改过后的book1指针落入book1的des中,book1的des要相对的大一点。。。并且利用edit功能来重新编写book1的des,在book1指针指向的那个地方(这里的偏移不变,通过调试确定)伪造一个fake_book2_struct,其name指针为book2的name指针的地址(为addr_book1+56),然后利用打印功能来leak出book2的name指针的值,Libc泄露成功!!!

change:

利用程序自带的edit功能来改malloc_hook为one_gadget(one_gadget需要多次尝试),因为我们已经可以掌控book1的des指针的值了,所以也就实现了任意地址写入。之后再次申请的时候就会触发malloc_hook拿到shell。

exp如下(我当时做的时候是改free_hook,具体的一些偏移量需要自己调试来确定,exp只提供思路!!!):

#coding:utf-8

from pwn import *

context(os = 'linux',arch = 'amd64')
context.log_level = 'debug'

p=process('./b00ks')
P=ELF
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值