Files
mukul975 c47eed6a64 Production hardening: security fixes, code quality, 724 skills complete
- Fix 25 shell=True subprocess calls with list-based commands
- Fix 49 verify=False in defensive skills (env-var override)
- Add timeout to 231 HTTP/subprocess/socket calls
- Fix 6 SQL injection patterns with whitelist validation
- Replace 8 __import__() with standard imports
- Remove 701 unused imports across 442 files
- Add authorized-testing disclaimers to all offensive skills
- Complete 11 incomplete skill directories
- Expand 10 stub SKILL.md files with full content
- Fix 2 YAML parse errors in frontmatter
- Fix 5 pre-existing syntax errors
- Convert 22 hardcoded paths/ports to environment variables
- Back up 21 redundant skill pairs to .bak
- Fix 2 global declaration errors
- 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE)
- 0 compile errors across all 724 agent.py files
2026-03-19 13:26:49 +01:00

141 lines
5.4 KiB
Python

#!/usr/bin/env python3
"""TLS 1.3 configuration audit agent using ssl and cryptography libraries."""
import json
import sys
import argparse
import ssl
import socket
from datetime import datetime
try:
from cryptography import x509
except ImportError:
print("Install: pip install cryptography")
sys.exit(1)
def check_tls_versions(host, port=443):
"""Check supported TLS versions on a server."""
results = {}
protocols = {
"TLSv1.0": ssl.TLSVersion.TLSv1 if hasattr(ssl.TLSVersion, 'TLSv1') else None,
"TLSv1.1": ssl.TLSVersion.TLSv1_1 if hasattr(ssl.TLSVersion, 'TLSv1_1') else None,
"TLSv1.2": ssl.TLSVersion.TLSv1_2,
"TLSv1.3": ssl.TLSVersion.TLSv1_3,
}
for version_name, version in protocols.items():
if version is None:
results[version_name] = {"supported": False, "note": "Not available in this Python build"}
continue
try:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
ctx.minimum_version = version
ctx.maximum_version = version
with socket.create_connection((host, port), timeout=5) as sock:
with ctx.wrap_socket(sock, server_hostname=host) as ssock:
results[version_name] = {
"supported": True,
"cipher": ssock.cipher()[0],
"severity": "CRITICAL" if "1.0" in version_name or "1.1" in version_name else "INFO",
}
except (ssl.SSLError, ConnectionRefusedError, socket.timeout, OSError):
results[version_name] = {"supported": False}
return results
def get_certificate_info(host, port=443):
"""Retrieve and analyze server certificate."""
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
try:
with socket.create_connection((host, port), timeout=5) as sock:
with ctx.wrap_socket(sock, server_hostname=host) as ssock:
der_cert = ssock.getpeercert(binary_form=True)
cert = x509.load_der_x509_certificate(der_cert)
days_remaining = (cert.not_valid_after_utc.replace(tzinfo=None) - datetime.utcnow()).days
return {
"subject": cert.subject.rfc4514_string(),
"issuer": cert.issuer.rfc4514_string(),
"not_after": str(cert.not_valid_after_utc),
"days_remaining": days_remaining,
"key_size": cert.public_key().key_size,
"signature_algorithm": cert.signature_hash_algorithm.name if cert.signature_hash_algorithm else "unknown",
"issues": [],
}
except Exception as e:
return {"error": str(e)}
def check_cipher_suites(host, port=443):
"""Check negotiated cipher suites."""
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
try:
with socket.create_connection((host, port), timeout=5) as sock:
with ctx.wrap_socket(sock, server_hostname=host) as ssock:
cipher = ssock.cipher()
return {
"negotiated_cipher": cipher[0],
"protocol": cipher[1],
"bits": cipher[2],
"tls13_ciphers": ["TLS_AES_256_GCM_SHA384", "TLS_AES_128_GCM_SHA256",
"TLS_CHACHA20_POLY1305_SHA256"],
}
except Exception as e:
return {"error": str(e)}
def run_audit(host, port=443):
"""Execute TLS 1.3 configuration audit."""
print(f"\n{'='*60}")
print(f" TLS 1.3 CONFIGURATION AUDIT")
print(f" Target: {host}:{port}")
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
print(f"{'='*60}\n")
versions = check_tls_versions(host, port)
print(f"--- TLS VERSION SUPPORT ---")
for ver, info in versions.items():
status = "SUPPORTED" if info.get("supported") else "NOT SUPPORTED"
sev = info.get("severity", "")
print(f" {ver}: {status} {f'[{sev}]' if sev else ''}")
cert = get_certificate_info(host, port)
print(f"\n--- CERTIFICATE ---")
if "error" not in cert:
print(f" Subject: {cert['subject']}")
print(f" Issuer: {cert['issuer']}")
print(f" Expires: {cert['not_after']} ({cert['days_remaining']} days)")
print(f" Key size: {cert['key_size']}")
cipher = check_cipher_suites(host, port)
print(f"\n--- CIPHER SUITE ---")
if "error" not in cipher:
print(f" Negotiated: {cipher['negotiated_cipher']}")
print(f" Protocol: {cipher['protocol']}")
return {"versions": versions, "certificate": cert, "cipher": cipher}
def main():
parser = argparse.ArgumentParser(description="TLS 1.3 Audit Agent")
parser.add_argument("--host", required=True, help="Target hostname")
parser.add_argument("--port", type=int, default=443, help="Target port")
parser.add_argument("--output", help="Save report to JSON file")
args = parser.parse_args()
report = run_audit(args.host, args.port)
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"\n[+] Report saved to {args.output}")
if __name__ == "__main__":
main()