BusyBox 14个安全漏洞
2021-11-12
来源:嘶吼专业版
Jfrog安全研究人员在BusyBox Linux工具中发现了14个安全漏洞。
BusyBox是一个使用非常广泛的软件套件,被称为嵌入式Linux的瑞士军刀,融合了多个通用Unix工具和applet到一个可执行文件中,可以运行在可编程逻辑控制器(PLC)、人机接口(HMI)和远程终端单元(RTU)等Linux系统中。
BusyBox 14个安全漏洞
Jfrog安全研究人员在BusyBox Linux工具中发现了14个安全漏洞,攻击者利用这些漏洞可以引发DoS条件、信息泄露和远程代码执行等,相关漏洞CVE编号为:
?CVE-2021-42373
?CVE-2021-42374
?CVE-2021-42375
?CVE-2021-42376
?CVE-2021-42377
?CVE-2021-42378
?CVE-2021-42379
?CVE-2021-42380
?CVE-2021-42381
?CVE-2021-42382
?CVE-2021-42383
?CVE-2021-42384
?CVE-2021-42385
?CVE-2021-42386
CVE-2021-42374漏洞
LZMA 是使用词典压缩的压缩算法,可以使用范围编码器编码输出结果。LZMA压缩算法会编码压缩的流,数据会被分成包,每个包是一个单独的字节或者LZ77序列。。lzma格式包含一个13字节的头,使用LZMA文件格式压缩字符串abc的示例如下:
CVE-2021-42374漏洞是LZMA中decompress_unlzma.c文件的unpack_lzma_stream函数中size检查不充分导致的安全漏洞。
while (global_pos + buffer_pos < header.dst_size) {
…
uint32_t pos;
pos = buffer_pos - rep0;
if ((int32_t)pos < 0) // Insufficient check
pos += header.dict_size; // dict_size is user-controlled
match_byte = buffer[pos]; // Read OOB may occur here
do {
int bit;
match_byte 《= 1;
bit = match_byte & 0x100;
…
为触发该漏洞和控制泄露数据的开始偏移量,需要确保满足以下条件:
buffer_pos = 0
and
rep0 = offset + dict_size
因此,pos就会等于(offset + dict_size)。在加上dict_size后,就可以通过match_byte从期望的offset泄露内容信息。泄露的内存包含可以用于下一步攻击的指针。
引发越界访问
漏洞该漏洞的基本思想是准备一个LZMA编码的流,在解码时,满足以上利用条件,并且pos等于一个负数(-offset)。这样的话,解码的流就会含有泄露的内存,可以写入输出流中。
为了满足buffer_pos=0这第一个条件,需要确保当前解码缓存流清空后马上能运行(state >= LZMA_NUM_LIT_STATES),这样的话缓存指针位置就等于0。可以通过当前匹配的最后一个循环来实现:
buffer[buffer_pos++] = previous_byte;
if (buffer_pos == header.dict_size) {
buffer_pos = 0;
global_pos += header.dict_size;
if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size)
goto bad;
IF_DESKTOP(total_written += header.dict_size;)
}
len--;
} while (len != 0 && buffer_pos < header.dst_size); // match_last_iteration will end with buffer_pos = 0;
第二个条件更难满足,基本思想是在LZMA位流中编码一个特殊的长度,解码后可以被rep0变量使用。
为实现OOB条件,需要写一些字节,然后使用匹配来填充缓存header.dict_size,修改rep0为目标值。因此,pos会等于(-offset),就可以从offset泄露字节。
从越界内存泄露信息
在读取match_byte后,就可以得到如下信息:
do {
int bit;
match_byte 《= 1;
bit = match_byte & 0x100;
bit ^= (rc_get_bit(rc, prob + 0x100 + bit + mi, &mi) 《 8); /* 0x100 or 0 */
if (bit)
break;
} while (mi < 0x100);
while (mi < 0x100) {
rc_get_bit(rc, prob + mi, &mi);
}
如果相关位与泄露的字节match_byte匹配,就会进入从prob + 0x100 + bit + mi读取信息的循环,如果位不匹配,就会从prob + mi读取。最后,泄露的位会清空为解压的缓存。
武器化ZIP文件
虽然该漏洞是在LZMA压缩算法中,但是zip文件格式也是支持LZMA压缩算法的。而且从攻击者的角度来看,zip更适合攻击。因此,研究人员创建了一个PoC脚本来生成武器化的使用LZMA压缩的zip文件: