研究人員發(fā)現(xiàn)xiph.org基金會(huì)支持的開源流媒體服務(wù)器Icecast的漏洞。攻擊者可以偽造HTTP header來覆寫服務(wù)器的棧內(nèi)容,導(dǎo)致遠(yuǎn)程代碼執(zhí)行漏洞。因?yàn)镮cecast常用于網(wǎng)絡(luò)電臺(tái),所以攻擊者利用該漏洞可以完全控制網(wǎng)絡(luò)電臺(tái)。該漏洞的CVE編號(hào)為CVE-2018-18820。
版本號(hào)為2.4.0到2.4.3的Icecast服務(wù)器和使用URL認(rèn)證的Icecast服務(wù)器受該漏洞的影響。研究人員建議盡快升級(jí)到v 2.4.4。
Snprintf
我們都知道sprintf是不安全的,因?yàn)椴惶峁⿲?duì)緩沖區(qū)溢出的保護(hù)。許多文檔中都說Snprintf是更安全版本的sprintf,但如果緩沖區(qū)太小,輸出就會(huì)變短。但我們不清楚的是如果輸出縮短,snprintf就不會(huì)返回寫的字節(jié)。事實(shí)上,如果輸出緩存足夠大,那么返回的是已經(jīng)寫入的字節(jié)數(shù)。如果提供一個(gè)大于緩沖區(qū)大小的size參數(shù),根本無法應(yīng)對(duì)緩沖區(qū)溢出。
下面是來自Icecast的有漏洞的代碼:
在來自用戶請(qǐng)求的HTTP header之上循環(huán),并復(fù)制到緩沖區(qū),構(gòu)建一個(gè)發(fā)送到認(rèn)證服務(wù)器的POST請(qǐng)求主體:
post_offset += snprintf(post + post_offset,
sizeof(post) - post_offset,
"&%s%s=%s",
url->prefix_headers ? url->prefix_headers : "",
cur_header, header_valesc);
下面是代碼的簡(jiǎn)化版:
post_offset += snprintf(post + post_offset,
sizeof(post) - post_offset,
"%s",
cur_header);
如果sizeof(post)的大小是10,那么就寫入了8字節(jié)。那么如果下一個(gè)復(fù)制的header是baz會(huì)怎么樣呢?
輸出會(huì)變短,但post_offset在緩存的尾部會(huì)遞增:
下面設(shè)想另一個(gè)復(fù)制的header內(nèi)容為“AAAAA…”。 到snprintf的size參數(shù)是sizeof(post) – post_offset,這會(huì)下溢變成一個(gè)非常大的數(shù)。結(jié)果就是之后對(duì)snprintf的調(diào)用會(huì)有效地寫入盡可能多的數(shù)據(jù)。數(shù)據(jù)會(huì)被寫入post + post_offset,可能會(huì)超出post緩存的范圍,那么就會(huì)覆蓋棧中的其他內(nèi)容。
也就是說我們可以發(fā)送一個(gè)隨后會(huì)被縮短的長(zhǎng)HTTP header,但是長(zhǎng)度可以讓我們定位棧中的任何位置post_offset。然后,可以發(fā)送第二個(gè)HTTP header,其內(nèi)容會(huì)被寫入定位的位置。
對(duì)攻擊者來說,比較難的一點(diǎn)是header在復(fù)制到snprintf之前會(huì)進(jìn)行處理,所以限制在可以寫入到棧中的數(shù)據(jù)。研究人員的POC漏洞利用可以引發(fā)服務(wù)器進(jìn)程段錯(cuò)誤(segfault),類似DoS攻擊。但研究人員認(rèn)為攻擊者可以對(duì)該攻擊進(jìn)行升級(jí)來獲得完全遠(yuǎn)程代碼執(zhí)行。
修復(fù)
Xiph很快對(duì)漏洞進(jìn)行了回應(yīng),并發(fā)布了補(bǔ)丁。補(bǔ)丁非常簡(jiǎn)單,檢查了snprintf的返回值,如果使post_offset指向緩沖區(qū)的尾部,就記錄錯(cuò)誤并退出循環(huán)。
|