java rmi漏洞
Java RMI漏洞这玩意儿,说白了就是远程方法调用协议在反序列化环节上开了个大口子。2015年那次ysoserial工具公开,直接把这块遮羞布撕得粉碎——攻击者只要向目标RMI注册中心或服务端口扔一个精心构造的序列化对象,就能在服务器上执行任意命令,跟拿到shell差不多。 举个真实例子。某银行内部系统用了老版本WebLogic,RMI服务监听在7001端口。渗透测试时,一个nmap扫描发现了这个端口,接着用ysoserial的CommonsCollections1链打过去,三秒钟就弹回了root权限。整个过程不需要任何账号密码,纯粹靠协议本身的信任机制——RMI默认信任所有反序列化数据,这设计在当年网络环境单纯时没问题,现在看就是引狼入室。 为啥这么容易中招?根子在于Java原生的序列化机制把对象和代码执行绑得太紧。RMI通信时,客户端和服务端要交换序列化对象,服务端拿到字节流后直接ObjectInputStream.readObject(),压根不校验里面装的是啥。攻击者构造一个恶意对象,重写它的readObject方法,让它在反序列化时触发Runtime.exec(),这就像你收了个快递,没看寄件人是谁就拆开,结果里面是个弹簧刀。 更恶心的是,这个漏洞不挑食。老的JDK版本、Spring框架、Apache Commons Collections库,只要classpath里有那些常见依赖,基本一打一个准。有些系统管理员觉得“我内网环境,外网打不进来”,可RMI端口常常映射到公网,或者通过跳板机穿透。我见过一个政府网站,RMI服务就绑在公网IP上,扫描器一搜一个准,跟裸奔没区别。 修复方案其实不复杂,但很多人懒得做。最直接的是升级JDK到8u121以上,或者给RMI服务加一层JEP 290过滤——这个机制允许你定义反序列化类的白名单。但现实里,很多老系统跑了好几年,业务代码依赖那些老库,一升级就报ClassNotFoundException,于是运维就拖着,拖到漏洞被利用。 还有个坑是,RMI漏洞不止在服务端。客户端也会中招,比如你连了一个恶意RMI注册中心,它返回一个恶意序列化对象,你的客户端反序列化时照样被干。这年头攻击者还会用JRMP监听器做中间人,诱导你连过去。所以别觉得“我没对外开放RMI就安全”,内部开发机、测试环境,都是重灾区。 我自己做过一次应急响应,某电商平台被入侵,查日志发现攻击者就是通过RMI漏洞上传了一个webshell。但有意思的是,他们没直接拿数据,而是在服务器上装了个挖矿程序,跑了一个月才被发现。这种漏洞的可怕之处在于,它给你的不是一次性的shell,而是持久的控制权——你改密码、重启服务都没用,只要RMI端口还开着,他随时能再进来。 说句实在话,Java RMI这技术本身已经过时了,现在微服务都用HTTP+gRPC,谁还玩这个。但架不住存量系统多,银行、政务、传统企业,一堆老项目还靠它撑着。你要是运维,别指望开发主动改架构,自己把端口用防火墙封了,或者加个代理层做白名单,比什么都强。要是非用不可,至少把JEP 290打开,再定期扫一遍classpath里的反序列化库版本。 最后提醒一句,别拿网上那些POC乱打,很多POC本身带后门。我见过有人用别人写的工具测试,结果自己服务器被反打了。搞安全,工具要自己写,依赖要自己审,漏洞利用这事儿,信任别人等于送人头。
-
上一篇
-
下一篇