rajquest
rajquest

Reputation: 711

How to scan and verify the version of TLS for a website?

How to scan and verify the version of TLS for a website?

I was hunting for solutions which can automatically scan all the endpoint website domain in our company. SSL Labs had a manual online solution

https://www.ssllabs.com/ssltest/index.html

How can this feature be achieved programmatically?

Upvotes: 1

Views: 2593

Answers (3)

Evaldas Jocys
Evaldas Jocys

Reputation: 319

I had same issue. Created free and open-source project on GitHub https://github.com/JocysCom/SslScanner, which contains:

  • Portable standalone SSL, TLS, STARTTLS Scanner Tool.
  • /Tool/Common/Test_SSL_Support.cs - C# code which will check SSL/TLS version
  • /Tool/Common/Test_SSL_Support.bat - simple batch script which runs C# like a script on Windows Command Line. Note: I use PowerShell and Batch on Windows to run C# like a scripting language in order to automate tons of stuff.

Test_SSL_Support.cs have 'TestTCP' method which returns 'true' if connection supports specified protocol version:

static bool TestTCP(string host, int port, SslProtocols protocol, out bool connected)
{
    var success = false;
    var client = new TcpClient();
    var asyncResult = client.BeginConnect(host, port, null, null);
    // 5 seconds timeout.
    connected = asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5));
    // Connected.
    if (connected)
    {
        var stream = client.GetStream();
        // Don't dispose underlying stream.
        using (var sslStream = new SslStream(stream, true, ValidateServerCertificate))
        {
            sslStream.ReadTimeout = 15000;
            sslStream.WriteTimeout = 15000;
            sslStream.AuthenticateAsClient(host, null, protocol, false);
            result.UpdateFromSslStream(sslStream);
            success = true;
        }
        client.EndConnect(asyncResult);
    }
    return success;
}

Test_SSL_Support.cs supports StartTLS protocol too. Look for method:

static bool TestStarTLS(string host, int port, SslProtocols protocol, out bool connected)

You can add multiple hosts and ports to Test_SSL_Support.bat for scan:

:: Test SSL/TLS.
CALL:PS www.google.com 443
:: Test StartTLS.
CALL:PS mail.jocys.com 110

Command line results are represented as:

172.217.169.4 www.google.com:443

  Ssl2  = False | The client and server cannot communicate, because they do not possess a common algorithm
  Ssl3  = False | The client and server cannot communicate, because they do not possess a common algorithm
  Tls   = True  | Exchange = ECC-256 | Cipher = AES128 | Hash = SHA1
  Tls11 = True  | Exchange = ECC-256 | Cipher = AES128 | Hash = SHA1
  Tls12 = True  | Exchange = ECC-256 | Cipher = AES128 | Hash = SHA256
  Tls13 = True  | Exchange = ECC-256 | Cipher = AES256 | Hash = SHA384

62.30.149.144 mail.jocys.com:110

  Ssl2  = False | The client and server cannot communicate, because they do not possess a common algorithm
  Ssl3  = False | The client and server cannot communicate, because they do not possess a common algorithm
  Tls   = False | Authentication failed because the remote party has closed the transport stream.
  Tls11 = False | Authentication failed because the remote party has closed the transport stream.
  Tls12 = True  | Exchange = ECC-384 | Cipher = AES256 | Hash = SHA384
  Tls13 = False | Authentication failed because the remote party has closed the transport stream.

Upvotes: 1

John Wu
John Wu

Reputation: 52250

Use HttpClient... force it to use TLS 1.2... see if it fails... profit.

public async Task<bool> SupportsTls12(string url)
{
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    var client = new HttpClient();
    try
    {
        var response = await client.GetAsync(url);
        return true;
    }
    catch(HttpRequestException)
    {
        return false;
    }
}

If you find this gives you false positive/negatives, you may have to modify the exception handler to inspect the specific error that is returned. But this is the general idea.

Upvotes: 0

rajquest
rajquest

Reputation: 711

SSLLabsAPI seems to work

using SslLabsLib.Enums;
using SslLabsLib;

public static void TLSChecker(string urlString)
{

    SslLabsClient client = new SslLabsClient();                                 
    // Get ipaddress and host
    var analysis = client.GetAnalysis(urlString, 24, AnalyzeOptions.Publish);
    Console.WriteLine(analysis.Host);            

    foreach (var item in analysis.Endpoints)
    {
        Console.WriteLine(item.IpAddress);

       var endpointanalysis = client.GetCachedEndpointAnalysis(analysis.Host, IPAddress.Parse(item.IpAddress));

        // get protocol list
        foreach (var protocol in endpointanalysis.Details.Protocols)
        {
            Console.WriteLine(protocol.Id);
            Console.WriteLine(protocol.Name);
            Console.WriteLine(protocol.Version);                    
        }                

    }

Upvotes: 0

Related Questions