Linux pwn入门教程——格式化字符串漏洞

本文深入探讨了Linux环境下格式化字符串漏洞的原理与利用,通过实例展示了如何利用该漏洞实现任意地址读写,从而进一步获取shell。文章详细解释了printf函数的潜在风险,以及如何构造payload来泄露和修改内存中的数据。此外,还讨论了64位环境下的格式化字符串漏洞利用及其挑战,并提到了防止这类漏洞的缓解机制,如RELRO和FORTIFY。
摘要由CSDN通过智能技术生成

本文作者:Tangerine@SAINTSEC

原文来自:https://bbs.ichunqiu.com/thread-42943-1-1.html

0×00 printf函数中的漏洞printf函数族是一个在C编程中比较常用的函数族。通常来说,我们会使用printf([格式化字符串],参数)的形式来进行调用,例如

image.png

然而,有时候为了省事也会写成

image.png

事实上,这是一种非常危险的写法。由于printf函数族的设计缺陷,当其第一个参数可被控制时,攻击者将有机会对任意内存地址进行读写操作。

0×01 利用格式化字符串漏洞实现任意地址读首先我们来看一个自己写的简单例子~/format_x86/format_x86

image.png

这是一个代码很简单的程序,为了留后门,我调用system函数写了一个showVersion().剩下的就是一个无线循环的读写,并使用有问题的方式调用了printf().正常来说,我们输入什么都会被原样输出

image.png

但是当我们输入一些特定的字符时输出出现了变化。

image.png

可以看到,当我们输入printf可识别的格式化字符串时,printf会将其作为格式化字符串进行解析并输出。原理很简单,形如printf(“%s”,“Hello world”)的使用形式会把第一个参数%s作为格式化字符串参数进行解析,在这里由于我们直接用printf输出一个变量,当变量也正好是格式化字符串时,自然就会被printf解析。那么后面输出的内容又是什么呢?我们继续做实验。

我们直接在call _printf一行下断点然后以调试方式启动程序,然后输入一大串%x.,输出结果如图

image.png

此时的栈情况如图

image.png

我们很容易发现输出的内容正好是esp-4开始往下的一连串数据。所以理论上我们可以通过叠加%x来获取有限范围内的栈数据。那么我们有可能泄露其他数据吗?我们知道格式化字符串里有%s,用于输出字符。其本质上是读取对应的参数,并作为指针解析,获取到对应地址的字符串输出。我们先输入一个%s观察结果。

image.png

我们看到输出了%s后还接了一个换行,对应的栈和数据如下:

image.png

栈顶是第一个参数,也就是我们输入的%s, 第二个参数的地址和第一个参数一样,作为地址解析指向的还是%s和回车0x0A。由于此时我们可以通过输入来操控栈,我们可以输入一个地址,再让%s正好对应到这个地址,从而输出地址指向的字符串,实现任意地址读。

通过刚刚的调试我们可以发现,我们的输入从第六个参数开始(上图从栈顶往下数第六个‘000A7325’ = %s\n\x00)。所以我们可以构造字符串”\x01\x80\x04\x08%x.%x.%x.%x.%s“。这里前面的地址是ELF文件加载的地址08048000+1,为什么不是08048000后面再说,有兴趣的可以自己试验一下。

由于字符串里包括了不可写字符,我们没办法直接输入,这回我们用pwnt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值