混合進制IP地址解析漏洞,Go,Rust語言net類庫受影響
本周在DEF CON大會上,由多名安全研究人員披露十進制和八進制混合IP地址解析漏洞,多種語言受影響,包括Go和Rust的官方類庫net。以及Python的標準庫ipaddress。
概述
Go和 Rust語言中常用的net庫,受到混合格式IP 地址驗證漏洞的影響。該漏洞源于庫中對IP地址處理時候將八進制-十進制)格式混合格式的八進制的數據當作十進制有關。
所有使用這次基礎庫的應用程序可能會受到不確定的服務器端請求偽造(SSRF) 和遠程文件包含(RFI) 漏洞的攻擊。
因為該基礎庫被廣使用,所以大量的Go,Rust網絡應用都受到影響。
另外,Python 標準庫ipaddress也受漏洞影響。
漏洞原理
漏洞CVE編號為CVE-2021-29922(Rust庫)和 CVE-2021-29923(Golang庫),主要在其同名類庫net處理混合格式的IP地址,或者更具體地說,當十進制IPv4 地址包含數據以0開始時。
眾所周知,IP地址可以用多種格式表示,包括十六進制和整數,盡管最常見的IPv4地址以十進制格式表示。
比如8.8.8.8
該地址可以用八進制格式表示為 0010.0010.0010.0010。
我們日常最常用的一個本地IP地址(回環地址,localhost)為127.0.0.1。 假如對其第一部分IP地址添加一個0,則0127.0.0.1 會被解析為啥呢?
我們在瀏覽器中輸入這個地址。在火狐瀏覽器的地址欄中輸入0127.0.0.1,瀏覽器將其自動轉化為八進制格式 。
其他瀏覽器也是如此,比如谷歌Chrome:
根據IETF草案,如果前綴為“0”,則 IPv4 地址的部分可以解釋為八進制。但是,在net庫中,任何前置零的地址都被簡單地剝離和丟棄。
在Golang和Rust的net模塊中將IPv4地址的八位字節都被簡單視為十進制。 因此,如果開發人員使用net來驗證IP地址是否屬于某個范圍(例如,根據訪問控制列表 (ACL) 解析IP列表),對于基于八進制的IPv4地址表示,結果可能會完全錯誤。
這樣可能會導致應用程序中出現不確定的服務器端請求偽造 (SSRF)和遠程文件包含(RFI)漏洞。
漏洞影響
由于net庫在Golang和Rust語言中均為核心庫,被大量應用所依賴,通過在Github上簡單搜索,僅golang中依賴該庫的代碼文件超超過49w。
而且Go和Rust不是唯一受該漏洞影響的語言,還有Python語言的ipaddress 庫 (CVE-2021-29921)、 netmask庫 (CVE-2021-28918、CVE-2021-29418) 和等類似的庫也受影響。
該系列漏洞大多都被評為有高或嚴重的嚴重性。
漏洞解決
目前 Golang 的 net 模塊將補丁將在Golang 1.17 版中發布。
對于 Rust net里,也已經有一個修復程序已經合并:
請使用這些類庫的同學,關注官方漏洞發布及時更新版本。