首页
社区
课程
招聘
[原创]格式化字符串漏洞简介
发表于: 2019-8-6 18:31 22839

[原创]格式化字符串漏洞简介

2019-8-6 18:31
22839

格式化字符串漏洞是一种比较常见的漏洞类型,主要是printf.sprintf和fprintf等c库中print家族的函数.先看看printf的函数声明:

这应该是所有人学习的第一个函数了,先是一个字符串指针,他指向一个format字符串,后面是个数可变的参数.在c程序中我们有很多用来格式化字符串的说明符,在这些说明符后面我们可以填充我们自己的内容.最常见的包括:

在这众多的格式符中有一个异类需要注意,别的都是用来打印数据的,而%n可以用来把一个int型的值写到制定的地址去.printf一般我们这样使用:

但是如果偷懒写成这样子:

看起来没什么问题,而且运行也很正常,但却产生了一个非常严重的漏洞.

正常情况下

汇编源码主体是这样:

运行到这里的时候栈是这样的:

本来函数应该按照cdecl函数调用规定从右边函数开始逐个压栈,但是printf是c语言中少有的支持可变参数的库函数.函数的调用者可以自由的指定函数参数的数量和类型,被调用者无法知道在函数调用之前到底会有多少个参数被压入栈中,所以printf函数要求传入一个format参数以指定参数的数量和类型,然后他就会忠实的按照函数的调用者传入的格式一个一个的打印函数.

那么问题来了,如果我们无意或者有意在format中要求printf函数打印的数据数量大于我们所给的数量会怎么样?下面的代码实验一下:

栈的情况和上面的代码除了format不一样之外大致都一样:

编译的时候会有warning,输出为

我们只给了五个参数,却让他打印7个数据.printf确实按照我们的意愿打印了七个数据,但多出来的两个却不是我们输入的,而是保存在栈中的另外两个数据.通过这个特性,就有了格式化字符串漏洞

任意地址读需要用到printf的另外一个特性,$操作符.这个操作符可以输出指定位置的参数.利用%n$x这样的字符串就可以获得对应的第n+1个参数的数值(因为格式化参数里边的n指的是格式化字符串对应的第n个输出参数,那么相对于输出函数来说就成了第n+1个).
示例程序:

首先测一下字符串开头的偏移量:

由结果可知偏移为6,然后编写脚本:

通过脚本我们读取到了0x08048000地址(即elf文件)的前几字段

如果程序中含有其他漏洞能够让我们控制eip来反复调用printf函数我们甚至可以把整个elf或者libc拖下来都是可以做到的

任意地址写就要用到上面说的%n了.示例程序:

这个程序中c的值被我们改成了11,但作为代价我们输入了长达11的字符串,如果我们想自定义打印字符段的宽度可以这样写:

这样我们就把c的值修改为100了.如果我们想把值修改为0x12345678就真的要回显0x12345678个字符吗?并不是,提供一份表:

举个例子,我们希望向0x08048000写入值0x10203040,可以这样构造:

分解一下就是四个地址加上四个格式化字符

即对0x08048000写入16+48=64=0x40
对0x08048001写入0x40+240=304=0x130=0x30
对0x08048002写入0x30+240=288=0x120=0x20
对0x08048003写入0x20+240=272=0x110=0x10
但是这个payload以0x00开头,可以手工调整一下,调换地址与格式化字符的位置,还要改一下n的值.


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 6
支持
分享
最新回复 (6)
雪    币: 11
活跃值: (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢答主!受教了
2020-1-3 20:48
2
雪    币: 288
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
写的非常详细~~
2020-2-3 14:32
1
雪    币: 163
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
受教了,谢谢答主分享
2020-3-5 11:56
0
雪    币: 443
活跃值: (1157)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
AAAA%6$x
AAAA41414141# 
这里符串开头的偏移量是什么原因,能详细解析下吗?
2020-5-25 23:03
0
雪    币: 443
活跃值: (1157)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
burning@burning-RedmiBook-14-APCS:~/linux$ ./test 
AAAA%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x
AAAAffa6c6d8,f7efce89,565d35e4,ffa6c70c,ffa6c7fc,41414141,252c7825,78252c78,2c78252c,252c7825,78252c78burning@burning-RedmiBook-14-APCS:~/linux$ ./test 
AAAA%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x
AAAAff945b68,f7f81e89,566085e4,ff945b9c,ff945c8c,41414141,252c7825,78252c78,2c78252c,252c7825,78252c78。是这样子的吧
2020-5-26 23:01
0
游客
登录 | 注册 方可回帖
返回
//