Jfrog安全研究人員在BusyBox Linux工具中發(fā)現(xiàn)了14個安全漏洞。
BusyBox是一個使用非常廣泛的軟件套件,,被稱為嵌入式Linux的瑞士軍刀,,融合了多個通用Unix工具和applet到一個可執(zhí)行文件中,可以運(yùn)行在可編程邏輯控制器(PLC),、人機(jī)接口(HMI)和遠(yuǎn)程終端單元(RTU)等Linux系統(tǒng)中,。
BusyBox 14個安全漏洞
Jfrog安全研究人員在BusyBox Linux工具中發(fā)現(xiàn)了14個安全漏洞,攻擊者利用這些漏洞可以引發(fā)DoS條件,、信息泄露和遠(yuǎn)程代碼執(zhí)行等,,相關(guān)漏洞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 是使用詞典壓縮的壓縮算法,可以使用范圍編碼器編碼輸出結(jié)果,。LZMA壓縮算法會編碼壓縮的流,,數(shù)據(jù)會被分成包,每個包是一個單獨(dú)的字節(jié)或者LZ77序列,。,。lzma格式包含一個13字節(jié)的頭,使用LZMA文件格式壓縮字符串a(chǎn)bc的示例如下:
CVE-2021-42374漏洞是LZMA中decompress_unlzma.c文件的unpack_lzma_stream函數(shù)中size檢查不充分導(dǎo)致的安全漏洞。
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;
…
為觸發(fā)該漏洞和控制泄露數(shù)據(jù)的開始偏移量,,需要確保滿足以下條件:
buffer_pos = 0
and
rep0 = offset + dict_size
因此,,pos就會等于(offset + dict_size)。在加上dict_size后,,就可以通過match_byte從期望的offset泄露內(nèi)容信息,。泄露的內(nèi)存包含可以用于下一步攻擊的指針。
引發(fā)越界訪問
漏洞該漏洞的基本思想是準(zhǔn)備一個LZMA編碼的流,,在解碼時,,滿足以上利用條件,并且pos等于一個負(fù)數(shù)(-offset),。這樣的話,,解碼的流就會含有泄露的內(nèi)存,可以寫入輸出流中,。
為了滿足buffer_pos=0這第一個條件,需要確保當(dāng)前解碼緩存流清空后馬上能運(yùn)行(state >= LZMA_NUM_LIT_STATES),,這樣的話緩存指針位置就等于0,。可以通過當(dāng)前匹配的最后一個循環(huán)來實(shí)現(xiàn):
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變量使用。
為實(shí)現(xiàn)OOB條件,,需要寫一些字節(jié),,然后使用匹配來填充緩存header.dict_size,,修改rep0為目標(biāo)值。因此,,pos會等于(-offset),,就可以從offset泄露字節(jié)。
從越界內(nèi)存泄露信息
在讀取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),;
}
如果相關(guān)位與泄露的字節(jié)match_byte匹配,就會進(jìn)入從prob + 0x100 + bit + mi讀取信息的循環(huán),,如果位不匹配,就會從prob + mi讀取,。最后,泄露的位會清空為解壓的緩存,。
武器化ZIP文件
雖然該漏洞是在LZMA壓縮算法中,,但是zip文件格式也是支持LZMA壓縮算法的,。而且從攻擊者的角度來看,zip更適合攻擊,。因此,,研究人員創(chuàng)建了一個PoC腳本來生成武器化的使用LZMA壓縮的zip文件: