前言
年前一直在忙没时间写文章,最近不忙了看到opmanager爆出一个XXE注入,人麻了,想起来上次审计opmanager时爆了rce,也不知道自己当时审计了个啥,还是太菜,不多说了来看洞。
官方漏洞通报:UCS模块中存在一个XML外部实体(XXE)漏洞。现在已经修好了。此问题已通过在解析 XML 响应时禁用 XML 实体得到修复,因此不会调用 XML 实体。
环境搭建
下载的是126140,打补丁的是126141,下载完一路下一步即可https://archives3.manageengine.com/opmanager/126140/ManageEngine_OpManager_64bit.exe
远程调试直接在\OpManager\conf\wrapper.conf
中改就好,文件中有开启远程调试的地方只是被注释了
漏洞分析
先来看下diff,发现修改的地方都是将createDocument
改为了getSafeDocumentBuilder
,直接在sink点修改,将所有使用createDocument
的地方都改了,漏洞通报提到是在UCS模块中,所以重点关注UCSLoginHandler
和UCSDeviceUtil
这两个类
这两个类中,总共修改了三处createDocument
的地方,经过向上回溯排除了一个,剩下两个地方基本类似都是getDetails
函数,都是创建connection连接,通过传入的deviceName
(ip)和deviceName
(端口),获取输入流然后使用xml解析触发xxe注入,接下来就是去找一下触发点了
这是
UCSDeviceUtil
类中的getDetails
函数
在功能点处找到一个添加UCS的地方,试验一下,添加凭证,UCS地址为物理机的地址,然后在两个类中都打上断点进行调试,看那个能走通
最后在UCSDeviceUtil
类中的com.adventnet.me.opmanager.server.ucs.UCSDeviceUtil#getDetails(java.lang.String, java.lang.String, java.lang.Integer, java.lang.String)
函数中触发,代码很简单,就不一一分析了,最后因为设置的端口本身没有开,随即断开
接下来用python起一个http服务,这里不能直接简单的python -m http.server 9999
直接起服务,因为他需要在被访问后返回值,而这个被返回的值就是触发xxe注入的地方,因此需要可控,在网上找了一个脚本,稍微改了一下,其中data的值就是post请求返回的值(在添加凭证的地方看到有验证登陆密码的地方,也加了个验证,但经过实际验证并不需要)
|
|
因为这个本身是没有回显的,因此要想办法把数据给外带出来,可以使用ftp协议利用工具进行外带,不过这个是有jdk版本限制的,我安装环境的jdk版本为1.8.0_181,可以使用ftp协议外带,但是被外带的文件不能有\n,在这篇文章里有介绍
这里运行xxe-ftp-server脚本后,给的值为post包返回的值,为了验证漏洞,创建了一个test.txt文件,内容中没有\n,
进行测试,确实可以外带文件,不过好像也没有其它利用的方式了
小结
又犯了老毛病没仔细看diff,没看到UCSDeviceUtil
类中的getDetails
函数也被改了,在UCSLoginHandler
类中耗费了不少时间,在发现不能触发断点的时候,还以为是因为条件不满足没触发,随即就去找在添加UCS功能点实现的地方,然后往下跟看那里没满足条件,然后就一路跟到了UCSDeviceUtil
类中的getDetails
函数,还以为是官方没修全,最后发现是自己diff没看全。所以一定要细心细心在细心。
本来准备在这篇文章里总结下Java层面XXE注入代码审计的一些知识点(毕竟这洞没太大研究的价值,多多少少要来些干货),但是有点事情耽搁了,等改天有时间重新写一篇总结文章。
参考链接
原文始发于Da22le:CVE-2022-43473 ZOHO ManageEngine OpManager XXE注入