In a recent assessment, we had to evaluate how Microsoft’s System Management Server (SMS) certificate management solution (CMS) stores and handles certificates. This question came up because sensitive, encrypted user certificates were to be stored in the SMS CMS. Due to the sensitivity of the handled certificates, we assessed the protection capabilities of the certificate management solution against extraction attempts from a local attacker with administrative privileges.
How did we do it?
We determined a five steps approach to gain access to the certificates and be able to decrypt the accessed certificate material:
- Identify certificate locations
- Extract certificates
- Understand certificate encryption procedure (assuming that the SMS CMS performs some additional encryption) and identify used key material
- Extract required key material
- Decrypt the certificates
But let’s take a step back and discuss a few tools and facts that are relevant when trying to extract the certificates from the SMS: Powershell and WMI. Powershell allows the import and deletion of user certificates in the pfx format. SCCM 2012 SP2 adds an SMS_ClientPfxCertificate class to the SDK. This class includes the following methods:
- ImportForUser
- DeleteForUser
During our evaluation the method ImportForUser was used to import a pfx file — to actually have a certificate in the SMS CMS that we can search for 😉
The Windows Management Instrumentation (WMI) is an implementation of the Web Based Enterprise Management (WBEM). WMI has the flexibility and extensibility required to manage local and remote resources that comprise arbitrary components. The WMI service lives in a shared svchost process which hosts an RPC service. The associated WMI provider is loaded into a WMI service WmiPrvSE. The responsibility for defining and exporting the representation of the objects that management applications are interested in is part of the WMI providers.
So keep in mind that since the WMI provider represents the communication interface for certificate operations, we can check if relevant information can be extracted from memory. During identification of relevant API calls, the WMI process is of course also an interesting object.
Down the rabbit hole
To be able to extract a certificate from the memory of the WmiPrvSE process, lets have a look how certificates are represented within memory.
- A certificate has the following ASN.1 syntax:
SEQUENCE { SEQUENCE { [..]
- The following shows the hexadecimal representation of this ASN.1 syntax:
30 82 ?? ?? - SEQUENCE (30 82), length of the SEQUENCE (?? ??) 30 82 ?? ?? - SEQUENCE (30 82), length of the SEQUENCE (?? ??)
As all certificates should be represented in this syntax, the memory can be analyzed for this pattern. Using the length of the sequence as described above, it is then possible to extract the certificate from the memory area.
- Determine the length of the certificate:
openssl asn1parse -inform DER -in cert.der 0:d=0 hl=4 l=1269 cons: SEQUENCE 4:d=1 hl=4 l= 989 cons: SEQUENCE [...] hexdump cert.der 8230 f504 8230 dd03 [...] Length of the SEQUENCE 0x04f5 in decimal 1269 bytes To determine the final size we only need to add the hl=4 byte header length. ls -l -rw-r--r-- 1 itchy users 1273 Aug 4 15:59 cert.der
However, there is one restriction when it comes to accessing these memory areas: by default, it is not allowed for applications to have access to other applications’ process memory. Whenever applications have to use services of the operating system there are secured and dedicated interfaces to ensure that. In this case, we need the corresponding privilege SE_DEBUG – by default only the administrator has this privilege.
The memory analysis as described above will potentially result in many identified certificates (especially on a busy SMS). The identification of the certificate we’re looking for involves manual analysis of the different certificate fields 😉
The certificate extracted from memory is not encrypted. This is because, during the import, there are some file consistency verification steps.
- File consistency verification:
HCERTSTORE WINAPI PFXImportCertStore( _In_ CRYPT_DATA_BLOB *pPFX, _In_ LPCWSTR szPassword, _In_ DWORD dwFlags) ); The dwFlage is set to PKCS12_NO_PERSIST_KEY which means, that no data is stored persisted. But since it is processed... it will at least show up in memory. see also: https://msdn.microsoft.com/en-us/library/windows/desktop/aa387314(v=vs.85).aspx
This is already a good result, given that we imported an encrypted certificate into the SMS CMS. That means the next step is to analyzing the complete import and encryption process of the SMS CMS, because we are after the persistent data.
First, the ODBC interface makes it possible for application to access data from a database management system. By attaching to the right process we can trace all exported functions from the library odbc32.dll. In this particular case we can figure out the relevant database tables and the data they contain with the API call SQLExecDirectW. The following are the relevant database tables:
- dbo.PfxCertificates, containing objects like:
4D00490049004B004A0041004900420041007A00430043004300 6500410047004300530071004700530049006200330044005100 0A00410061004300 […]
- dbo.PfxSecretsLocalSite, containing objects like:
0x0C01000040000000010200000366000000A40000991D8F5704 60B6C93732A267F84D9F1F6518D6447A81DD94014B6387227999 D6F33E61E6750C405BD2BE0E3836D827C531274A98750EBBDE3E D0E202B23A2D1F01486 […]
- dbo.PfxSecrets, containing objects like:
8A711CEAA62244896EBA88889D939334
The objects in PfxSecretsLocalSite consist of three parts: a header, an encrypted 3DES key, and an encrypted AES key. Tracing various API calls we determined the following encryption process:
- The certificate is stored in the database as it was submitted initially (i.e. encrypted by the user with a password chosen by the user).
- The random generated AES key is used to encrypted the initial PFX password (which if requested from the user during import).
- The random generated 3DES key is used to encrypted the AES key.
- The asymmetric SCCM site key is used to encrypted the 3DES key (the public key part is stored in the registry).
That means the only missing information to decrypt the whole chain is the private part of the SMS site keys.
Extracting the SMS Site Key
Since Windows Server 2008 and Vista, there is a feature called “Key Isolation”. The Local Security Authority (LSA) process is used as the key isolation process. All access to private keys goes through the key storage router, which exposes a comprehensive set of functions for managing and using private keys. With the tool mimikatz it is possible to dump all the private keys stored in a specific key provider.
- These are the mimikatz commands to achieve this:
privilege::debug crypto::capi crypto::cng Crypto::keys /machine /export
Finally, the last command dumps all the private keys in the mimikatz root folder. So now we have a whole truckload of key files. However, the only thing to do is identify the right private key to our already identified public key.
- Verifying that a private key matches a public key:
openssl rsa -pubin -inform 'MS\ PUBLICKEYBLOB' -in pub -outform PEM -out public.pem openssl rsa -pubin -inform PEM -text -noout < public.pem Public-Key: (2048 bit) Modulus: 00:b3:d9:81:2f:00:b8:d8:fa:c1:da:7b:6b:18:37: [...] 84:b7 Exponent: 65537 (0x10001) openssl rsa -inform pvk -in extracted_sms_private_key.pvk -out private.pem -outform pem openssl rsa -in private.pem -noout -text Private-Key: (2048 bit) modulus: 00:b3:d9:81:2f:00:b8:d8:fa:c1:da:7b:6b:18:37: [...] 84:b7 publicExponent: 65537 (0x10001) [...]
The `modulus’ and the `exponent’ portions of both should match ;).
Summary
As we described above, it is possible for a local administrator to extract certificate information from the SMS CMS and decrypt it — which is not overly surprising given the overall nature of the x86 architecture 😉 However, in our project the time to achieve this was an important benchmark to design appropriate controls protecting the overall SMS. One countermeasure which was discussed later was the use of an HSM to store the certificates. This may increase the effort to extract certificates even further, however, given that the SMS CMS (in the specific scenario) is there to handle and process the certificates in an automated way, an attacker with local admin privileges will still be able to extract the certificates eventually. Thus we recommend to perform extensive hardening of the SMS in question with a particular focus on privilege escalation. Extensive use of EMET, UAC/MIC, and of course only assigning the SE_DEBUG privilege when absolutely necessary come directly to mind — but this post is not about hardening Windows systems 🙂
Please also note that there is no vulnerability involved here but everything works as designed. We also checked with Microsoft before the release of this article, but as Microsoft in general is open for the publication of analysis results from their products, they had no additional questions in this case either.
Have a nice (and maybe even sunny) weekend!,
Dominik, Felix & Matthias