格式化字符串的漏洞利用
liebian365 2024-12-31 12:44 107 浏览 0 评论
格式化字符串漏洞是一类允许攻击者在任意内存地址执行读或者写操作的软件缺陷。本教程主要关注C编程程序以及对格式化字符串函数的利用。
在我们开始理解软件缺陷之前,我们必须得先知道什么是格式化字符串。一个格式化字符串也就是一个ASCII字符串,其包括了文本和格式参数。例如,
printf("My name is: %s", "nops");
该函数调用将返回字符串
My name is: nops
该printf函数的第一个参数就是格式化字符串,它主要是依靠一个用来告诉程序如何进行格式化输出的说明符。在C程序中我们有许多用来格式化字符串的说明符,在这些说明符后面我们可以填充我们的内容。记住,说明符的前缀总是“%”字符,另外说明符存在许多不同的数据类型,最常见的包括:
?
1
2
3
4
5
6%d - 十进制 - 输出十进制整数
%s - 字符串 - 从内存中读取字符串
%x - 十六进制 - 输出十六进制数
%c - 字符 - 输出字符
%p - 指针 - 指针地址
%n - 到目前为止所写的字符数
可能会存在格式化字符串漏洞的函数包括(但不局限于)fprintf, printf, sprintf, snprintf,等
该漏洞的存在主要是程序员对于用户的输入没有进行好过滤造成的,下面我们通过一个例子进行说明:
#include
int main(int argc, char * argv[])
{
char a[1024];
strcpy(a, argv[1]);
printf(a);
printf("\n");
}
这段代码将把接收到的字符串作为参数,创建一个1024字符串缓冲区,接着将字符串复制到缓冲区,最后调用两个printf函数格式化输出。在正常情况下编译并运行,程序获取到的第一个参数是可预期的(如果你关注过缓冲区溢出漏洞就十分清楚)。
3root@localhost:~/#gcc test.c -o test
root@localhost:~/# ./test blah
blah
但是如果我们仔细查看printf文档,我们了解到调用的第一个参数是一个特殊的格式化字符串说明符。在我们这个简单的测试代码中,我们可以看到argv[1]将作为参数传递给printf函数。所以,我们有用户提供(即黑客提供)的数据将被解释成格式化字符串,这是十分危险的。接下来我们就看看这类攻击的示例
root@localhost:~/# ./test %s
TERM_PROGRAM=Apple_Terminal
我们键入%s作为攻击参数,它就会爆出一些有关我们终端的信息。为何会这样?这是因为printf函数认为它将要打印下一个堆栈地址,便将数据理解成了字符串。这是因为我们将%s作为格式化字符串(在代码中它仅仅是一个变量),接下来我们在漏洞程序中添加更多的格式化字符串,看看会发生什么。
root@localhost:~/# ./test %s.%s
TERM_PROGRAM=Apple_Terminal.(null)
目前,我们添加了第二个格式化字符串参数,通过“.”进行分隔,下一个堆栈的值为null。为第二个参数增加null的值,我们获取到与之前相同的终端信息。这种攻击是在堆栈中直接读取值,堆栈中如果存储有密码,密钥等那就想当危险了。我们尝试使用这项技术读取更多的信息,程序会爆分段错误。
root@localhost:~/# ./test %s.%s.%s
Segmentation fault: 11
但是我们可以进一步利用该漏洞,将值压入堆栈中。为了更好理解的这个工作原理,我们必须搞清楚printf规范中的两个特性,"%n"可以用来存储到目前为止所写的字符数,在相应的参数中用整数来表明变量名。
int i;
printf("ABCDE%n", &i);
printf函数会将5(刚刚写入的字符数)写入i变量么?
我们需要了解的第二个特性便是“$”操作符,其允许我们从格式化字符串中选取一个作为特定的参数。例如,
printf("%3$s", 1, "b", "c", 4);
最终会显示结果“c”。这是因为格式化字符串“%3$s”,它告诉计算机“把格式化字符串后面第三个参数告诉我,然后将参数解释为字符串”。所以,我们也可以这样做
printf("AAA%3$n");
printf函数将值“3”(输入的A的数量)写入第三个参数指向的地址。等等,我们这里没有第三个参数啊!记住咯,printf会使用堆栈上连续的参数。不论怎样,printf都会将“3”写入堆栈中某一个地址中。
好吧,我个人觉得是很酷的。我们获取堆栈中泄漏的数据,以及一个不受控制的原始任意写(write-what-where)。为了利用这个漏洞执行代码我们可以控制写入的内容,我们可以控制在哪里写入内容。我们只能在堆栈中的任意位置进行写操作,并非万能的。在下一节内容中我们会讲到ShellCode的开发,并给我们这个BUG添加攻击载荷,让我们可以控制数据。
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)