Skip to content

Instantly share code, notes, and snippets.

@ilatypov
Last active January 3, 2018 14:49
Show Gist options
  • Save ilatypov/993f993a05370cc9c0cb2347a2d04568 to your computer and use it in GitHub Desktop.
Save ilatypov/993f993a05370cc9c0cb2347a2d04568 to your computer and use it in GitHub Desktop.
# Detect SSL certificate mismatch indicating either multiple hosts serving the
# same name with different certificates or middle boxes authorized by the local
# machine's software.
# Usage from CMD:
# powershell -noprofile -noninteractive "$VerbosePreference = 'Continue'; .\grc.ps1 www.example.com"
# Usage from Cygwin:
# powershell -noprofile -noninteractive '$VerbosePreference = "Continue"; .\grc.ps1 www.example.com'
# How can my employer be a man-in-the-middle when I connect to Gmail?
# answer by mnmnc, Community.
# https://security.stackexchange.com/a/63391/72554
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
[string]$Hostnm
)
$grc = "https://www.grc.com/fingerprints.htm?chain=$Hostnm"
write-verbose "Connecting to $grc ..."
$result = Invoke-WebRequest $grc
# Windows PowerShell parse HTML local file
# answer by Anthony Neace, Community
# https://stackoverflow.com/a/27494480/80772
$tds = $result.ParsedHtml.getElementsByTagName("td")
$subj = ""
foreach ($td in $tds) {
if ($subj) {
$fp = $td.innerText
write-verbose "$fp $subj"
$subj = ""
}
if ($td.className -eq "ledge") {
$subj = $td.innerText
}
}
# $fpgrc = $fp -replace ':', ''
# write-verbose "$Hostnm via grc.com: $fpgrc"
$fpgrc = $fp
$ConnectString = "https://$Hostnm"
$WebRequest = [Net.WebRequest]::Create($ConnectString)
# $WebRequest.Proxy = $Proxy
# $WebRequest.Credentials = $null
# $WebRequest.Timeout = $Timeout
$WebRequest.AllowAutoRedirect = $false
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
write-verbose "Connecting to $ConnectString ..."
try {$Response = $WebRequest.GetResponse()}
catch {
write-verbose $_.Exception | format-list -force
}
if ($WebRequest.ServicePoint.Certificate -ne $null) {
$Cert = [Security.Cryptography.X509Certificates.X509Certificate2]$WebRequest.ServicePoint.Certificate.Handle
try {$SAN = ($Cert.Extensions | Where-Object {$_.Oid.Value -eq "2.5.29.17"}).Format(0) -split ", "}
catch {$SAN = $null}
$chain = New-Object Security.Cryptography.X509Certificates.X509Chain -ArgumentList (!$UseUserContext)
[void]$chain.ChainPolicy.ApplicationPolicy.Add("1.3.6.1.5.5.7.3.1")
$Status = $chain.Build($Cert)
$pso = New-Object PSObject -Property ([Ordered]@{
OriginalUri = $ConnectString;
ReturnedUri = $Response.ResponseUri;
Certificate = [Security.Cryptography.X509Certificates.X509Certificate2]$WebRequest.ServicePoint.Certificate;
Issuer = $WebRequest.ServicePoint.Certificate.Issuer;
Subject = $WebRequest.ServicePoint.Certificate.Subject;
SubjectAlternativeNames = $SAN;
CertificateIsValid = $Status;
Response = $Response;
ErrorInformation = $chain.ChainStatus | ForEach-Object {$_.Status}
})
# $pso
$fphere = $pso.Certificate.Thumbprint
$fphere = $fphere -replace '(..(?!$))', '$1:'
# write-verbose "$Hostnm from here: $fphere"
$chainElems = @($chain.ChainElements)
[array]::Reverse($chainElems)
foreach ($ce in $chainElems) {
# write-verbose "Issuer: $($ce.Certificate.Issuer)"
$subj = ($ce.Certificate.SubjectName.Name -split ", ")[0].substring(3)
$fp = $ce.Certificate.Thumbprint
$fp = $fp -replace '(..(?!$))', '$1:'
write-verbose "$fp $subj"
}
$chain.Reset()
[Net.ServicePointManager]::ServerCertificateValidationCallback = $null
} else {
Write-Error "Certificate is null"
}
if ($fpgrc -eq $fphere) {
write-verbose "Fingerprint match."
} else {
throw "Fingerprint mismatch."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment