zoukankan      html  css  js  c++  java
  • Java安全之挖掘回显链

    Java安全之挖掘回显链

    0x00 前言

    前文中叙述反序列化回显只是为了拿到RequestResponse对象。在这里说的的回显链其实就是通过一连串反射代码获取到该Request对象。

    在此之前想吹爆一个项目,Java Object Searcher项目地址

    0x01 回显链挖掘

    借助Java Object Searche工具根据工具说明文档,在tomcat中下断点,然后在IDEA的Evaluate中执行索引语句。

    TargetObject = {org.apache.tomcat.util.threads.TaskThread} 
      ---> group = {java.lang.ThreadGroup} 
       ---> threads = {class [Ljava.lang.Thread;} 
        ---> [14] = {java.lang.Thread} 
         ---> target = {org.apache.tomcat.util.net.NioEndpoint$Poller} 
          ---> this$0 = {org.apache.tomcat.util.net.NioEndpoint} 
             ---> handler = {org.apache.coyote.AbstractProtocol$ConnectionHandler} 
              ---> global = {org.apache.coyote.RequestGroupInfo}
    

    根据得出结果在Evaluate中进行查看

    获取group

    编写代码获取该对象

    Field group = Class.forName("org.apache.tomcat.util.threads.TaskThread").getDeclaredField("group");
                group.setAccessible(true);
                ThreadGroup threadGroup = (ThreadGroup) group.get(thread);
    

    获取测试错误了,其原因是因为org.apache.tomcat.util.threads.TaskThread中并没有group变量,该类继承了Thread类, 该变量在Thread类中。

     Field group = Class.forName("java.lang.Thread").getDeclaredField("group");
                group.setAccessible(true);
                ThreadGroup threadGroup = (ThreadGroup) group.get(thread);
    

    获取成功。

    获取thread

    ThreadGroup threadGroup = (ThreadGroup) group.get(thread);
    Field threads = Class.forName("java.lang.ThreadGroup").getDeclaredField("threads");
    threads.setAccessible(true);
    Thread[] thread1 = (Thread[])threads.get(threadGroup);
    

    获取target

    发现thread并不是每一次都是14,需要这里采用获取线程名称进行定位对于的thread。

    if (thread2.getName().contains("http-nio")&&thread2.getName().contains("ClientPoller-1"))
    

    最终代码

    package com;
    
    import org.apache.coyote.RequestGroupInfo;
    import org.apache.coyote.RequestInfo;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.lang.reflect.Field;
    //TargetObject = {org.apache.tomcat.util.threads.TaskThread}
    //  ---> group = {java.lang.ThreadGroup}
    //   ---> threads = {class [Ljava.lang.Thread;}
    //    ---> [14] = {java.lang.Thread}
    //     ---> target = {org.apache.tomcat.util.net.NioEndpoint$Poller}
    //      ---> this$0 = {org.apache.tomcat.util.net.NioEndpoint}
    //         ---> handler = {org.apache.coyote.AbstractProtocol$ConnectionHandler}
    //          ---> global = {org.apache.coyote.RequestGroupInfo}
    @WebServlet("/test2Servlet")
    public class test2Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            Thread thread = Thread.currentThread();
            try {
                Class<?> aClass = Class.forName("java.lang.Thread");
                Field group = aClass.getDeclaredField("group");
                group.setAccessible(true);
                ThreadGroup threadGroup = (ThreadGroup) group.get(thread);
                Field threads = Class.forName("java.lang.ThreadGroup").getDeclaredField("threads");
                threads.setAccessible(true);
                Thread[] thread1 = (Thread[])threads.get(threadGroup);
                for (Thread thread2 : thread1) {
                    if (thread2.getName().contains("http-nio")&&thread2.getName().contains("ClientPoller-1")){
                        Field target = Class.forName("java.lang.Thread").getDeclaredField("target");
                        target.setAccessible(true);
                        Object o = target.get(thread2);
                        Field this$0 = o.getClass().getDeclaredField("this$0");
                        this$0.setAccessible(true);
                        Object o1 = this$0.get(o);
                        Field handler = Class.forName("org.apache.tomcat.util.net.AbstractEndpoint").getDeclaredField("handler");
                        handler.setAccessible(true);
                        Object handler1 = handler.get(o1);
    
                        Field global = handler1.getClass().getDeclaredField("global");
                        global.setAccessible(true);
                        RequestGroupInfo requestGroupInfo = (RequestGroupInfo)global.get(handler1);
    
                        Field processors = Class.forName("org.apache.coyote.RequestGroupInfo").getDeclaredField("processors");
                        processors.setAccessible(true);
                        java.util.List<RequestInfo> RequestInfo_list = (java.util.List<RequestInfo>) processors.get(requestGroupInfo);
                        Field req = Class.forName("org.apache.coyote.RequestInfo").getDeclaredField("req");
                        req.setAccessible(true);
                        for (RequestInfo requestInfo : RequestInfo_list) {
                            org.apache.coyote.Request request1 = (org.apache.coyote.Request) req.get(requestInfo);
                            org.apache.catalina.connector.Request request2 = ( org.apache.catalina.connector.Request)request1.getNote(1);
                            org.apache.catalina.connector.Response response2 = request2.getResponse();
                            response2.getWriter().write("Success!!!");
                        }
    
    
    
                    }
                }
    //            for (Thread thread2 : thread1) {
    //                System.out.println(thread2.getName());
    //            }
    
    //            if ()
    //            thread1[14]
    //            Field target = Class.forName("java.lang.Thread").getDeclaredField("target");
    //            target.setAccessible(true);
    //            Runnable runnable = (Runnable)target.get(thread1[13]);
    
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    
    

    Reference

    半自动化挖掘request实现多种中间件回显

    0x02 结尾

    其他中间件也是同理,设置筛选条件。然后定位request进行一步步的反射获取即可。再次吹爆该项目。目前只会简单使用,其他用法待研究。

    WX:TG9yaTI1NDgyNjYxNDU= 欢迎各位师傅来一起做技术交流
  • 相关阅读:
    ERROR Function not available to this responsibility.Change responsibilities or contact your System Administrator.
    After Upgrade To Release 12.1.3 Users Receive "Function Not Available To This Responsibility" Error While Selecting Sub Menus Under Diagnostics (Doc ID 1200743.1)
    产品设计中先熟练使用铅笔 不要依赖Axure
    12.1.2: How to Modify and Enable The Configurable Home Page Delivered Via 12.1.2 (Doc ID 1061482.1)
    Reverting back to the R12.1.1 and R12.1.3 Homepage Layout
    常见Linux版本
    网口扫盲二:Mac与Phy组成原理的简单分析
    VMware 8安装苹果操作系统Mac OS X 10.7 Lion正式版
    VMware8安装MacOS 10.8
    回顾苹果操作系统Mac OS的发展历史
  • 原文地址:https://www.cnblogs.com/nice0e3/p/14897670.html
Copyright © 2011-2022 走看看