基本原理
控制函数执行libc中的函数,通常需要先泄露libc文件版本和加载位置,然后通过相对偏移找到并执行相关函数或利用相关gadgets。
原理
一个ELF文件想要调用文件外定义的函数需要先进行加载和链接。链接根据是否是编译时完成分为非动态链接和动态链接。通常来说,我们做的libc的题是动态链接的。静态链接的优点是程序与glibc版本无关,在各版本ubuntu上都能运行,动态链接的优点是程序体积小。
我们只说动态链接过程,只有当程序第一次执行某个函数时才进行对该函数的链接。具体过程是:
- 先跳转到过程链表,也即
.plt
节处 - 跳转到全局偏移表,也即
.got
节处 - 调用动态链接器,也即
_dl_runtime_resolve
函数 - 之后动态链接器会找到函数的绝对地址然后将该函数地址回填到
.got
表对应位置并执行函数调用
我们的利用就是函数的绝对地址会在调用后存放在.got
中。
假设当前我们没有目标环境的libc文件,在构建rop链泄露函数地址之后,我们可以通过该函数后三位16进制数推测可能的libc版本。在知道libc版本之后,只需根据相对偏移算出目标函数的绝对地址即可加以利用。 假设我们有目标环境的libc文件,在构建rop链泄露函数地址之后,我们可以直接在libc文件中查找对应函数地址。
利用手法
下次再说