Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

x509 Details

Certificate Investigations

Warning: Antivirus and other vpn/client will intercept certificates!

Public Key: In some cases, the public key might not be accessible or exist. This depends on the certificate itself. Friendly Name: The friendly name is often used in a Windows environment and it’s optional. It’s not a part of the certificate itself but is stored in the Windows certificate store as additional data. Certificates obtained from outside the Windows certificate store won’t have a friendly name. Remember that the certificate’s details depend on the Certificate Authority (CA) that issued it. If some information is missing, it might be because it wasn’t included by the CA or it’s not accessible using the method you’re using to fetch it.

openssl: all info

openssl s_client -connect google.com:443 <<< "Q"

curl: Useful Summary

curl --insecure -vvI https://www.google.com 2>&1 | awk 'BEGIN { cert=0 } /^\* Server certificate:/ { cert=1 } /^\*/ { if (cert) print }'

Powershell: Local Store Thumbprints

Get-ChildItem -Path Cert:\LocalMachine\Root\* | ft -AutoSize

Powershell: certificate info:

function Get-ServerCertificate($url) {
    $uri = New-Object System.Uri($url)
    $tcpClient = New-Object System.Net.Sockets.TcpClient($uri.Host, 443)
    $sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream())
    $sslStream.AuthenticateAsClient($uri.Host)
    $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($sslStream.RemoteCertificate)
    $sslStream.Close()
    $tcpClient.Close()

    "Server certificate:"
    "subject: {0}" -f $certificate.Subject
    "start date: {0}" -f $certificate.NotBefore
    "expire date: {0}" -f $certificate.NotAfter
    "issuer: {0}" -f $certificate.Issuer
}

Get-ServerCertificate 'https://www.google.com'

Powershell: Check TLS Version

function Get-TlsVersion($hostname) {
    $tcpClient = New-Object System.Net.Sockets.TcpClient($hostname, 443)
    $sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream(), $false, { $true })
    $sslStream.AuthenticateAsClient($hostname)
    $sslStream.SslProtocol.ToString()
    $sslStream.Close()
    $tcpClient.Close()
}

Get-TlsVersion 'www.google.com'

Powershell: Get all Details (bulk)

function Get-ServerCertificateAndTlsVersion($url) {
    $uri = New-Object System.Uri($url)
    $tcpClient = New-Object System.Net.Sockets.TcpClient($uri.Host, 443)
    $sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream())
    $sslStream.AuthenticateAsClient($uri.Host)

    $certificate = $sslStream.RemoteCertificate
    if ($certificate -eq $null) {
        Write-Host "Unable to retrieve certificate for $url"
        return $null
    }

    $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certificate)
    $publicKey = if ($certificate.PublicKey.Key) { $certificate.PublicKey.Key.ToXmlString($false) } else { $null }
    $rawData = if ($certificate.RawData) { [System.BitConverter]::ToString($certificate.RawData) } else { $null }

    $certificateDetails = @{
        "Subject"                 = $certificate.Subject
        "Start Date"              = $certificate.NotBefore
        "Expire Date"             = $certificate.NotAfter
        "Issuer"                  = $certificate.Issuer
        "Archived"                = $certificate.Archived
        "Extensions"              = $certificate.Extensions
        "Friendly Name"           = $certificate.FriendlyName
        "Has Private Key"         = $certificate.HasPrivateKey
        "Issuer Name"             = $certificate.IssuerName.Name
        "Key Algorithm"           = $certificate.KeyAlgorithm
        "Key Algorithm Parameters"= $certificate.KeyAlgorithmParameters
        "Not After"               = $certificate.NotAfter
        "Not Before"              = $certificate.NotBefore
        "Public Key"              = $publicKey
        #"Raw Data"                = $rawData
        "Serial Number"           = $certificate.SerialNumber
        "Signature Algorithm"     = $certificate.SignatureAlgorithm.FriendlyName
        "Subject Name"            = $certificate.SubjectName.Name
        "Thumbprint"              = $certificate.Thumbprint
        "Version"                 = $certificate.Version
    }

    $details = @{
        "URL" = $url
        "certificateDetails" = $certificateDetails
        "TLS version" = $sslStream.SslProtocol.ToString()
    }

    $sslStream.Close()
    $tcpClient.Close()

    return $details
}

function Print-Details($url, $details) {
    Write-Host "`nURL: $url"
    Write-Host "Server certificate:"
    $details.'certificateDetails'.GetEnumerator() | ForEach-Object {
        Write-Host "$($_.Name): $($_.Value)"
    }
    Write-Host "TLS version: $($details.'TLS version')" -ForegroundColor red
}

# Now you can call the function with a list of URLs
$urls = 'https://www.google.com', 'https://grimoire.jamesfraze.com'
foreach($url in $urls){
    $details = Get-ServerCertificateAndTlsVersion $url
    Print-Details $url $details
}