热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【技术分享】溢出利用FILE结构体

作者:

作者:rac_cp

稿费:300RMB(不服你也来投稿啊!)

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


前言

最近的上海大学生网络安全赛就只出了一题pwn450,对于还不是很会的我,瞬间懵逼,不过大佬还是大佬,最后还是挺多大佬做出来了,不过反正我没做出来,最后看题解,用到了两个点,一个是堆溢出,另一个就是利用这个FILE结构体做文章;菜鸡的我只有一个一个学,堆溢出的这点后面再学,先学习了如何利用FILE结构体,也就写出了这篇文章。学习的过程主要也是看大牛的博客文章写出来的,在最后也会附上相应的文章。


一、结构体介绍

首先介绍下FILE结构体,下面图就是FILE结构体:

http://p1.qhimg.com/t016ecaea604dd19c4b.png

平常我们正常使用FILE结构体的情景是:

http://p5.qhimg.com/t015f9266b53e802514.png

此时,系统会给应用程序申请一段空间将相应数据赋值好后然后将地址返回给fp。事实上,系统并不是直接分配的FILE(_IO_FILE)结构体,而是名字为_IO_FILE_plus结构体,这个结构体包含了_IO_FILE结构体,还包含了一个虚函数表指针,其定义为:

http://p6.qhimg.com/t01189975e4846fe10a.png

这个结构体里面的_IO_jump_t指针类似于C++中的虚函数表,而其结构中具体虚函数名称定义如下:

http://p4.qhimg.com/t01b781807ef3b43905.png

二者之间的整个关系结构图如下:

http://p4.qhimg.com/t01b40ad4596d99e588.png

图片来源:https://outflux.net/blog/archives/2011/12/22/abusing-the-file-structure/


二、利用原理

我们平常在应用程序中调用fclose、fputs这些函数的时候系统最终都会通过_IO_jump_t这个函数表指针对函数进行调用(如fclose会调用close函数等)。

在知道了这一点后,试想如果我们想办法利用其他各种溢出方式覆了应用程序的文件指针,使其指向我们可控区域,在该区域伪造相应的_IO_FILE_plus头(主要是_IO_jump_t表或者是表中函数的指针),最终在程序调用fclose函数或其它函数的时候,就可以控制程序去执行我们想要它执行的地址,control the eip, control the world。

比较常见的是利用strcpy,strcat等覆盖了文件指针然后进一步利用,下面会举两个例子来进一步理解如何实现,一个是利用UAF来覆盖修改指针,一个是利用strcpy栈溢出。


三、实例

1)UAF利用

直接贴出源代码(来源:https://outflux.net/blog/archives/2011/12/22/abusing-the-file-structure/):

http://p4.qhimg.com/t016de8e09f8823cf4c.png

可以看到,程序首先申请_IO_FILE_plus (sizeof(_IO_FILE+sizeof(void)) 结构体大小的内存块,接下了free掉,紧接着打开一个文件,此时系统会将刚刚释放掉的内存空间分配给文件指针(不懂可以先去看下UAF的相关资料)即此时str与fp指向同一块内存空间,这时利用str将fp结构体的_IO_jump_t指针指向我们伪造的funcs数组,同时再系统最后调用fclose的时候,即调用_IO_jump_t里面的close函数的时候最终变成了调用我们定义的pwn函数,最终程序执行截图如下:

http://p6.qhimg.com/t01f3749364d7ec4b2d.png

2)栈溢出利用

先贴出源码(看了别人的文章以后改编的)

http://p8.qhimg.com/t01485bac180c8283f1.png

程序的意思是将”abc…..”这个字符串写进到aa.txt中,编译。

首先是漏洞的发现,可以输入最多1046个字符,最后strcpy拷贝到stage缓冲区中,会造成缓冲区溢出,拖进IDA中,如下图

http://p3.qhimg.com/t0140344d552cd1f71a.png

可以看到stage为bp-0x41A而fp指针则为bp-0x8,也就是说在输入长度大于0x41a-0x8=0x412(1042)的时候就可以覆盖fp指针,最大允许输入为0x416,多四字节,刚好可以覆盖fp指针,为了降低难度只体现利用FILE结构体的思想,程序中没有要求我们自己泄露栈地址什么的,而是直接给出了buff地址,所以可以直接覆盖fp指针,指向buff中的地址。最后在调用fputs(源代码是fprintf,编译的时候优化成了fputs)的时候,我们把它调用_IO_jump_t结构中对应的函数地址改写成get_flag函数的地址即可。

在写exp的时候还遇到了不少的困难,下面说我是怎样一步一步解决的。大牛的文章是将stderr指针中的数据拷贝到我们输入的内存中(详细情况可以参考http://www.evil0x.com/posts/13764.html),可是我想文件指针里面的数据要不都是地址要不都不怎么用,如果我们事先使用gdb将stderr里面数据拷出来,由于地址随机化的影响,数据很大肯能性已经变得不可访问了,这样容易出错,在看了一遍_IO_FILE结构体后我决定直接将fp里面的数据全都覆盖成stage的地址。前面我又已知了系统的_IO_FILE结构体大小为0x94(148),所以在0x94后面的数据我把_IO_jump_t函数表指针的值设置成了stage+180的地址,在stage+180的地方伪造_IO_jump_t的函数表,并将函数表里面的地址都指向get_flag函数。这样最初写出来的exp代码如下:

http://p7.qhimg.com/t01d8f4d20f8cb82df0.png

执行脚本…….

http://p3.qhimg.com/t0188ae57519e080852.png

没有任何反应,gdb附载程序,看下哪里出错,断点下在fputs函数调用前。重新执行脚本

http://p0.qhimg.com/t01e791ee14b4e5e03f.png

可以看到执行fputs时,此时的fp指针是0xbf9e3c76,而打印出来的stage地址为:

http://p7.qhimg.com/t0181c4a918030f05a9.png

二者相同,说明第一 步我们已经成功,即将fp指针覆盖成我们输入的地址,可以看下此时stage地址中的数据内容

http://p1.qhimg.com/t01e9743798a047ac52.png

全都是stage的地址,到这一步还没错,接下来按c继续执行看哪出错。程序崩了,重新再来一次,这次不下断点,直接看哪里出错

http://p9.qhimg.com/t01fe1d64d6201327ec.png

程序错在fupts+141这里,也就是call[eax+0x1c]这里,查看eax寄存器里面的内容

http://p5.qhimg.com/t0115be24cca98d45f4.png

发现和stage的地址很像,只是错位了两个字节

http://p9.qhimg.com/t01bf4e2acc0a15ea51.png

往上追溯,看eax是在哪赋值的,由于之前的调试,现在我直接去看fputs+120的地方。

http://p2.qhimg.com/t01e5617b043c53da2a.png

看到在fputs+123的地方将eax赋值,查看esi寄存器

http://p7.qhimg.com/t01875e7fe8932866c0.png

发现是stage的地址,其实也就是文件指针,fputs+123代码将文件指针+0x94(_IO_FILE大小就是0x94),刚好是_IO_jump_t函数表指针的地址,不过这里还多加了个eax*1,继续往前翻,看eax来自于哪里

http://p1.qhimg.com/t012e426c3f59a0daf6.png

可以看到eax寄存器中的内容来自于esi+0x46,突然想起之前的_IO_FILE结构图,

http://p0.qhimg.com/t014c9c42843181811f.png

里面有个offset字段,也就是说通过_IO_FILE指针寻找_IO_jump_t函数表指针的时候不是直接+0x94得到的,而是通过+0x94+offset得到的,之前我们输入的offset可能会很大,导致访存错误,所以下一步修改我们输入的offset字段,也就是偏移0x46处的内容,由于strcpy会截断,故该字段值不能为’x00’,为了方便,我把它直接改成了0x4,同时此时需要将伪造的_IO_jump_t函数表指针地址往后移四个字节。修改后的exp如下:

http://p5.qhimg.com/t01f9c625464b61ea4b.png

同时在执行的时候,在fputs+109处下断点,观察eax寄存器中的值

http://p9.qhimg.com/t012d69b342007795b1.png

可以看到此时esi+0x46的值正是我们所控制的0x4,继续跟,直到跟到取出_IO_jump_t函数表指针地址的地方,在我这里也就是fputs+123的地方

http://p0.qhimg.com/t0165b62b27887b6f14.png

可以看到此时计算esi+0x94+eax后所指向的地址,正是我们写的指向get_flag函数的地址,进一步查看它偏移0x1c的地址

http://p4.qhimg.com/t01562676f83d9ea581.png

仍然为get_flag函数的地址(因为我在脚本里将整个_IO_jump_t表函数地址都写成get_flag的地址)。最后在call的时候,就会跳到get_flag函数那里去执行。从而得到shell

http://p9.qhimg.com/t01b67d1a4167fd779e.png

到这里就算完成了利用,最后结果如下

http://p8.qhimg.com/t01fd9f9f95201e7f42.png

最后再提一下,在这里fputs首先调用的是_IO_jump_t+0x1c的地址,

http://p0.qhimg.com/t011fe0172332e73511.png

(JUMP_INIT_DUMMY 8个字节),也就是先调用xsputn函数(我也不知道干什么用,之前我猜的是会调用write函数,不过可能是初始化调用这个函数,后面可能还是会调用write,有兴趣的可以继续跟下去),在这里提一下是后面如果遇到,在不覆盖全部指针的情况下,仍然知道如何处理。

到这里,就算写完了。还有就是脚本跑个五六次可能会有一俩次出错,重新跑一次就行了,猜测是stage地址刚好包含’x00’,导致strcpy直接截断,而不复制,最后无果而终,地址随机化开了,多试个一两次就好。


四、 小结

利用FILE结构体,最主要的就是那个函数表,控制了它就可以控制函数的流程,linux系统也没有进行检查,可能后面会进行修补吧,不过修了也没关系,大牛们总会有办法的,不过这就和我没什么关系了。现在想想,这个其实也不是很难,只是一个知识点还可以接受,上海的比赛把这个和堆结合起来有有点蒙圈了。

学了这个之后,下一步可能会针对上海的那题再学下堆的利用,再把二者结合起来再总结一下。

第一次写文章,里面应该有很多不对的地方,有什么吐槽的尽管说,我会学习了以后再修改。最后再感谢下大牛们的博客,学到了很多东西,也再一次看到了差距,还要继续努力。


五、 参考资料

1、http://www.evil0x.com/posts/13764.html

2、https://securimag.org/wp/news/buffer-overflow-exploitation/

3、https://outflux.net/blog/archives/2011/12/22/abusing-the-file-structure/

4、http://repo.thehackademy.net/depot_ouah/fsp-overflows.txt


推荐阅读
  • Apache Shiro 身份验证绕过漏洞 (CVE202011989) 详细解析及防范措施
    本文详细解析了Apache Shiro 身份验证绕过漏洞 (CVE202011989) 的原理和影响,并提供了相应的防范措施。Apache Shiro 是一个强大且易用的Java安全框架,常用于执行身份验证、授权、密码和会话管理。在Apache Shiro 1.5.3之前的版本中,与Spring控制器一起使用时,存在特制请求可能导致身份验证绕过的漏洞。本文还介绍了该漏洞的具体细节,并给出了防范该漏洞的建议措施。 ... [详细]
  • 在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的步骤和方法
    本文介绍了在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的详细步骤和方法。首先需要下载最新的Java SE Development Kit 9发行版,然后按照给出的Shell命令行方式进行安装。详细的步骤和方法请参考正文内容。 ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • Jquery 跨域问题
    为什么80%的码农都做不了架构师?JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念。当然 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文总结了Linux下多线程执行shell脚本的4种方法,包括切换到工作目录执行、使用绝对路径执行、直接使用bash或sh执行。同时介绍了为什么需要加上"./"来执行脚本的原因。 ... [详细]
  • 本文讨论了读书的目的以及学习算法的重要性,并介绍了两个算法:除法速算和约瑟夫环的数学算法。同时,通过具体的例子和推理,解释了为什么x=x+k序列中的第一个人的位置为k,以及序列2和序列3的关系。通过学习算法,可以提高思维能力和解决问题的能力。 ... [详细]
  • 腾讯安全平台部招聘安全工程师和数据分析工程师
    腾讯安全平台部正在招聘安全工程师和数据分析工程师。安全工程师负责安全问题和安全事件的跟踪和分析,提供安全测试技术支持;数据分析工程师负责安全产品相关系统数据统计和分析挖掘,通过用户行为数据建模为业务决策提供参考。招聘要求包括熟悉渗透测试和常见安全工具原理,精通Web漏洞,熟练使用多门编程语言等。有相关工作经验和在安全站点发表作品的候选人优先考虑。 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • GSIOpenSSH PAM_USER 安全绕过漏洞
    漏洞名称:GSI-OpenSSHPAM_USER安全绕过漏洞CNNVD编号:CNNVD-201304-097发布时间:2013-04-09 ... [详细]
author-avatar
hongxiaochen8847_106
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有