提交 #911865: dromara orion-visor v2.5.7 AES Encryption Key信息

标题dromara orion-visor v2.5.7 AES Encryption Key
描述Hardcoded AES Encryption Key Enables Decryption of SSH Private Keys and Host Passwords (CWE-321) in orion-visor Summary The orion-visor bastion host uses AES encryption to protect extremely sensitive credentials: SSH private keys (stored in host_key table) and host identity passwords. The AES secret key uQeacXV8b3isvKLK is hardcoded as a default value in both application-prod.yaml (line 93) and docker-compose.yaml (line 48). This key is identical across all deployments and publicly visible in the open-source repository. If an attacker obtains encrypted ciphertext from the database—via SQL injection, unauthorized database access, or backup file exposure—they can use this known key to decrypt all SSH private keys and host passwords, gaining direct unrestricted SSH access to every managed host and completely bypassing the bastion security model. Details Root cause: Cryptographic key management failure. The AES encryption key used by AesEncryptUtils to protect the system's most sensitive data is hardcoded with a default value in configuration files. In application-prod.yaml lines 90-93: encrypt.aes.secret-key: ${SECRET_KEY:uQeacXV8b3isvKLK}. In docker-compose.yaml line 48: SECRET_KEY: ${SECRET_KEY:-uQeacXV8b3isvKLK}. If the SECRET_KEY environment variable is not explicitly set during deployment, the fallback value uQeacXV8b3isvKLK is used. This key is publicly visible in the open-source repository at github.com/dromara/orion-visor. Source-to-sink chain: HostKeyServiceImpl.encryptKey() (lines 281-290) calls AesEncryptUtils.encryptAsString() to encrypt SSH public keys and private keys before storing them in the host_key database table. HostKeyServiceImpl.decryptKey() (lines 297-306) calls AesEncryptUtils.decryptAsString() to decrypt them back. HostKeyServiceImpl.createHostKey() (line 100) additionally encrypts the key passphrase. All these operations use the same hardcoded AES key. AesEncryptUtils delegates to AesEncryptorImpl which is configured with the key from the configuration. Trust boundary failure: The encryption is meant to protect credentials at rest (in the database). However, the key is not truly secret—it is a known default value. The cryptographic protection is therefore completely ineffective against any attacker who has access to the encrypted ciphertext and knows where to find the key (i.e., the public repository). Core vulnerable code path: # orion-visor-launch/src/main/resources/application-prod.yaml:90-93 encrypt: aes: # 加密密钥 secret-key: ${SECRET_KEY:uQeacXV8b3isvKLK} Production configuration with hardcoded AES encryption key default uQeacXV8b3isvKLK. This fallback value is used when the SECRET_KEY environment variable is not explicitly set and is publicly visible in the open-source repository. # docker-compose.yaml:48-48 SECRET_KEY: ${SECRET_KEY:-uQeacXV8b3isvKLK} Docker Compose configuration also hardcodes the same AES key uQeacXV8b3isvKLK as a default fallback, confirming the key is identical across deployment methods. // orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostKeyServiceImpl.java:281-306 private void encryptKey(HostKeyDO record) { String publicKey = record.getPublicKey(); if (!Strings.isBlank(publicKey)) { record.setPublicKey(AesEncryptUtils.encryptAsString(publicKey)); } String privateKey = record.getPrivateKey(); if (!Strings.isBlank(privateKey)) { record.setPrivateKey(AesEncryptUtils.encryptAsString(privateKey)); } } private void decryptKey(HostKeyDO record) { String publicKey = record.getPublicKey(); if (!Strings.isBlank(publicKey)) { record.setPublicKey(AesEncryptUtils.decryptAsString(publicKey)); } String privateKey = record.getPrivateKey(); if (!Strings.isBlank(privateKey)) { record.setPrivateKey(AesEncryptUtils.decryptAsString(privateKey)); } } encryptKey() and decryptKey() methods use AesEncryptUtils to encrypt/decrypt SSH public and private keys with the hardcoded AES key. The private key material is the most sensitive credential in the bastion system—it grants direct SSH access to managed hosts. // orion-visor-common/src/main/java/org/dromara/visor/common/utils/AesEncryptUtils.java:108-110 public static String decryptAsString(String text) { return delegate.decryptAsString(text); } AesEncryptUtils.decryptAsString() delegates to the AesEncryptor which uses the hardcoded key. With the known key, any encrypted ciphertext from the database can be trivially decrypted to recover plaintext SSH private keys and passwords. POC Preconditions: (1) System deployed using default AES key uQeacXV8b3isvKLK (SECRET_KEY environment variable not overridden). (2) Attacker can obtain encrypted data from the host_key database table—this could be via SQL injection, unauthorized database access, exposed database backup files, or insider threat. Step 1 - Obtain the key: The AES key uQeacXV8b3isvKLK is publicly available from the open-source repository's docker-compose.yaml and application-prod.yaml files. Step 2 - Obtain encrypted ciphertext: From the host_key database table, extract the encrypted private_key and password columns: SELECT private_key, password FROM host_key WHERE id = 1; Step 3 - Decrypt: Using the known AES key, decrypt the ciphertext to recover the plaintext SSH private key. Python PoC: python3 -c "from Crypto.Cipher import AES; from Crypto.Util.Padding import unpad; import base64; key=b'uQeacXV8b3isvKLK'; ct=base64.b64decode(''); cipher=AES.new(key,AES.MODE_ECB); print(unpad(cipher.decrypt(ct),16).decode())" Expected result: Plaintext SSH private key (-----BEGIN RSA PRIVATE KEY-----...). The decrypted password passphrase (if any) can also be recovered. Step 4 - Direct SSH access: ssh -i /tmp/decrypted_key root@managed-host. Bastion access control, session recording, and command auditing are all completely bypassed. Impact Complete compromise of the bastion host security model. All SSH private keys and host passwords stored in the database can be decrypted using the publicly known AES key. The attacker gains direct unrestricted SSH access to every managed host, completely bypassing bastion access control, privilege management, session recording, and command audit logging. CVSS Score: 9.1 (Critical) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H. Remediation Remove the hardcoded AES key default from all configuration files (application-prod.yaml, application.yaml, docker-compose.yaml, docker-compose-bt.yml). Require a mandatory SECRET_KEY environment variable at startup; refuse to start if not set or if it matches any known default value. Generate a unique cryptographically random key (at least 256 bits) per deployment during initial setup. Consider using a dedicated key management service (HashiCorp Vault, AWS KMS, Azure Key Vault) instead of storing keys in configuration. Implement a key rotation mechanism and re-encrypt all existing encrypted data with the new key. Audit existing deployments and notify users to immediately rotate their SECRET_KEY and re-encrypt all stored credentials. Store the key exclusively in a secure secrets manager, never in version-controlled files. Disclosure Notes The hardcoded AES key uQeacXV8b3isvKLK is publicly visible in the open-source repository. Discovered through source code audit. Affected versions: confirmed in v2.5.7. The development default in application.yaml is a different hardcoded value: I66AndrKWrwXjtBL. Earlier versions that use AesEncryptUtils are also affected. Full exploitation requires database access (via SQL injection, backup exposure, or insider access), but CWE-321 is independently CVE-worthy as a critical cryptographic failure. Vendor patch timeline: to be confirmed. Supplemental Information Affected products Ecosystem: self-hosted Package name: orion-visor Affected versions: v2.5.7 Patched versions: to be confirmed Severity Scoring method: CVSS v3.1 Score: 9.1 Vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H Weaknesses CWE: CWE-321 Use of Hard-coded Cryptographic Key Project address: https://github.com/dromara/orion-visor Reporter: sumo166 Email: [email protected] GitHub profile: https://github.com/sumo166 vuldb ID:summmm
来源⚠️ https://github.com/dromara/orion-visor/issues/171;https://github.com/sumo166/CVE-apply/blob/main/dromara-orion-visor/Hardcoded%20AES%20Encryption%20Key%20Enables%20Decryption%20of%20SSH%20Private%20Keys%20and%20Host%20Passwords%20(CWE-321)_en.md
用户
 summmm (UID 69690)
提交2026-07-31 11時31分 (1 月前)
管理2026-09-12 10時58分 (1 month later)
状态已接受
VulDB条目403098 [dromara orion-visor 直到 2.5.7 HostKeyServiceImpl.java HostKeyServiceImpl.encryptKey 弱加密]
积分20

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!