Test Your SSL Servers From Within PowerShell

If you read my blog or follow my GitHub account, you’re likely to have seen I’ve recently released a .NET library which is a wrapper for the SSL Labs assessment Api’s. These Api’s allow the consumer to test their public facing SSL services to detect any configuration issues like certificate chain incomplete, Heartbleed vulnerable, etc.

So why am I mentioning this wrapper again? Well let me explain.

While we were preforming out out of hours maintenance to replace the SSL certificates on our load balancers, I found myself constantly jumping to my browser to run a fresh assessment of our SSL hosts using SSL Labs. As you can imagine even with a great testing tool such as SSL Labs the process became laborious and just didn’t scale that well (i.e opening multiple scans using multiple browser tabs). I therefore saw this as another great opportunity to use my SSL Labs Api Wrapper (previously called SSLLWrapper) as well as improving our process using automation.

Welcome ExternalSSLTester.ps1

ExternalSSLTester.ps1 is written to analyse a host as well as its endpoints and then return this information back to you. The script can also take a list of multiple hosts to ease the life of an IT administrators or DevOps engineer.

#######################################################################

# Written by Ashley Poole  -  http://www.ashleypoole.co.uk            #

#                                                                     #

# Checks servers SSL implementation for the given host(s).            #

# This is achieved by consuming SSL Labs Assessment Api Via           #

# SSLLabs Api Wrapper                                                 #

#######################################################################


#region Construction

Param
(
	[Parameter(Mandatory=$false)]
	[ValidateNotNullOrEmpty()]
	[String]
	[alias("host")]
	$hostInput,

	[Parameter(Mandatory=$false)]
	[ValidateNotNullOrEmpty()]
	[String]
	[alias("hosts")]
	$hostsInput,

	[Parameter(Mandatory=$false)]
	[ValidateNotNullOrEmpty()]
	[Bool]
	[alias("endpointdetails")]
	$WriteEndpointDetails
)

# Validating and loading inputs

If (($hostInput) -or ($hostsInput))
{
    If ($hostsInput)
    {
        $Hosts = Get-Content ($PSScriptRoot.ToString() + "\Hosts.txt")
    }
    Else
    {
        $Hosts = @($hostInput)
    }
}
Else
{
    Write-Host "ERROR: No values for host(s) were specified!`r`nSee README files for details on input parameters." -ForegroundColor Red
    Exit
}

# Variables

$SSLLabsApiUrl = "https://api.dev.ssllabs.com/api/fa78d5a4/"

$SSLLWrapperFilePath = $PSScriptRoot.ToString() + "\SSLLWrapper\SSLLWrapper.dll"
$NewtonsoftJsonFilePath = $PSScriptRoot.ToString() + "\SSLLWrapper\NewtonSoft.Json.dll"

# Loading DLLs

Add-Type -Path $NewtonsoftJsonFilePath -ErrorAction Stop
Add-Type -Path $SSLLWrapperFilePath -ErrorAction Stop

# Creating SSLLService

$SSLService = New-Object SSLLWrapper.SSLLService($SSLLabsApiUrl)

#endregion


#region Functions

Function ToBooleanString($value)
{
    return [System.Convert]::ToBoolean($value).ToString()
}

#endregion


clear
Write-Host "`n"
Write-Host "Starting analysis... This process may take several minutes per endpoint, per host..."
Write-Host "`n"

# Testing if Api is online

$ApiInfo = $SSLService.Info()

If ($ApiInfo.Online -ne $true)
{
    # Api is not online. Exiting.

    Write-Host "Api " $SSLLabsApiUrl " is not online, contactable or is incorrect.`r`nExiting." -ForegroundColor Red
    Exit
}

Foreach ($myHost In $Hosts)
{
    # Analysising host with a maximum of a 5 minute wait time

    #$HostAnalysis = $SSLService.AutomaticAnalyze($myHost, 500, 10)

    $HostAnalysis = $SSLService.AutomaticAnalyze($myHost, [SSLLWrapper.SSLLService+Publish]::Off, [SSLLWrapper.SSLLService+ClearCache]::Ignore, [SSLLWrapper.SSLLService+FromCache]::On,[SSLLWrapper.SSLLService+All]::On,500,10)

    Write-Host "**********************************************************************************"
    Write-Host $myHost " - " (Get-Date -format "dd-MM-yyyy HH:mm:ss")
    Write-Host "**********************************************************************************"
    Write-Host "Endpoints #           :" ($HostAnalysis.endpoints).Count
    Write-Host "Analysis Error        :" $HostAnalysis.HasErrorOccurred
    Write-Host "`n"

    Foreach ($Endpoint In $HostAnalysis.endpoints)
    {
        Write-Host "Endpoint              :" $Endpoint.ipAddress

        Write-Host "Grade                 :" $Endpoint.grade
        Write-Host "Has Warnings          :" $Endpoint.hasWarnings

        # Output extra details if EndpointDetails is true and analysis data is good (i.e check grade exists)
        If (($WriteEndpointDetails) -and ($Endpoint.grade))
        {
            $EndpointAnalysis = $SSLService.GetEndpointData($HostAnalysis.host, $Endpoint.ipAddress)

            Write-Host "Server Signature      :" $EndpointAnalysis.Details.serverSignature
            Write-Host "Cert Chain Issue      :" $EndpointAnalysis.Details.chain.issues
            Write-Host "Forward Secrecy       :" $EndpointAnalysis.Details.forwardSecrecy
            Write-Host "Supports RC4          :" $EndpointAnalysis.Details.supportsRc4
            Write-Host "Beast Vulnerable      :" $EndpointAnalysis.Details.vulnBeast
            Write-Host "Heartbleed Vulnerable :" $EndpointAnalysis.Details.heartbleed
            Write-Host "Poodle Vulnerable     :" $EndpointAnalysis.Details.poodleTls

       }
       Write-Host "`n"
    }
    Write-Host "`r`n"
}

Note - the script currently uses the development SSL Labs Api as it hasn’t currently been released for production use yet.

Usage

Here is a copy of the ReadMe file for ExternalSSLTester that describes the usage information.

About

This PowerShell script can be used to check the SSL implementations of any public facing server. To achieve this, the script consumes the SSL Labs Assessment Api using a .NET library called SSL Labs Api Wrapper (previously called SSLLWrapper). This wrapper is also written by myself and can be found at GitHub, NuGet or My Website.

Usage

ExternalSSLTester.ps1 can be invoked for use with a single host or a predefined selection of hosts which are passed in as a file path. Below are examples of both options: Single Host ExternalSSLTester.ps1 https://www.ashleypoole.co.uk ExternalSSLTester.ps1 -host https://www.ashleypoole.co.uk Multiple Hosts ExternalSSLTester.ps1 -hosts "C:\HostsToCheck.txt" Detailed Output The script can also be instructed to give a more detailed output for a host's endpoints by using the 'details' parameter. Examples below: ExternalSSLTester.ps1 https://www.ashleypoole.co.uk -endpointdetails $True ExternalSSLTester.ps1 -host https://www.ashleypoole.co.uk -endpointdetails $True

I’ve uploaded the script to my PowerShell tools repository on GitHub where you can also find the required DLL’s. Feel free to fork the repository and create pull requests for any improvements to share with the community or comment on this post.

Posted in Programming, DevOps, Security with : PowerShell, SSL