Keep An Eye on your Root Certificates

Published: 2017-11-11
Last Updated: 2017-11-11 07:48:49 UTC
by Xavier Mertens (Version: 1)
3 comment(s)

A few times a year, we can read in the news that a rogue root certificate was installed without the user consent. The latest story that pops up in my mind is the Savitech audio drivers which silently installs a root certificate[1]. The risks associated with this kind of behaviour are multiple, the most important remains performing MitM attacks. New root certificates are not always the result of an attack or infection by a malware. Corporate end-points might also get new root certificates. Indeed, more and more companies are deploying SSL inspections tools. It could be interesting to keep an eye on what’s happening in your certificate store. On Windows systems, there is a GUI tool for this purpose, that you can call from the command line:

PC C:\Users\xavier> certmgr.msc

Or, from the Control panel ("Manager User/Computer Certificated"):

A GUI is nice but the power of the command line is better! We can also interact with the certificate store via PowerShell. PowerShell has a virtual drive ‘CERT:’ that allows interacting with the certificate store. Here are some examples of commands:

PS C:\Users\xavier> ls CERT:

Location   : CurrentUser
StoreNames : {TrustedPublisher, ClientAuthIssuer, Root, UserDS...}

Location   : LocalMachine
StoreNames : {TrustedPublisher, ClientAuthIssuer, Root, TrustedDevices…}

PS C:\Users\xavier> ls CERT:\CurrentUser

Name : TrustedPublisher
Name : ClientAuthIssuer
Name : Root
Name : UserDS
Name : CA
Name : REQUEST
Name : AuthRoot
Name : TrustedPeople
Name : ADDRESSBOOK
Name : My
Name : SmartCardRoot
Name : Trust
Name : Disallowed

Now, let’s list the CA for the current user:

PS C:\Users\xavier> ls CERT:\CurrentUser\AuthRoot

PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\AuthRoot

Thumbprint                                Subject
----------                                -------
F18B538D1BE903B6A6F056435B171589CAF36BF2  CN=thawte Primary Root CA - G3, OU="(c) 2008 thawte, Inc. - For authorized use only", OU=Certification Services...
E12DFB4B41D7D9C32B30514BAC1D81D8385E2D46  CN=UTN-USERFirst-Object, OU=http://www.usertrust.com, O=The USERTRUST Network, L=Salt Lake City, S=UT, C=US
DE28F4A4FFE5B92FA3C503D1A349A7F9962A8212  CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
DAC9024F54D8F6DF94935FB1732638CA6AD77C13  CN=DST Root CA X3, O=Digital Signature Trust Co.
D69B561148F01C77C54578C10926DF5B856976AD  CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R3
D4DE20D05E66FC53FE1A50882C78DB2852CAE474  CN=Baltimore CyberTrust Root, OU=CyberTrust, O=Baltimore, C=IE
(remaining list removed)

You can display more details with only a few lines of code:

PS C:\Users\xavier> $store = New-Object System.Security.Cryptography.X509Certificates.X509Store("root","LocalMachine")
$store.Open("ReadOnly")
$store.certificates | select ThumbPrint,FriendlyName,NotAfter

Thumbprint                               FriendlyName                                    NotAfter          
----------                               ------------                                    --------          
CDD4EEAE6000AC7F40C3802C171E30148030C072 Microsoft Root Certificate Authority            10-May-21 01:28:13
BE36A4562FB2EE05DBB3D32323ADF445084ED656 Thawte Timestamping CA                          01-Jan-21 00:59:59
A43489159A520F0D93D032CCAF37E7FE20A8B419 Microsoft Root Authority                        31-Dec-20 08:00:00
92B46C76E13054E104F230517E6E504D43AB10B5                                                 15-Mar-32 00:59:59
8F43288AD272F3103B6FB1428485EA3014C0BCFE Microsoft Root Certificate Authority 2011       22-Mar-36 23:13:04
7F88CD7223F3C813818C994614A89C99FA3B5247 Microsoft Authenticode(tm) Root                 01-Jan-00 00:59:59
3B1EFD3A66EA28B16697394703A72CA340A05BD5 Microsoft Root Certificate Authority 2010       24-Jun-35 00:04:01
245C97DF7514E7CF2DF8BE72AE957B9E04741E85 Microsoft Timestamp Root                        31-Dec-99 00:59:59
18F7C1FCC3090203FD5BAA2F861A754976C8DD25 VeriSign Time Stamping CA                       08-Jan-04 00:59:59

What I'm doing on my test computers, I'm running a quick PowerShell script that collects details for all the certificates installed in the store, computes a SHA256 hash of the results and compares it with the hash generated by the last execution. Schedule it at a regular interval (ex: once a day). It will display information on the console but also create a specific Windows Event in the Application log:

#
# Generates a SHA256 hash of the certificate store and 
# compares it with the previous execution.
#
# Note:
# Do This with admin privs to create the new eventlog source:
# New-EventLog –LogName Application –Source “CertificateStoreChecker”

param(
    [String]$outputPath="$env:USERPROFILE\certstore.hash"
)

# Compute the hash of a string
Function Get-StringHash([String] $String,$HashName = "SHA256")
{
    $StringBuilder = New-Object System.Text.StringBuilder
    [System.Security.Cryptography.HashAlgorithm]::Create($HashName).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|%{
        [Void]$StringBuilder.Append($_.ToString("x2"))
    }
    $StringBuilder.ToString()
}

# Replace 'CERT:' with your prefered location (ex: CERT:\CurrentUser\root)
# if you want to focus on specific certificates.
$certStoreDump = Get-ChildItem -Recurse -Path "CERT:\" 
$newSHA256 = Get-StringHash $certStoreDump
$fileExists = Test-Path $outputPath
if ($fileExists -eq $True) {
    $oldSHA256 = Get-Content $outputPath

    if($oldSHA256 -ne $newSHA256) {
        Write-Host "[WARNING] Certificate store content changed since the last execution!"
        Write-EventLog -LogName "Application" -Source "CertificateStoreChecker" -EventID 65501 -EntryType Information -Message "[WARNING] Certificate store content changed since the last execution!"

    }
}
else {
    Write-Host "[INFO] First execution, generating SHA256 file: $outputPath"
    Write-EventLog -LogName "Application" -Source "CertificateStoreChecker" -EventID 65500 -EntryType Information -Message "[INFO] First execution, generating SHA256 file: $outputPath"

}
Out-File -FilePath $outputPath -InputObject $newSHA256

By default, the hash is stored in %USERPROFILE%\certstore.hash but you can specify it on the command line:

PS C:\bin> .\certificatestorechecker.ps1
[WARNING] Certificate store content changed since the last execution! 

And the corresponding event in the Event Log Viewer:

[1] http://www.securityweek.com/savitech-audio-drivers-caught-installing-root-certificate

Xavier Mertens (@xme)
ISC Handler - Freelance Security Consultant
PGP Key

3 comment(s)

Comments

Try Microsoft's SigCheck. It shows you differences between Microsoft's list and your certificate store.

http://blog.benmoore.info/2016/04/sigcheck.html
> A few times a year, we can read in the news that a rogue root certificate was installed without the user consent.


You mean like how Windows will automatically and silently install root certificates that you have manually removed? Thankfully we run an HTTPS intercept proxy so the real certificate store used by our workstations for Internet access is the one on the proxy and not the one in Windows.
My best choice to monitor certificates is osquery and it works for both Windows and Macos since summer
https://github.com/facebook/osquery/pull/3498
https://osquery.io/schema/ (certificates table)

Alternatives
- CASA for Splunk by IAD/NSA https://github.com/iadgov/Certificate-Authority-Situational-Awareness
- powershell scripts like https://gallery.technet.microsoft.com/scriptcenter/Certificate-Authority-0c39cb4a

Diary Archives