编程语言
首页 > 编程语言> > 劫持vtable修改程序执行流——pwnable seethefile

劫持vtable修改程序执行流——pwnable seethefile

作者:互联网

前置知识

vtable

vtable是和file结构体并列的一段内容,是函数指针数组,其中包含了对file的一些操作函数。
以下来自ctf-wiki
在 libc2.23 版本下,32 位的 vtable 偏移为 0x94,64 位偏移为 0xd8
在这里插入图片描述
以下是vtable的实际结构,如图所示,我们需要关注的是close部分。也就是关闭文件时将会调用的函数。
在这里插入图片描述## 劫持原理
以下内容摘自https://www.jianshu.com/p/2e00afb01606
分析close函数,最关键的利用点在这里
在这里插入图片描述
注意到_IO_FINISH(fp)是vtable中的一个函数,而参数又是我们可以控制的,因此可以通过劫持函数和参数来控制执行流。但是前提是通过前面的if,这里检查的是

fp->_IO_file_flags & _IO_IS_FILEBUF

其中_IO_IS_FILEBUF被定义为0x2000.
因此,只需要在file指针的flag位置放上0xffffdfff即可(或者是别的,只要满足fp->_IO_file_flags & _IO_IS_FILEBUF=0来绕过判断都可以)所以程序接下来会执行_IO_FINISH。
因此,总的来说就是布置fp("/bin/sh"地址),fp->flags(0xffffdfff),vtable->finish(system)这三个参数,来实现最终的getshell。

seethefile

这里可以看到的是,程序可以实现读写除了flag之外的其他文件,参考了别人的wp.知道了原来/proc/self/maps可以输出自己虚拟空间的映射方式,从而获得libc基地址。这里注意要输出两次,第一次输出不完。
在最后有个明显的scanf漏洞,注意到fp指针也在bss段上,因此可以考虑溢出劫持fp。具体的布置方法如下
在这里插入图片描述
简单分析下流程:先调用fclose,发现fp->flag & 0x2000不满足上述if条件,就调用finish函数,现在全是system,其中的参数是fp,被我们布置为指向fp->flags的地址,怎么不是/bin/sh啊?因为没办法,第一位必须是flags位,接下来因为分号截断,就成功调用/sh来作为system参数,拿到shell。
在这里插入图片描述
这里比较无语的是为了防止奇奇怪怪的拿到flag,还必须用他的seethefile文件夹下的程序打开才能行…自己探索吧!

标签:fp,vtable,IO,pwnable,程序执行,flag,flags,file
来源: https://blog.csdn.net/weixin_46521144/article/details/119010100