DHCP客戶端腳本代碼執行漏洞分析
概述
2015年5月,安全研究人員在Red Hat Enterprise Linux多個版本DHCP客戶端軟體包的NetworkManager集成腳本中發現了命令注入漏洞(CVE-2018-1111)。攻擊者藉助該漏洞,可以通過惡意DHCP伺服器或本地網路上的惡意構造DHCP響應來實現攻擊。該攻擊成功後,攻擊者就可以在使用NetworkManager且已經配置DHCP的系統上以root許可權執行任意命令。目前,該漏洞已經在新版本中修復。
這一漏洞針對使用Red Hat Enterprise Linux 6或7版本的用戶造成嚴重威脅,相關用戶應該及時打上補丁。
本文主要對這一漏洞展開詳細分析,幫助用戶進一步了解該漏洞的潛在風險,並提供針對此漏洞的安全防護建議。
漏洞詳情
NetworkManager是一個Linux程序,用於在DHCP網路模式情況下管理系統網路。具體而言,NetworkManager會啟動dhclient以發送DHCP請求,如下圖所示。
在上述示例中,大家可能會注意到另一個配置文件(/var/lib/NetworkManager/dhclient-eth0.conf)從NetworkManager傳遞給了dhclient。正如我們在下面示例所看到的,默認情況下,dhclient會被配置成請求多個DHCP數據包選項,其中也包括WPAD。
當dhclient發送DHCP伺服器的原始請求時,請求中就會包含這一WPAD(代碼252)選項,如下所示:
由於CVE-2018-1111漏洞,攻擊者可以構造一個格式錯誤的響應,並將其作為對這一DHCP請求的響應。舉例來說,攻擊者可能會使用以下數據進行響應,如下圖所示:
xxx"&touch /tmp/test #
收到此響應後,默認的11-dhclient腳本最終會將這一數據傳遞給eval()語句,這將導致主機會通過touch命令創建/tmp/test。
技術分析
從被攻擊系統收到特殊構造的DHCP響應後到創建/tmp/test之前的這段時間裡,還會發生許多其他事情。首先,dhclient調用client_option_envadd()函數,將值保存到變數中,這一過程我們通過閱讀源代碼可以發現。在第3154行,client_envadd()函數負責執行這一過程。
在上面的源代碼中,我們還可以看到,在設置變數之前會調用pretty_print_option()函數,這一函數通過在特殊符號之前添加「」來實現過濾。舉例來說:
『字元將變為『
&字元將變為&
在我們的示例中,原本要發送的數據如下:
xxx』&touch /tmp/test #
但經過轉義後,就變成了:
xxx』&touch /tmp/test #
如下圖所示,該函數會對接收到的數據進行轉義:
在完成轉義後,它會繼續調用check_option_values()函數,然後再將值存儲到變數中。該函數的作用是檢查某些特定的選項中是否包含特殊字元。目前我們已經發現,會對HOST_NAME或DOMAIN_NAME進行檢查,如下圖所示。
檢查源代碼中,是否包含特定選項:
當提供NETBIOS_SCOPE選項時,下述代碼將被執行:
從代碼中可以看出,WPAD選項並不會被檢查。至此我們知道,由於該選項沒有經過嚴格的檢查,我們有可能藉助修改DHCP響應中這一選項的數據來實現攻擊。
接下來,dhclient通過設置參數的方式來啟動/usr/libexec/nm-dhcp-helper進程,然後將這些變數保存到dbus服務中。
另一個名為nm-dispatcher的進程會由NetworkManager啟動,然後從dbus服務中讀取變數。它會將WPAD DHCP選項的值保存到環境變數DHCP4_WPAD中,然後繼續啟動位於/etc/NetworkManager/dispatcher.d/的11-dhclient腳本。
下面,讓我們來關注一下11-dhclient腳本,其中包含如下內容:
我們來深入分析一下這個腳本。
在eval()語句中,它以「declare」命令開始。這個「declare」命令會輸出系統上所有環境變數。大家可能更熟悉「env」這個變數,其實它與「declare」的運行方式類似。儘管二者在輸出上比較相似,但還是存在著一些關鍵差異,如下圖所示。
如上所見,「declare」命令將會執行另外兩項操作:
1、如果變數中包含特殊字元(例如空格或單引號),會在變數的兩側添加』符號;
2、將變數中的』字元轉換為』』』(由原來的1個字元變成4個字元)。
由於變數值為xxx』&touch /tmp/test #,因此「declare」的輸出將會變為『xxx』」&touch /tmp/test #』。
運行「declare」命令後,腳本將只會搜索以「DHCP4_」開頭的環境變數。接下來就會執行「read」命令。如果未提供此參數,這一命令將會讀取轉義字元。具體而言,』就將變為』。
回到我們在DHCP響應的WPAD選項中提供的數據,『xxx』」&touch /tmp/test #』將會變為『xxx」』&touch /tmp/test #』。由於使用了不含任何參數的「read」命令,原本應該轉義的字元現在未被轉義。
其它的命令會將解析的環境變數數據設置為一系列變數,但最後一個命令中包含可能被利用的代碼。存在問題的代碼如下:
echo "export $optname=$optvalue"
假如使用我們示例中的字元串,將會在系統上執行以下代碼:
eval "$(echo "export new_wpad="xxx"""&touch /tmp/test #" ")"
如下圖,我們在命令行中進行演示:
由於引用沒有被轉義,並且其後面跟著一個&符號,所以我們就可以向這個eval()語句附加一個額外的命令。在我們的示例中,我們添加了一個touch /tmp/test的命令,這樣一來就可以使其在/tmp/目錄下創建一個名為test的空文件。
如果引號和&符號被轉義,那麼我們的嘗試就會失敗,如下所示:
請注意,其他字元也可能用於執行此類攻擊,例如|和;。
漏洞修復方式
針對這一漏洞,修復方式非常簡單,只需要在「read」命令中添加「-r」選項就可以保證各類字元都被轉義。我們看到,補丁中的修復方式如下:
根據官方文檔中「read」命令的說明,「-r」選項可以防止命令將反斜杠作為轉義字元讀取。換而言之,使用「-r」後將會保留數據中的所有反斜杠。這樣一來,也就能有效的抵禦命令注入攻擊。
漏洞披露狀態
在漏洞被發現後不久,2018年5月16日,PoC已經通過Twitter被公開:
此外,在GitHub也發布了一個能夠輕鬆測試該漏洞是否存在的工具:
https://github.com/knqyf263/CVE-2018-1111
總結
考慮到NetworkManager已經被廣泛使用,並且這一漏洞非常容易被攻擊者利用,因此我們應該將其視為一個嚴重漏洞。目前,惡意攻擊者仍然在利用這一漏洞實現攻擊。因此,建議廣大用戶及時通過補丁的方式實現修復。


※知名比特幣網站bustabit價值$12,000的點擊劫持、XSS以及拒絕服務漏洞詳情揭秘
※Thermanator攻擊:通過讀取鍵盤上的熱殘留竊取密碼
TAG:嘶吼RoarTalk |