☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

避免缓冲区溢出

13.1 ID_bufferOverflow
目录 › next › previous

缓冲区溢出是一种高度危险的安全漏洞,也是很多安全问题的根源。

“缓冲区(buffer)”的本意是指内存等高速设备上的区域,程序在这种区域内接收或处理数据,之后再一并输出到网络或磁盘等低速环境,起到提高效率的作用,故称缓冲区。连续的内存区域均可称为缓冲区,如数组等。对缓冲区的越界读写称为“缓冲区溢出(buffer overflow)”。

缓冲区之外可能是其他对象的数据,也可能是函数返回地址、资源分配信息等重要数据,缓冲区溢出往往会造成严重后果,如:

  • 导致程序崩溃,或产生其他形式的拒绝服务漏洞
  • 使攻击者能够篡改程序的行为,窃取或损坏敏感信息
  • 为恶意代码的执行提供可乘之机
  • 助力攻击者获取非法权限,威胁系统安全

示例:

int buffer[10];
for (int i = 0; i <= 10; i++) {  // Off-by-one error
    buffer[i] = 0;               // Overflow when ‘i’ is 10
}

例中循环变量 i 等于 10 时,buffer[i] = 0 便造成了缓冲区溢出,此为常见笔误,应将循环条件改为 i != 10。

又如:

int auth() {
    char pswd[8];
    gets(pswd);                    // May overflow
    return !strcmp(pswd, "abc");
}

例中 auth 函数验证用户输入的密码,密码存于数组 pswd 中,gets 函数接收用户输入,但不检查输入长度,一旦输入超过 8 个字符就会造成缓冲区溢出。由于 gets 函数过于危险,已被 C11 标准弃用,但在自定义的缓冲区操作中,仍然需要对这种问题保持高度警惕。

如果按下列方式调用 auth 函数:

int main() {
    int ret = auth();
    if (!ret) {
        return -1;   // May be invalid under attack
    }
    show_secret();
}

在进程的实际内存布局中,pswd 数组之后可以是 auth 函数的返回地址,如果攻击者利用缓冲区溢出将其篡改,便可以扰乱程序的执行,甚至可以绕过用于判断的 if 语句,直接执行用于显示敏感信息的 show_secret 函数,造成敏感信息泄露。

关于避免缓冲区溢出的方法和防御措施,可参见本规则相关规则的进一步介绍。

相关

ID_insufficientBuffer ID_improperNullTermination ID_zeroLengthAllocation ID_unsafeStringFunction ID_dangerousFunction ID_missingHardening ID_arrayIndexOverflow

参考

CWE-119 CWE-125 CWE-787 CWE-788
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.