Certificates Revisited - SSL VPN Certificates 2 Ways
As a consultant that does lots of network "stuff", I tend to build SSL VPN access for lots of clients. And a few times per year, I get the "our certificate has just expired" call from one client or another.
We covered off the "find / enumerate all the certificates for an organization " 2 weeks back, but what if you are just looking for, say, all the certificates for the Cisco AnyConnect VPN profiles in your list? That'd be handy to head off those emergency cert expiry calls.
First of all, AnyConnect profiles are all stored as XML files in C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Profile, which means we can get the list in PowerShell like this:
$files = get-childitem('C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\')
The files are in XML, so you can parse them like this (fullname includes the path):
foreach ($f in $files) {
[xml]$custprofile = get-content $f.fullname
Once read, we're just looking for the "hostaddress" xml tag, which is either the FQDN or the IP address of the target:
$hostaddr = $custprofile.anyconnectprofile.serverlist.hostentry.hostaddress
After that, we're callling nmap, using the ssl-cert.nse script:
$results = & "nmap" -sT -p443 --open $hostaddr --script=ssl-cert.nse
Once that's done, dump out selected lines to a "results" file:
$results | sls report,issuer,algorithm,after >> results.txt
In this example, we're using "select string" (sls) to look for the hostname, the Issuer of the certificate, the Signature Algorithm and the expiry date ("not valid after")
What I'm looking for is:
- Self-Signed certificates
- Certs signed by "problem" CAs (Symantec for instance)
- Certs with "problem" algorithms (md5 for instance, yes we still see those in the wild)
- Certs that are expired
Putting it all together:
$files = get-childitem('C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\')
foreach ($f in $files) {
[xml]$custprofile = get-content $f.fullname
$hostaddr = $custprofile.anyconnectprofile.serverlist.hostentry.hostaddress
$results = & "nmap" -sT -p443 --open $hostaddr --script=ssl-cert.nse
$results | sls report,issuer,algorithm,after >> results.txt
}
What do our results look like? I picked a few respresentative ones below:
Note that some of these don't have FQDN's, they're only accessed by IP address. SSL will never work right for those profiles, as there's no "CN" in the request to match the certificate.
How would this look for Palo Alto's GlobalProtect VPN Client? Not much different, except that PA stores their VPN profiles in the Windows Registry instead of in files.
First, let's grab the profiles:
$GPProfiles = gci -Path 'HKCU:\software\Palo Alto Networks\GlobalProtect\Settings'
For each of the profiles, we'll split the name by "\", and split off the registry info, grabbing only the last (5th from zero) item, which is the hostname:
foreach($prf in $GPProfiles) {
$hostaddr = $prf.name.split('\')[5]
$hostaddr
}
This gives us the hostnames (or IP addresses) for the same commands as for the Cisco VPN. The final script for PAN Certificate enumaeration is:
$GPProfiles = gci -Path 'HKCU:\software\Palo Alto Networks\GlobalProtect\Settings'
foreach($prf in $GPProfiles) {
$hostaddr = $prf.name.split('\')[5]
$results = & "nmap" -sT -p443 --open $hostaddr --script=ssl-cert.nse
$results | sls report,issuer,algorithm,after >> results.txt
}
Since the end result is the same parsed-out nmap output, the output for the Palo Alto Globalprotect enumeration is the same as for Cisco AnyConnect (only 3 certs shown):
Run these scripts (or the equivalent script for your VPN client) once a month or so, and certificate expiry dates become email notifications in advance, instead of panic renewals after expiry!
There are of course a zillion VPN clients out there - do you have a similar script for yours? Please, share using the comment form!
===============
Rob VandenBrink
Compugen
Comments