ID: 806 类型:变量 | 状态:未完成 |
描述
软件在读取或写入目标缓冲区时使用源缓冲区的大小,这可能导致它访问缓冲区边界之外的内存。
扩展描述
当目标的大小小于源的大小时,可能会发生缓冲区溢出。
相关视图
"研究概念"视图 (CWE-1000)
Nature | Type | ID | Name |
ChildOf | 805 |
"开发概念"视图 (CWE-699)
Nature | Type | ID | Name |
ChildOf | 805 |
引入模式
阶段 | 说明 |
实现 |
应用平台
语言
C (Sometimes Prevalent)
C++ (Sometimes Prevalent)
后果
范围 | 冲击 | 可能性 |
可利用性 | 技术冲击: DoS: 崩溃、推出或者重启: DoS: Resource Consumption (CPU) 缓冲区溢出通常会导致崩溃。其他导致可用性不足的攻击是可能的,包括将程序放入无限循环。 | |
完整性 | 技术冲击: 执行未获授权的代码或命令 缓冲区溢出通常可用于执行任意代码,这通常不在程序的安全策略的范围内。 | |
访问控制 | 技术冲击: 越过保护机制 当结果是任意代码执行时,这通常可以用来破坏任何其他安全服务。 |
示例
例1
在下面的示例中,使用strncpy方法将源字符串复制到dest字符串
(问题代码)
Example Language: C
...
char source[21] = "the character string";
char dest[12];
strncpy(dest, source, sizeof(source)-1);
...
但是,在对strncpy的调用中,在sizeof调用中使用源字符串来确定要复制的字符数。这将创建缓冲区溢出,因为源字符串的大小大于dest字符串。应在sizeof调用中使用dest字符串,以确保复制正确的字符数,如下所示。
(正确代码)
Example Language: C
...
char source[21] = "the character string";
char dest[12];
strncpy(dest, source, sizeof(dest)-1);
...
例2
在本例中,方法outputfilenametolog将文件名输出到日志文件。方法参数包括指向包含文件名的字符串的指针和字符串中字符数的整数。将文件名复制到一个缓冲区,其中缓冲区大小设置为日志文件输入的最大大小。然后,该方法调用另一个方法将缓冲区的内容保存到日志文件中。
(问题代码)
Example Language: C
#define LOG_INPUT_SIZE 40
// saves the file name to a log file
int outputFilenameToLog(char *filename, int length) {
int success;
// buffer with size set to maximum size for input to log file
char buf[LOG_INPUT_SIZE];
// copy filename to buffer
strncpy(buf, filename, length);
// save to log file
success = saveToLogFile(buf);
return success;
}
但是,在这种情况下,字符串复制方法strncpy错误地使用length方法参数来确定要复制的字符数,而不是使用本地字符串buf的大小。如果文件名指向的字符串中包含的字符数大于本地字符串允许的字符数,则可能导致缓冲区溢出。字符串复制方法应该在size of调用中使用buf字符串,以确保只复制buf数组大小以下的字符以避免缓冲区溢出,如下所示.
(正确代码)
Example Language: C
...
// copy filename to buffer
strncpy(buf, filename, sizeof(buf)-1);
...
应对措施
阶段: 架构与设计 使用抽象库来抽象危险的API。示例包括Viega的safe c字符串库(safestr)和Microsoft的strsafe.h库。这不是一个完整的解决方案,因为许多缓冲区溢出与字符串无关 |
阶段: 编译及链接 使用某些编译器或编译器扩展提供的自动缓冲区溢出检测机制。示例包括stackguard、propolice和Microsoft Visual Studio/GS标志。这不一定是一个完整的解决方案,因为这些基于金丝雀的机制只检测某些类型的溢出。此外,结果仍然是拒绝服务,因为典型的响应是退出应用程序。 |
阶段: 实现 在分配和管理应用程序内存时,程序员应该遵守以下规则:仔细检查您的缓冲区是否如您指定的那样大。当使用接受多个字节进行复制的函数(如strncpy())时,请注意,如果目标缓冲区大小等于源缓冲区大小,则它可能不会为空,从而终止字符串。如果在循环中调用此函数,请检查缓冲区边界,并确保不会有写入已分配空间的危险。在将所有输入字符串传递给copy和concatenation函数之前,请将其截断到合理的长度。 |
阶段: 操作 策略: 强化环境 使用随机排列程序可执行文件和库在内存中的位置的特性或扩展来运行或编译软件。因为这会使地址不可预测,所以可以防止攻击者可靠地跳到可利用的代码上。 示例包括地址空间布局随机化(ASLR)[Ref-58][Ref-60]和位置独立可执行文件(Pie)[Ref-64]。 有效性: 深度防御 注意:这不是一个完整的解决方案。然而,它迫使攻击者猜测一个未知值,该值会改变每个程序的执行。此外,攻击仍然可能导致拒绝服务,因为典型的响应是退出应用程序。 |
阶段: 操作 策略: 强化环境 使用提供数据执行保护(NX)或其等效功能的CPU和操作系统[REF-60] [REF-61]. 有效性: 深度防御 Note: 这不是一个完整的解决方案,因为缓冲区溢出可以用来覆盖附近的变量,以危险的方式修改软件的状态。此外,它不能用于需要自我修改代码的情况。最后,攻击仍然可能导致拒绝服务,因为典型的响应是退出应用程序。 |
阶段: 编译及链接; 操作 迄今为止,编译器或操作系统级别的大多数缓解技术只解决缓冲区溢出问题的一个子集,很少提供对该子集的完整保护。实施策略来增加攻击者的工作负载是一个很好的实践,例如让攻击者猜测一个未知值,该值会改变每个程序的执行。 |