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