目录

CVE-2022-36923 ManageEngine OpManager getUserAPIKey Authentication Bypass

目录

根据ZDI的公告来看,漏洞点存在于com.adventnet.me.opmanager.server.util.RMMUtil#getUserAPIKey

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/1.png

关键点在于怎么走到这个位置。

搜索xml配置文件发现

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/2.png

路由为/RestAPI/getAPIKey,尝试构造请求包

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/3.png

提示缺失参数,看日志报错

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/4.png

IAMSecurityException 断点打在其构造函数上向上追溯,最终在com.adventnet.iam.security.ParameterRule#checkForAllowedValueRegex发现是由于参数正则匹配不对导致抛出异常。

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/5.png

最终构造参数成功返回200

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/6.png

此时回头来看com.adventnet.me.opmanager.server.util.RMMUtil#getUserAPIKey

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    public String getUserAPIKey(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String userName = request.getParameter("username");
        String domainName = request.getParameter("domainname");
        if (userName != null && domainName != null) {
            try {
                Long userId = MickeyLiteUtil.getUserId(userName, domainName);
                String apiKey = (new APIKeyGenerator()).checkAndGenerateApiKey(userId, -1L);
                response.setContentType("text/plain");
                PrintWriter out = response.getWriter();
                out.println(apiKey);
                out.flush();
                return null;
            } catch (Exception var8) {
                var8.printStackTrace();
                return null;
            }
        } else {
            return null;
        }
    }

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/7.png

MickeyLiteUtil.getUserId()需要给一个正确的domainName才行,得看数据库AaaLogin表中有什么值。

查看数据库jdbc链接C:\Program Files\ManageEngine\OpManager\conf\database_params.conf

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/8.png

密码被加密,在bin目录中发现bin\encrypt.bat

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
call .\setCommonEnv.bat

set CLASS_PATH="%SERVER_HOME%\lib\framework-tools.jar"

IF "%1"=="" GOTO SHOW_SYNTAX

"%JAVA%"  -Dserver.home="%SERVER_HOME%" -cp %CLASS_PATH% com.zoho.framework.utils.crypto.CryptoUtil %*
GOTO END_ENCRYPT

:SHOW_SYNTAX 
"%JAVA%" -Dserver.home="%SERVER_HOME%" -cp %CLASS_PATH% com.zoho.framework.utils.crypto.CryptoUtil "showUsage"

:END_ENCRYPT

调用CryptoUtil类进行加密

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/9.png

直接写一个类调用decrypt函数即可

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/10.png

cryptTag由EnDecryptUtil.getCryptTag()获得

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/11.png

解析persistence-configurations.xml文件拿到CryptTag属性,查看文件内容

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/12.png

尝试用MLITE_ENCRYPT_DECRYPT解密不成功,然后发现这个xml文件最上方引入了外部实体

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/13.png

最终在conf\customer-config.xml文件中找到了CryptTag

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/14.png

算法为AES256,解密后链接数据库,查看AaaLogin表

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/15.png

得到domainName为-,最终请求包如下

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/16.png

由此拿到restapi

rce的方式看了看restapi文档,有一个workflow可以rce,但是通过restapi访问有问题,在OpManagerServerClasses.jar!/com/adventnet/me/opmanager/server/api/OpManagerAPIServlet.class:354

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/17.png

如果你的api是APIUtil.getInstance().isInternalAPI()内部api,那么在session中isAPIClient只有在login的时候才会被赋值,所以这个地方isApiclient为false,而NmsUtil.isRMMEdition为false,导致抛出异常APIError.internalAPI(request, response)那么所有的内部api都不能被调用。

conf\OpManager\do\RestApi.xml定义了workflow关键的api都是EXPOSED_API=TRUE,也就是内部API

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/18.png

到这rce就断了,回溯了一下isInternalAPI()函数,发现所有的api在数据库OpManagerDB.public.restapioperation表中,过滤一下exposed_api='true',一共955个api可以通过restapi访问。

https://y4er.com/img/uploads/CVE-2022-36923-ManageEngine-OpManager-getUserAPIKey-Authentication-Bypass/19.png

看了看没啥都是增删改查,希望有缘人能挖出来一个rce把。

补充

同事看了opmanager的另外两个命令注入的cve,发现应该是可以串起来rce的。见同事的文章

ZOHO ManageEngine OpManager 两个RCE

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。