Java Filter 型内存马调试系列 (三)——一种Tomcat全版本获取StandardContext的新方法(全网首次发布,精调无错版)_standardcontext获取(1)

    Thread[] threads = (Thread[]) this.getField(Thread.currentThread().getThreadGroup(), "threads");
    //log2.info(String.valueOf(threads.length));  //32

    for (Thread thread : threads) {
        // 过滤掉不相关的线程
        if (thread == null || thread.getName().contains("exec")) {
            continue;
        }

        if ((thread.getName().contains("Acceptor") || thread.getName().contains("Poller")) && (thread.getName().contains("http"))) {  // thread  http-nio-8080-Acceptor
            log2.info("thread: " + thread.getName());
            Object target = this.getField(thread, "target"); //target org.apache.tomcat.util.net.Acceptor@6698f6ae
            log2.info("target: " + target.toString());
            HashMap children;
            Object jioEndPoint = null;

            // Poller 线程
            if (thread.getName().contains("Poller")) {
                try {
                    jioEndPoint = getField(target, "this$0");  //等价于  thread.getClass().getDeclaredField("this$0");  // Poller 线程
                    log2.info("jioEndPoint: " + jioEndPoint.toString());
                } catch (Exception e) {
                    //log2.info(e.toString());  //java.lang.NullPointerException
                }
            } else
                // Acceptor 线程
                if (thread.getName().contains("Acceptor")) {
                    //if (jioEndPoint == null) {
                    try {
                        jioEndPoint = getField(target, "endpoint");  // org.apache.tomcat.util.net.NioEndpoint@4eaaa9
                        log2.info("jioEndPoint: " + jioEndPoint.toString());
                    } catch (Exception e) {
                        log2.warning("异常,准备return " + e.toString());
                        return;
                    }
                }
            Object service = getField(getField(getField(getField(getField(jioEndPoint, "handler"), "proto"), "adapter"), "connector"), "service");
            log2.info("service: " + service.toString());   // StandardService[Catalina]
            StandardEngine engine = null;
            try {
                // tomcat 6,7,8
                engine = (StandardEngine) getField(service, "container");
                log2.info("engine: " + engine.toString());
            } catch (Exception e) {
                //log2.info(e.toString());  //java.lang.NullPointerException
            }
            if (engine == null) {
                // tomcat 9
                engine = (StandardEngine) getField(service, "engine");  // StandardEngine[Catalina]
                log2.info("engine: " + engine.toString());
            }

            children = (HashMap) getField(engine, "children");  //{localhost=StandardEngine[Catalina].StandardHost[localhost]}
            log2.info("children: " + children.toString());
            try {
                // 这里使用ip会有问题会走catch的逻辑,也可以都用catch的逻辑代替
                StandardHost standardHost = (StandardHost) children.get(this.serverName);
                children = (HashMap) getField(standardHost, "children");
                log2.info("standardHost: " + standardHost.toString());
                Iterator iterator = children.keySet().iterator();
                while (iterator.hasNext()) {
                    String contextKey = (String) iterator.next();
                    if (!(this.uri.startsWith(contextKey))) {
                        continue;
                    }
                    StandardContext standardContext = (StandardContext) children.get(contextKey);
                    this.standardContext = standardContext;
                    return;
                }
            } catch (Exception e) {
                // 不管是用 ip 还是 localhost 访问 最终都是走这个逻辑   children.get("localhost");
                //log2.info(e.toString());  // java.lang.NullPointerException

                StandardHost standardHost = (StandardHost) children.get("localhost");
                log2.info("standardHost: " + standardHost.toString());
                try {
                    children = (HashMap) getField(standardHost, "children");
                    Iterator iterator = children.keySet().iterator();
                    while (iterator.hasNext()) {
                        String contextKey = (String) iterator.next();
                        if (this.uri.startsWith(contextKey) && contextKey != "") {
                            StandardContext standardContext = (StandardContext) children.get(contextKey);
                            this.standardContext = standardContext; // StandardEngine[Catalina].StandardHost[localhost].StandardContext[/untitled3_war_exploded]
                            log2.warning(ANSI_GREEN + "standardContext: " + standardContext.toString() + ANSI_RESET);
                            return;
                        }
                    }
                } catch (Exception e2) {
                    //log2.info(e2.toString()); //java.lang.NoSuchFieldException: children
                }
            }
        }
    }
}

public StandardContext getSTC() {
    return this.standardContext;
}

%>
<%
String ANSI_RESET = “\u001B[0m”;
String ANSI_RED = “\u001B[31m”;
String ANSI_GREEN = “\u001B[32m”;
String ANSI_YELLOW = “\u001B[33m”;
Logger log = Logger.getLogger(“main”);

Thread[] threads = (Thread[]) this.getField(Thread.currentThread().getThreadGroup(), "threads"); // tomcat 线程
Object object;
for (Thread thread : threads) {
    if (thread == null || thread.getName().contains("exec")) {
        continue;
    }
    log.info(ANSI_RED + "main_thread: " + thread + ANSI_RESET);        // 打印 线程  // Thread[main,5,main]  // Thread[Monitor Ctrl-Break,5,main]
    if (thread.getName().contains("Acceptor") || thread.getName().contains("Poller")) {
        Object target = this.getField(thread, "target");  //! target instanceof Runnable
        log.info("main_target: " + target);
        log.info(String.valueOf(target instanceof Runnable));
        if (!(target instanceof Runnable)) {
            continue;
        }

        try {
            object = getField(getField(getField(target, "this$0"), "handler"), "global");
        } catch (Exception e) {
            //log.warning(ANSI_RED+e.toString()+ANSI_RESET); // java.lang.NoSuchFieldException
            continue;
        }
        if (object == null) {
            continue;
        }
        java.util.ArrayList processors = (java.util.ArrayList) getField(object, "processors");
        Iterator iterator = processors.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            Object req = getField(next, "req");   // 获取 req 对象
            // 过滤 // req: R( null)
            Object serverPort = getField(req, "serverPort");
            if (serverPort.equals(-1)) {   // 不是对应的请求时,serverPort = -1
                continue;
            }
            log.info("req: " + req.toString());  // req: R( /untitled3_war_exploded/2.jsp)

            org.apache.tomcat.util.buf.MessageBytes serverNameMB = (org.apache.tomcat.util.buf.MessageBytes) getField(req, "serverNameMB");
            this.serverName = (String) getField(serverNameMB, "strValue");
            if (this.serverName == null) {
                this.serverName = serverNameMB.toString();
            }
            if (this.serverName == null) {
                this.serverName = serverNameMB.getString();
            }
            log.info(this.serverName.toString());  // 10.10.40.65
            org.apache.tomcat.util.buf.MessageBytes uriMB = (org.apache.tomcat.util.buf.MessageBytes) getField(req, "uriMB");
            this.uri = (String) getField(uriMB, "strValue");
            if (this.uri == null) {
                this.uri = uriMB.toString();
            }
            if (this.uri == null) {
                this.uri = uriMB.getString();
            }
            log.info(this.uri.toString());
            this.getStandardContext();
        }
    }
}

%>


![](https://img-blog.csdnimg.cn/7d3fe446d7fd4826a31a24d412d512c1.jpeg)



### 0x02 复盘总结



getField(jioEndPoint, “handler”).proto.endpoint.poller.selector.keys[0]


![](https://img-blog.csdnimg.cn/4abac33e425c49839c4c9b03a6441ec4.png)




(threads[6].target.endpoint.poller.selector.keys).toArray()[0].channel.toString()


![](https://img-blog.csdnimg.cn/46b687fe5b2c4f748ed9f49260800cb2.png)



即使使用ip访问,线程获取到的只有localhost,不过这并不影响最终获取:


以 Tomcat9为例,


Poller线程:


![](https://img-blog.csdnimg.cn/ba8f15cd2f4f45d5905decee87beeffa.png)



threads[5].target.this$0.handler.proto.adapter.connector.service.engine.children


![](https://img-blog.csdnimg.cn/67dd62df426740ba91b26bebee336bbe.png)


 Acceptor线程:



threads[6].target.endpoint.handler.proto.adapter.connector.service.engine.children


![](https://img-blog.csdnimg.cn/804a31279a3c436ca7e5cdc5f7a681ef.png)


 获取到 StandardContext:


![](https://img-blog.csdnimg.cn/1f5d9ee3c0a74be4a51fc43723ebdb72.png)



### 0x03 后记


把源码公开,不求回报,大家在实战过程中如遇到问题欢迎留言讨论。。



### reference


[Tomcat Acceptor/Poller](https://bbs.csdn.net/topics/618653875)
## 最后

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**

![img](https://img-blog.csdnimg.cn/img_convert/a99715cf0fb6b89eff946932fa1c0fe1.png)

![img](https://img-blog.csdnimg.cn/img_convert/8a558cc62f1ca8e12df3ab971640ea9b.png)

![img](https://img-blog.csdnimg.cn/img_convert/ae01ae436e25f6b20a4b0901161a2dde.png)

![img](https://img-blog.csdnimg.cn/img_convert/59bfee2cbd19b7d6774b8f9e95008464.png)

![img](https://img-blog.csdnimg.cn/img_convert/482861d8b88e4516e1eede45caeba67c.png)

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)

**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

..(img-fBj81zfU-1715881479726)]

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)

**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值