当前位置:首页 > 嵌入式 > 嵌入式分享
[导读]C语言因直接操作内存和高效性被广泛应用于系统级开发,但其缺乏边界检查的机制导致整数溢出成为安全漏洞的高发区。从符号转换漏洞到无符号整数(unsigned)绕过安全检查,攻击者通过精心构造的输入触发溢出,进而实现缓冲区溢出、权限提升甚至远程代码执行。本文结合典型漏洞案例,深入剖析整数溢出的攻击原理与防御策略。

C语言因直接操作内存和高效性被广泛应用于系统级开发,但其缺乏边界检查的机制导致整数溢出成为安全漏洞的高发区。从符号转换漏洞到无符号整数(unsigned)绕过安全检查,攻击者通过精心构造的输入触发溢出,进而实现缓冲区溢出、权限提升甚至远程代码执行。本文结合典型漏洞案例,深入剖析整数溢出的攻击原理与防御策略。

一、符号转换漏洞:从类型不匹配到任意内存写入

符号转换漏洞通常发生在有符号整数(signed)与无符号整数(unsigned)混合使用时。C语言在类型转换时遵循“算术转换规则”,即当有符号数与无符号数参与运算时,有符号数会被隐式转换为无符号数。若未对输入范围进行严格校验,攻击者可利用此特性绕过安全检查。

典型案例:OpenSSH远程缓冲区溢出漏洞

在OpenSSH的auth2-chall.c文件中,input_userauth_info_response()函数存在整数溢出漏洞:

nresp = packet_get_int(); // 读取网络数据包中的整数值

if (nresp > 0) { // 检查nresp是否为正数

response = xmalloc(nresp * sizeof(char *)); // 分配内存

for (i = 0; i < nresp; i++) {

response[i] = packet_get_string(NULL); // 读取字符串

}

}

攻击原理:

符号转换绕过检查:packet_get_int()返回的nresp为有符号整数,但xmalloc的参数类型为size_t(无符号整数)。若攻击者发送负数(如-1),在比较nresp > 0时会被视为无符号数0xFFFFFFFF(32位系统),从而绕过检查。

整数溢出导致堆溢出:nresp * sizeof(char *)的计算中,-1的无符号转换值为0xFFFFFFFF,乘以4后发生溢出(结果为0x00000004),导致xmalloc仅分配4字节内存。后续循环写入大量数据时,覆盖堆内存中的函数指针或元数据,最终实现任意代码执行。

防御策略:

严格类型匹配:避免有符号与无符号数混合运算,统一使用size_t处理内存相关操作。

输入范围校验:在分配内存前,显式检查nresp是否超过合理阈值(如nresp < MAX_ALLOWED_SIZE)。

使用安全函数:改用带边界检查的内存分配函数(如calloc替代malloc)。

二、unsigned绕过安全检查:从回绕到缓冲区溢出

无符号整数溢出在C语言中是“定义明确的行为”(undefined behavior的例外),即发生溢出时会对类型位宽取模。攻击者利用此特性构造输入,使安全检查失效并触发溢出。

典型案例:字符串拼接缓冲区溢出

以下代码片段试图将两个用户输入的字符串拼接至固定大小的缓冲区:

void concat_strings(char *str1, char *str2) {

size_t len1 = strlen(str1);

size_t len2 = strlen(str2);

char buf[256];

if (len1 + len2 < sizeof(buf)) { // 检查总长度是否超过缓冲区

memcpy(buf, str1, len1);

memcpy(buf + len1, str2, len2);

buf[len1 + len2] = '\0';

}

}

攻击原理:

无符号整数回绕绕过检查:若len1和len2均为较大值(如0x100和0xFFFFFF00),len1 + len2会发生溢出(结果为0x100 + 0xFFFFFF00 = 0x00000000),导致条件len1 + len2 < sizeof(buf)成立。

缓冲区溢出:实际拼接时,memcpy会写入超过buf大小的数据,覆盖栈上的返回地址或函数指针,实现控制流劫持。

防御策略:

显式溢出检查:在计算长度前,检查len1或len2是否接近SIZE_MAX - sizeof(buf)。

使用安全函数:改用snprintf或strlcpy等带长度限制的字符串操作函数。

静态分析工具:通过Coverity、Clang Static Analyzer等工具检测潜在溢出风险。

三、整数溢出攻击的衍生场景

1. 循环条件绕过

以下代码试图限制循环次数以避免缓冲区溢出:

void read_data(int fd, char *buf, size_t max_len) {

int len = 0;

while (len < max_len) { // 检查已读取长度

len += read(fd, buf + len, max_len - len); // 读取数据

}

}

攻击原理:

若max_len为INT_MAX,且read返回负数(如-1),len会因符号转换变为0xFFFFFFFF,导致循环条件len < max_len恒成立,最终触发无限循环或缓冲区溢出。

防御策略:

检查返回值:确保read的返回值非负,且len不会超过max_len。

使用无符号类型:将len声明为size_t以避免符号问题。

2. 数组越界访问

以下代码通过用户输入的索引访问数组:

int get_array_element(int *arr, int index, size_t size) {

if (index >= 0 && index < size) { // 检查索引范围

return arr[index];

}

return -1;

}

攻击原理:

若size为INT_MAX,攻击者传入index = -1,在比较index < size时,-1会被转换为无符号数0xFFFFFFFF,导致条件成立并访问非法内存。

防御策略:

统一使用无符号索引:将index声明为size_t,并确保size为合理值。

边界检查:在访问数组前,显式检查index是否小于size。

四、防御整数溢出的通用策略

编译器选项:启用-fsanitize=undefined等编译选项,在运行时检测溢出。

静态分析:通过SonarQube、Fortify等工具扫描代码中的潜在溢出风险。

安全编码规范:

避免混合使用有符号与无符号整数。

对用户输入进行严格校验。

使用安全的数学库(如SafeInt、Arbitrary Precision Arithmetic)。

总结

C语言整数溢出的攻击面广泛,涵盖符号转换漏洞、无符号整数回绕、循环条件绕过等多种场景。攻击者通过精心构造输入,利用C语言的隐式类型转换和未定义行为,绕过安全检查并触发缓冲区溢出或控制流劫持。开发者需通过严格的输入校验、类型安全编程和安全工具辅助,构建多层次的防御体系,从根本上降低整数溢出漏洞的风险。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭