Pwn 题加了一些C++奇奇怪怪的东西,看到C++就有点反感。后续要花点时间学习一下C++ Pwn。
最近,在总结自己最近几场比赛的状态:1. 常规题自己虽然能做,但是太慢了,拿不到blood,还有比赛有时候会遇到一些突发状况。以后这种题就要做的又快又稳;2. 新题,这类题其实原理不复杂,但是可能夹杂了许多干扰,就导致自己把自己吓住了,这以后一定要能够细致的分析题目加坚持;3.难题,这类题可能就是比较难的方向,但是一定要坚持分析看下去,先把题目的思路理清楚,然后再分析能不能做。
最后,以王安石《游褒禅山记》中的一句话,算是给以后一个方向吧:
世之奇伟、瑰怪,非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也。
Einstein
程序分析
漏洞点很简单,主要是check
的时候,如果name
check
不过,会free(chun1)
,而 Passwd
不过时,会输出 chunk1
的内容,此时就可以泄露 libc
地址。
1 | __int64 __fastcall check(__int64 a1) |
然后就可以修改3字节,来 getshell
。
利用分析
这里泄露出 Libc
地址后,只能修改3字节来 getshell
。
其实,很久之前应该是做过修改 exit_hook
来 getshell
的题,但是太久远已经忘记这种方法。(:这也说明我做题后面复习的时候,没有仔细调试,所以就没有太多记忆:)在这里分析一下:
首先分析一下 exit.c
源代码,exit
源代码会调用 __run_exit_handlers
函数
1 | void exit (int status) |
然后 __run_exit_handlers
的主要逻辑就是去调用注册的exit
的处理函数,我们主要关注这里面的exit_function_list
结构体,程序会接着执行三个call
指令。我们通过动态调试看看这三个call
会调用什么函数。
1 | //经删减 |
接下来我们动态调试一下这三个call
指令的调用关系:
我们从 _dl_fini
源码中可以发现,其中调用了两个函数 __rtld_lock_lock_recursive
和 _rtld_lock_unlock_recursive
两个函数。
1 | void internal_function |
而这两个结构体存放在 _rtld_global
结构体中,这个结构体我们是可以直接在gdb
中找到地址:
因此,我们可以找到两个固定的libc
地址,只需要劫持这两个函数指针,我们就可以成功劫持 exit
函数。
总结:
exit()中执行流程为exit()->__run_exit_handlers->_dl_fini->__rtld_lock_unlock_recursive
由于__rtld_lock_unlock_recursive
存放在结构体空间,为可读可写,那么如果可以修改__rtld_lock_unlock_recursive
,就可以在调用exit()时劫持程序流。_rtld_lock_lock_recursive
也是一样的流程。
EXP
1 | from pwn import * |
IO_FILE
程序分析
2.27 glibc
下的tcache double free
攻击。是简单题。
利用分析
唯一需要 注意的就是,这里由于程序没有开PIE
,可以直接先修改 chunk_list
,将一些无用块指针清空。这样才能保证后面 getshell
时的 chunk
数量不会超出。
EXP
1 | from pwn import * |
- 本文作者: A1ex
- 本文链接: http://yoursite.com/2020/11/26/2020安洵杯/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!