# Author: Kerry Cordero # Version: 1.0.0 # Description: This script prompts for domain and gets the TLS version for that domain along with Cipher Suites import ssl import socket import warnings from termcolor import colored from prettytable import PrettyTable # Suppress deprecation warnings warnings.filterwarnings("ignore", category=DeprecationWarning) # Define a list of OpenSSL-style cipher suites CIPHER_SUITES = [ 'DHE-RSA-AES128-GCM-SHA256', 'DHE-RSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-RSA-CHACHA20-POLY1305', 'AES128-GCM-SHA256', 'AES256-GCM-SHA384', 'DHE-RSA-AES256-SHA256', 'ECDHE-RSA-AES128-SHA256', 'AES256-GCM-SHA384', 'AES128-GCM-SHA256', 'AES256-SHA256', 'AES128-SHA256' # You can add more cipher suites here... ] # Define TLS versions TLS_VERSIONS = { "TLSv1.0": ssl.PROTOCOL_TLSv1, "TLSv1.1": ssl.PROTOCOL_TLSv1_1, "TLSv1.2": ssl.PROTOCOL_TLSv1_2, "TLSv1.3": ssl.PROTOCOL_TLS } def check_cipher_suite_support(fqdn, port, cipher_suite, tls_version): context = ssl.SSLContext(tls_version) context.verify_mode = ssl.CERT_NONE try: context.set_ciphers(cipher_suite) except ssl.SSLError: # This can occur if the cipher suite is not compatible with the chosen TLS version return False try: with socket.create_connection((fqdn, port)) as sock: with context.wrap_socket(sock, server_hostname=fqdn) as ssock: return True except Exception as e: return False def main(): fqdn = input("Enter the FQDN: ") port = 443 # default port for HTTPS, change if necessary print(f"\nScanning {fqdn} for supported cipher suites...\n") # Create a table with TLS versions as columns table = PrettyTable() table.field_names = ["Cipher Suites"] + list(TLS_VERSIONS.keys()) # Fill the table with cipher suite support information for cipher_suite in CIPHER_SUITES: row = [cipher_suite] for tls_version_name, tls_version_protocol in TLS_VERSIONS.items(): is_supported = check_cipher_suite_support(fqdn, port, cipher_suite, tls_version_protocol) status = colored('✔️', 'green') if is_supported else colored('❌', 'red') row.append(status) table.add_row(row) print(table) if __name__ == "__main__": main()
I received an email from a Vendor stating they will no longer support some older 1.2 Cipher Suites and listed the Cipher suites they support:
The following TLSv1.3 cipher suites will be supported (suites in server-preferred order).
TLS_AES_128_GCM_SHA256 (0x1301)
TLS_AES_256_GCM_SHA384 (0x1302)
The following TLSv1.2 cipher suites will be supported (suites in server-preferred order).
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
The following TLSv1.2 cipher suites will no longer be supported.
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c)
TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d)
TLS_RSA_WITH_AES_128_CBC_SHA (0x2f)
TLS_RSA_WITH_AES_128_CBC_SHA256 (0x3c)
TLS_RSA_WITH_AES_256_CBC_SHA (0x35)
TLS_RSA_WITH_AES_256_CBC_SHA256 (0x3d)
In cases like this, you can just scan for those cipher suites:
CIPHER_SUITES = [ 'AES_128_GCM_SHA256', # TLSv1.3 'AES_256_GCM_SHA384', # TLSv1.3 'ECDHE_RSA_WITH_AES_256_GCM_SHA384', # TLSv1.2 'ECDHE_RSA_WITH_AES_128_GCM_SHA256', # TLSv1.2 'ECDHE_RSA_WITH_AES_256_CBC_SHA384', # TLSv1.2 (less preferred due to CBC mode) 'ECDHE_RSA_WITH_AES_128_CBC_SHA256' # TLSv1.2 (less preferred due to CBC mode) ]