常见缓冲区溢出示例是攻击者将其恶意代码注入损坏的内存。或者,他们可能只是利用缓冲区溢出和相邻内存损坏。
例如,当依赖外部数据的代码接收到“gets()”函数以读取堆栈缓冲区中的数据时,可能会导致简单的缓冲区溢出。系统无法限制函数读取的数据,这使得代码安全依赖于用户输入少于“BUFSIZE”字符。这个代码可能看起来像这样:
“...
char buf【BUFSIZE】;
get(buf);
…”
其他缓冲区溢出攻击依赖于用户输入来控制行为,然后通过内存函数“memcpy()”添加间接。这接受目标缓冲区、源缓冲区和要复制的字节数,使用“read()”命令填充输入缓冲区,并指定要复制的“memcpy()”的叮咬次数。
“...
char buf【64】, in【MAX_SIZE】;
printf("输入缓冲区内容:\n");
read(0, in, MAX_SIZE-1);
printf("要复制的字节数:\n");
scanf("%d", &bytes);
memcpy(buf、in、字节);
…”
缓冲区溢出的另一个场景是,数据属性未在本地验证。函数“lccopy()”采用字符串并返回堆分配的副本,其中大写字母更改为小写。该功能不执行边界检查,因为它预计“str”小于“BUFSIZE”。攻击者可以绕过代码或更改大小假设以溢出缓冲区。该代码的一个示例是:
“char *lccopy(const char *str) {
char buf【BUFSIZE】; char *p;
strcpy(buf、str);
对于 (p = buf; *p; p++) {
if (isupper(*p)) {
*p = tolower(*p);
}
}
返回 strdup(buf);
}”
缓冲区溢出的另一个例子是代码过于复杂,无法预测其行为。以下示例来自 libPNG 图像解码器,Mozilla 和 Internet Explorer 等浏览器均使用该解码器。该代码在检查可变长度大小时看起来很安全,但会执行“png_ptr->mode”检查,使其更加复杂。这可能会导致在“png_crc_read()”调用中检查盲长度,这表明最大限度地降低内存操作中代码的复杂性的重要性。
“如果(!(png_ptr->mode & PNG_HAVE_PLTE)){
/* 应该是错误,但我们可以应对 */
png_warning(png_ptr, "tRNS 前 PLTE 缺失");}
否则,如果(长度 > (png_uint_32)png_ptr->num_palette){
png_warning(png_ptr, "tRNS 区块长度不正确");
png_crc_finish(png_ptr,长度);
退货;
}
...
png_crc_read(png_ptr、readbuf、(png_size_t)length);”
