mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-15 23:44:56 +03:00
c47eed6a64
- 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
141 lines
5.4 KiB
Python
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()
|