赞
踩
ID: 134 类型:基础 | 状态:草稿 |
描述
软件使用一个接受格式字符串作为参数的函数,但格式字符串来自外部源。
扩展描述
当攻击者可以修改外部控制的格式字符串时,这可能导致缓冲区溢出、拒绝服务或数据表示问题。
应该注意的是,在某些情况下,例如国际化,格式字符串集是由设计从外部控制的。如果这些格式字符串的源是可信的(例如,仅包含在系统管理员可修改的库文件中),则外部控件本身可能不会构成漏洞。
关联视图
与“研究层面”视图(CWE-1000)相关
同“公开弱点简图”视图(CWE-1003)相关
与“开发层面”视图(CWE-699)相关
同"七类最严重错误" 视图(CWE-700)相关
引入模式
阶段 | 说明 |
实现 | 程序员很少打算对格式字符串进行外部控制。在构造日志消息的代码中,经常引入这个弱点,其中省略了常量格式字符串。 |
实现 | 在本地化和国际化等情况下,特定于语言的消息存储库可能是一种利用途径,但格式字符串问题将是结果,因为攻击者对这些存储库的控制还允许修改消息长度、格式和内容。 |
应用平台
语言
C (经常出现)
C++ (经常出现)
Perl (很少出现)
后果
范围 | 冲击 | 可能性 |
保密性 | 技术冲击: 内存读取 格式字符串问题允许信息泄漏,这可以严重简化程序的利用。 | |
完整性 | 技术冲击: 执行未获授权的代码或命令 格式字符串问题可能导致执行任意代码。 |
被利用的可能性:
高
示例
例1
以下程序打印作为参数提供的字符串。
(问题代码)
Example Language: C
#include <stdio.h>
void printWrapper(char *string) {
printf(string);
}
int main(int argc, char **argv) {
char buf[5012];
memcpy(buf, argv[1], 5012);
printWrapper(argv[1]);
return (0);
}
由于在printWrapper()函数中调用了printf(),因此该示例是可利用的。注意:添加了堆栈缓冲区以使利用更简单。
例2
以下代码使用snprintf()将命令行参数复制到缓冲区中。
(问题代码)
Example Language: C
int main(int argc, char **argv){
char buf[128];
...
snprintf(buf,128,argv[1]);
}
此代码允许攻击者查看堆栈的内容,并使用包含一系列格式化指令的命令行参数写入堆栈。攻击者可以通过提供更多的格式化指令(如%x)从堆栈中读取,而不是将函数作为要格式化的参数。(在本例中,函数不接受要格式化的参数。) 通过使用%n格式化指令,攻击者可以写入堆栈,使snprintf()将到目前为止输出的字节数写入指定参数(而不是从参数中读取值,这是预期的行为)。这种攻击的复杂版本将使用四个交错写入来完全控制堆栈上指针的值。
例3
某些实现通过提供格式指令来控制内存中要读取或写入的位置,使得更高级的攻击更加容易。以下代码显示了这些指令的一个示例,这些代码是为glibc编写的:
(问题代码)
Example Language: C
printf("%d %d %1$d %1$d\n", 5, 9);
此代码产生以下输出:5 9 5 5还可以使用半写(%hn)精确控制内存中的任意双字,这大大降低了执行攻击所需的复杂性,否则将需要四个交错写入,如第一个示例中提到的写入
应对措施
阶段: 需求 选择不受此缺陷影响的语言。 |
阶段: 实现 确保所有格式字符串函数都传递一个用户无法控制的静态字符串,并且始终向该函数发送适当数量的参数。如果可能,请使用格式字符串中不支持%n运算符的函数。[参考-116][参考-117] |
阶段: 编译及链接 注意编译器和链接器的警告,因为它们可能会警告您使用不当。 |
种属
关系 | 类型 | ID | 名称 |
属于 | 635 | ||
属于 | 726 | ||
属于 | 743 | CERT C Secure Coding Standard (2008) Chapter 10 - Input Output (FIO) | |
属于 | 808 | ||
属于 | 845 | The CERT Oracle Secure Coding Standard for Java (2011) Chapter 2 - 验证输入 and Data Sanitization (IDS) | |
属于 | 865 | ||
属于 | 877 | ||
属于 | 884 | ||
属于 | 990 | ||
属于 | 1131 | ||
属于 | 1134 | SEI CERT Oracle Secure Coding Standard for Java - Guidelines 00. 验证输入 and Data Sanitization (IDS) | |
属于 | 1163 | SEI CERT C Coding Standard - Guidelines 09. Input Output (FIO) |
说明
应用平台
在任何支持格式字符串的编程语言中,这种弱点都是可能的。
研究空白
格式字符串问题正在研究中,除了C语言以外的其他语言。内存或磁盘消耗、控制流或变量更改,数据损坏可能是由于在用其他语言编写的应用程序(如Perl、PHP、Python等)中使用格式字符串而导致的。
其它
虽然格式字符串漏洞通常属于缓冲区溢出类别,但从技术上讲,它们不是溢出缓冲区。格式字符串漏洞是一个相当新的漏洞(大约在1999年),其原因在于,对于一个函数来说,没有实际的方法可以使用可变数量的参数来确定传入了多少个参数。最常见的接受变量数参数的函数,包括c-runtime函数,是printf()调用系列。格式字符串问题以多种方式出现。不带格式说明符的*printf()调用是危险的,可以被利用。例如,printf(input);是可利用的,而printf(y,input);在该上下文中是不可利用的。 第一次调用的结果(使用不正确)允许攻击者查看堆栈内存,因为输入字符串将用作格式说明符。攻击者可以用格式说明符填充输入字符串并开始读取堆栈值,因为剩余的参数将从堆栈中提取。最坏的情况是,这种不正确的使用可能会释放足够的控制权,允许将任意值(或漏洞利用程序的值)写入正在运行的程序的内存中。
通常目标实体是文件名、进程名和标识符。
格式字符串问题是一个经典的C/C++问题,由于其易发现性,目前很少出现。可以利用格式字符串漏洞的一个主要原因是%n运算符。%n运算符将把到目前为止格式字符串已打印的字符数写入其参数指向的内存。通过熟练地创建格式字符串,恶意用户可以使用堆栈上的值来创建一个任意写入的情形。一旦实现了这一点,他们就可以执行任意代码。也可以使用其他运算符;例如,一个%9999S运算符也可以触发缓冲区溢出,或者在文件格式化函数(如fprintf)中使用时,它可以生成比预期更大的输出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。