Java安全之挖掘回显链
Java安全之挖掘回显链
0x00 前言
前文中叙述反序列化回显只是为了拿到Request和Response对象。在这里说的的回显链其实就是通过一连串反射代码获取到该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
0x02 结尾
其他中间件也是同理,设置筛选条件。然后定位request进行一步步的反射获取即可。再次吹爆该项目。目前只会简单使用,其他用法待研究。
Java安全之挖掘回显链的更多相关文章
- Java安全之反序列化回显研究
Java安全之反序列化回显研究 0x00 前言 续上文反序列化回显与内存马,继续来看看反序列化回显的方式.上篇文中其实是利用中间件中存储的Request 和Response对象来进行回显.但并不止这么 ...
- Java安全之基于Tomcat的通用回显链
Java安全之基于Tomcat的通用回显链 写在前面 首先看这篇文还是建议简单了解下Tomcat中的一些概念,不然看起来会比较吃力.其次是回顾下反射中有关Field类的一些操作. * Field[] ...
- Java安全之反序列化回显与内存马
Java安全之反序列化回显与内存马 0x00 前言 按照我个人的理解来说其实只要能拿到Request 和 Response对象即可进行回显的构造,当然这也是众多方式的一种.也是目前用的较多的方式.比如 ...
- Java反序列化漏洞执行命令回显实现及Exploit下载
原文地址:http://www.freebuf.com/tools/88908.html 本文原创作者:rebeyond 文中提及的部分技术.工具可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使 ...
- java序列回显学习
java反序列化回显 在很多不出网的情况下,一种是写webshell(内存嘛),另一种就是回显,本文先学习回显,回显的主要方式有一下几种. defineClass RMI绑定实例 URLClassLo ...
- 【Java EE 学习 73】【数据采集系统第五天】【参与调查】【导航处理】【答案回显】【保存答案】
一.参与调查的流程 单击导航栏上的“参与调查”按钮->EntrySurveyAction做出相应,找到所有的Survey对象并转发到显示所有survey对象的页面上供用户选择->用户单击其 ...
- java图片上传及图片回显1
目的:选择图片,进行图片回显之后将图片保存到服务器上(PS:没有使用任何插件,样式很丑) 实现方式: js+servlet+jsp的方式来实现 事先准备: 文件上传处理在浏览器中是以流的形式提交到服务 ...
- java反序列化提取payload之xray 高级版的shiro回显poc的提取过程
本文中xray高级版shiro payload来源于雷石安全实验室公众号发布的shiroExploit.jar 感谢雷石安全实验室,雷石安全实验室牛逼 本文主要描述如何从shiro的payload中提 ...
- SpEL表达式注入漏洞学习和回显poc研究
目录 前言 环境 基础学习和回显实验 语法基础 回显实验 BufferedReader Scanner SpEL漏洞复现 低版本SpringBoot中IllegalStateException CVE ...
随机推荐
- 安装过程中出现一个错误: No such plugin: cloudbees-folder
上面的错误显示是,安装插件cloudbees-folder失败,是因为下载的Jenkins.war里没有cloudbees-folder插件 需要去 https://updates.jenkins-c ...
- Spring 实现策略模式--自定义注解方式解耦if...else
策略模式 定义 定义一簇算法类,将每个算法分别封装起来,让他们可以互相替换,策略模式可以使算法的变化独立于使用它们的客户端 场景 使用策略模式,可以避免冗长的if-else 或 switch分支判断 ...
- [Java] Hibernate
背景 持久化技术框架 封装了JDBC做数据库相关功能开发的重复性工作 比如创建连接,关闭连接,把字段逐一映射到属性中等 使用 在数据库中创建表 创建java project 导入hibernate依赖 ...
- 怎么用CMD命令进入D盘
怎么用CMD命令进入D盘 太平洋电脑网 已认证的官方帐号 6 人赞同了该文章 大家都知道win操作系统想要打开D盘,直接点我的电脑就能进d盘了,有时候只能使用dos的情况下也利用系统自带的cmd命 ...
- Rust 多态
Rust 多态 分发 多态的上下文中的方法解析过程被称为分发,调用该方法称为分发化,在支持多态的主流语言中,分发可以通过以下任意一种方式进行. 静态分发 当在编译期决定要调用的方法时,它被称为静态分发 ...
- 035.Python正则表达式
正则表达式 一 介绍 拼正则表达式是什么? 它是约束字符串匹配某种形式的规则 正则表达式有什么用? 检测某个字符串是否符合规则比如:判断手机号,身份证号是否合法 提取网页字符串中想要的数据.比如:爬虫 ...
- component: resolve => require(['../pages/home.vue'], resolve)-装载
import Vue from 'vue'import VueRouter from 'vue-router'// "@"相当于".."import Detai ...
- MyBatis 动态SQL(十二)
动态条件查询 以下是我们数据库表 tb_user 的记录: 假设现在有一个需求,就是根据输入的用户年龄和性别,查询用户的记录信息.你可能会说,这太简单了,脑袋里立马蹦出如下的 SQL 语句: SELE ...
- MyBatis 数据源的原理和机制
回顾JDBC JDBC访问数据库流程 加载驱动 获取Connection连接对象(消耗性能) 获取PrepareStatement对象 执行SQL语句 获取结果集 关闭Connection连接对象 存 ...
- readlink 函数用法 -(转自 JK198310的专栏)
相关函数: stat, lstat, symlink 表头文件: #include <unistd.h> 定义函数:ssize_t readlink(const char *path, c ...