ISCC2019 Pwn01 writeup
TOC
源程序下载:pwn01.zip
本题主要考察 ret2dlresolve 漏洞的使用。
程序功能介绍
安全防护
ex@Ex:~/test$ checksec pwn01 |
主要代码
; int __cdecl main(int argc, const char **argv, const char **envp) |
就是先把我们的输入读到全局变量buf
中,然后再将输入的内容复制到栈中。
分析
主要通过栈溢出来达到我们想要的目的,但是程序没有回显函数,也没有现成ROPgadget可以直接拿shell,我们也不知道glibc库的基地址,所以这题我们需要用到ret2dlresolve
漏洞来拿shell。
思路
- 控制程序流
- 构造好假的
Elf32_Rel
和假的Elf32_Sym
,让_dl_runtime_resolve
函数解析我们指定的字符串
控制程序流
只需要简单的栈溢出即可控制程序流。
offset = 0x100 |
这里之所以需要偏移,是因为我们后面的栈直接指向的buf_addr + offset
这个地址,所以我们需要先填充号中间的空缺。
之后调用read函数来读取我们构造好的内容,注意这里需要栈转移,否则很容易会出问题,具体情况需要调试glibc源码。
# 0x08048519 : pop esi ; pop edi ; pop ebp ; ret |
然后就控制程序流调用_dl_runtime_resolve
函数来解析我们构造好的函数名字符串,并传入“/bin/sh”参数,准备拿shell。
# _dl_runtime_resolve(link_map, rel_offset) |
这里要container_offset
偏移的原因是,我把要执行的栈和假的Elf32_Rel
和假的Elf32_Sym
放在了一起,所以中间需要用偏移间隔开来。
构造
计算地址
我们需要把我们所需要的地址全都计算好。
rel_plt_addr = 0x80482b4 |
构造好假的Elf32_Rel
和假的Elf32_Sym
布局,为了前面的调用_dl_runtime_resolve
函数做好准备。
layout2 = [ |
这样就可以解析我们的system
字符串并直接执行syste函数了,像sh_offset
的偏移都需要我们提前构造好,这题的难点可能就是在构造上面了。
完整脚本
#!/usr/bin/python2 |
运行实例
ex@Ex:~/test$ ./exp.py |
修复
填充指令
push ebp |
patched
.text:08048476 push 0F4240h |
将call _read
指令修改为我们填充的指令的地址。
总结
第一次接触ret2dlresolve
漏洞的时候,感觉这个漏洞是很难理解的,但是随着自己的调试,慢慢地就理解它的原理。
这里还要多多感谢ZhouYetao
师傅的指点。