network security

Performing SSL/TLS Security Assessment

Assess SSL/TLS server configurations using the sslyze Python library to evaluate cipher suites, certificate chains, protocol versions, HSTS headers, and known vulnerabilities like Heartbleed and ROBOT.

certificatecipher-suitesnetwork-securitysslsslyzetlsvulnerability-assessment
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

Assess SSL/TLS server configurations using sslyze, a fast Python-based scanning library. This skill covers evaluating supported protocol versions (SSLv2/3, TLS 1.0-1.3), cipher suite strength, certificate chain validation, HSTS enforcement, OCSP stapling, and scanning for known vulnerabilities including Heartbleed, ROBOT, and session renegotiation weaknesses.

When to Use

  • When conducting security assessments that involve performing ssl tls security assessment
  • When following incident response procedures for related security events
  • When performing scheduled security testing or auditing activities
  • When validating security controls through hands-on testing

Prerequisites

  • Python 3.9+ with sslyze library (pip install sslyze)
  • Network access to target HTTPS servers on port 443
  • Understanding of TLS protocol versions and cipher suite classifications

Steps

Step 1: Configure Server Scan

Create ServerScanRequest with ServerNetworkLocation specifying target hostname and port.

Step 2: Execute TLS Scan

Use sslyze Scanner to queue and execute scans for all TLS check commands concurrently.

Step 3: Analyze Results

Evaluate accepted cipher suites, certificate validity, protocol versions, and vulnerability scan results.

Step 4: Generate Security Report

Produce a JSON report with compliance findings and remediation recommendations.

Expected Output

JSON report with supported protocols, accepted cipher suites, certificate details, vulnerability results (Heartbleed, ROBOT), and HSTS status.

Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 1

api-reference.md1.9 KB

API Reference: Performing SSL/TLS Security Assessment

sslyze Python API

from sslyze import Scanner, ServerScanRequest, ServerNetworkLocation
 
location = ServerNetworkLocation(hostname="example.com", port=443)
request = ServerScanRequest(server_location=location)
scanner = Scanner()
scanner.queue_scans([request])
 
for result in scanner.get_results():
    scan = result.scan_result
    # Access individual scan command results
    tls12 = scan.tls_1_2_cipher_suites
    cert = scan.certificate_info
    heartbleed = scan.heartbleed

Install: pip install sslyze

Scan Command Attributes

Attribute Check
ssl_2_0_cipher_suites SSLv2 support (must be disabled)
ssl_3_0_cipher_suites SSLv3 support (must be disabled)
tls_1_0_cipher_suites TLS 1.0 (deprecated)
tls_1_1_cipher_suites TLS 1.1 (deprecated)
tls_1_2_cipher_suites TLS 1.2 (current)
tls_1_3_cipher_suites TLS 1.3 (recommended)
certificate_info Certificate chain validation
heartbleed CVE-2014-0160 Heartbleed
robot ROBOT RSA oracle attack
openssl_ccs_injection CVE-2014-0224
session_renegotiation Client-initiated renego

Weak Cipher Suite Keywords

Keyword Risk Description
RC4 High Broken stream cipher
DES / 3DES High Weak block cipher
NULL Critical No encryption
EXPORT Critical Weak export-grade cipher
anon Critical No authentication

sslyze CLI

sslyze example.com --regular
sslyze example.com --certinfo --tlsv1_2 --heartbleed --robot
sslyze example.com --json_out results.json

References

Scripts 1

agent.py7.7 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Agent for performing SSL/TLS security assessment using sslyze.

Scans TLS server configurations to evaluate cipher suites,
protocol versions, certificate chains, HSTS, and known
vulnerabilities like Heartbleed and ROBOT.
"""

import argparse
import json
import os
from datetime import datetime
from pathlib import Path

try:
    from sslyze import (
        Scanner,
        ServerScanRequest,
        ServerNetworkLocation,
        ScanCommand,
        ScanCommandAttemptStatusEnum,
    )
except ImportError:
    Scanner = None


WEAK_CIPHERS_KEYWORDS = ["RC4", "DES", "3DES", "NULL", "EXPORT", "anon"]


class SSLTLSAssessmentAgent:
    """Assesses SSL/TLS configurations using sslyze."""

    def __init__(self, output_dir="./ssl_tls_assessment"):
        self.output_dir = Path(output_dir)
        self.output_dir.mkdir(parents=True, exist_ok=True)
        self.findings = []

    def scan_server(self, hostname, port=443):
        """Run full sslyze scan against a target server."""
        if Scanner is None:
            return {"error": "sslyze not installed: pip install sslyze"}

        location = ServerNetworkLocation(hostname=hostname, port=port)
        scan_request = ServerScanRequest(server_location=location)
        scanner = Scanner()
        scanner.queue_scans([scan_request])

        for result in scanner.get_results():
            return self._process_result(result, hostname, port)
        return {"error": "No scan results returned"}

    def _process_result(self, result, hostname, port):
        """Process sslyze ServerScanResult into structured findings."""
        report = {"hostname": hostname, "port": port, "protocols": {},
                  "cipher_suites": {}, "certificate": {}, "vulnerabilities": {}}

        protocol_checks = [
            ("ssl_2_0_cipher_suites", "SSLv2"),
            ("ssl_3_0_cipher_suites", "SSLv3"),
            ("tls_1_0_cipher_suites", "TLS 1.0"),
            ("tls_1_1_cipher_suites", "TLS 1.1"),
            ("tls_1_2_cipher_suites", "TLS 1.2"),
            ("tls_1_3_cipher_suites", "TLS 1.3"),
        ]

        scan = result.scan_result
        for attr, proto_name in protocol_checks:
            attempt = getattr(scan, attr, None)
            if attempt and attempt.status == ScanCommandAttemptStatusEnum.COMPLETED:
                ciphers = attempt.result
                accepted = [c.cipher_suite.name for c in ciphers.accepted_cipher_suites]
                report["protocols"][proto_name] = len(accepted) > 0
                report["cipher_suites"][proto_name] = accepted

                if proto_name in ("SSLv2", "SSLv3"):
                    if accepted:
                        self.findings.append({
                            "severity": "critical", "type": "Deprecated Protocol",
                            "detail": f"{proto_name} enabled with {len(accepted)} cipher suites",
                        })
                elif proto_name in ("TLS 1.0", "TLS 1.1"):
                    if accepted:
                        self.findings.append({
                            "severity": "high", "type": "Legacy Protocol",
                            "detail": f"{proto_name} still enabled",
                        })

                for cipher_name in accepted:
                    if any(weak in cipher_name for weak in WEAK_CIPHERS_KEYWORDS):
                        self.findings.append({
                            "severity": "high", "type": "Weak Cipher Suite",
                            "detail": f"{cipher_name} accepted on {proto_name}",
                        })

        cert_attempt = getattr(scan, "certificate_info", None)
        if cert_attempt and cert_attempt.status == ScanCommandAttemptStatusEnum.COMPLETED:
            cert_result = cert_attempt.result
            for deployment in cert_result.certificate_deployments:
                leaf = deployment.received_certificate_chain[0]
                report["certificate"] = {
                    "subject": leaf.subject.rfc4514_string(),
                    "issuer": leaf.issuer.rfc4514_string(),
                    "not_before": leaf.not_valid_before_utc.isoformat(),
                    "not_after": leaf.not_valid_after_utc.isoformat(),
                    "serial": str(leaf.serial_number),
                    "signature_algorithm": leaf.signature_hash_algorithm.name
                        if leaf.signature_hash_algorithm else "unknown",
                    "chain_valid": deployment.verified_certificate_chain is not None,
                    "ocsp_stapling": deployment.ocsp_response is not None,
                }
                if leaf.not_valid_after_utc < datetime.utcnow():
                    self.findings.append({
                        "severity": "critical", "type": "Expired Certificate",
                        "detail": f"Certificate expired on {leaf.not_valid_after_utc}",
                    })
                if leaf.signature_hash_algorithm and leaf.signature_hash_algorithm.name == "sha1":
                    self.findings.append({
                        "severity": "high", "type": "SHA-1 Certificate",
                        "detail": "Certificate uses SHA-1 signature",
                    })

        vuln_checks = [
            ("heartbleed", "Heartbleed", "is_vulnerable_to_heartbleed"),
            ("openssl_ccs_injection", "CCS Injection", "is_vulnerable_to_ccs_injection"),
        ]
        for attr, name, field in vuln_checks:
            attempt = getattr(scan, attr, None)
            if attempt and attempt.status == ScanCommandAttemptStatusEnum.COMPLETED:
                vulnerable = getattr(attempt.result, field, False)
                report["vulnerabilities"][name] = vulnerable
                if vulnerable:
                    self.findings.append({
                        "severity": "critical", "type": f"{name} Vulnerable",
                        "detail": f"Server is vulnerable to {name}",
                    })

        robot_attempt = getattr(scan, "robot", None)
        if robot_attempt and robot_attempt.status == ScanCommandAttemptStatusEnum.COMPLETED:
            robot_result = robot_attempt.result
            is_vuln = "VULNERABLE" in str(robot_result.robot_result)
            report["vulnerabilities"]["ROBOT"] = is_vuln
            if is_vuln:
                self.findings.append({
                    "severity": "critical", "type": "ROBOT Vulnerable",
                    "detail": "Server is vulnerable to ROBOT attack",
                })

        return report

    def generate_report(self, targets):
        """Scan multiple targets and generate consolidated report."""
        results = []
        for target in targets:
            parts = target.split(":")
            hostname = parts[0]
            port = int(parts[1]) if len(parts) > 1 else 443
            results.append(self.scan_server(hostname, port))

        report = {
            "report_date": datetime.utcnow().isoformat(),
            "targets_scanned": len(targets),
            "scan_results": results,
            "findings": self.findings,
            "total_findings": len(self.findings),
        }
        out = self.output_dir / "ssl_tls_assessment_report.json"
        with open(out, "w") as f:
            json.dump(report, f, indent=2, default=str)
        print(json.dumps(report, indent=2, default=str))
        return report


def main():
    parser = argparse.ArgumentParser(
        description="Assess SSL/TLS server configurations using sslyze"
    )
    parser.add_argument("targets", nargs="+", help="Target host:port (e.g. example.com:443)")
    parser.add_argument("--output-dir", default="./ssl_tls_assessment")
    args = parser.parse_args()

    os.makedirs(args.output_dir, exist_ok=True)
    agent = SSLTLSAssessmentAgent(output_dir=args.output_dir)
    agent.generate_report(args.targets)


if __name__ == "__main__":
    main()
Keep exploring