Made suggested changes

1. changed the date format from "%Y/%m/%d" to "%Y-%m-%d" to make it ANSI and ISO 8601 compliant.

2. Changed the issuer and subject to issuer_str and subject_str which are formatted string from the x509 objects.

3. Added subject to  ssl_expired_certificate_vuln and ssl_expiring_certificate_scan modules
This commit is contained in:
Captain-T2004 2024-09-01 18:03:29 +05:30
parent 3dd57520bb
commit 97eb4f9c4c
4 changed files with 75 additions and 33 deletions

View File

@ -130,18 +130,24 @@ def create_tcp_socket(host, port, timeout):
def get_cert_info(cert): def get_cert_info(cert):
x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert) x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
weak_signing_algo = is_weak_hash_algo(str(x509.get_signature_algorithm())) weak_signing_algo = is_weak_hash_algo(str(x509.get_signature_algorithm()))
cert_activation = datetime.strptime(x509.get_notBefore().decode("utf-8"), "%Y%m%d%H%M%S%z")
cert_expires = datetime.strptime(x509.get_notAfter().decode("utf-8"), "%Y%m%d%H%M%S%z") cert_expires = datetime.strptime(x509.get_notAfter().decode("utf-8"), "%Y%m%d%H%M%S%z")
cert_activation = datetime.strptime(x509.get_notBefore().decode("utf-8"), "%Y%m%d%H%M%S%z")
issuer_str = ", ".join(
f"{name.decode()}={value.decode()}" for name, value in x509.get_issuer().get_components()
)
subject_str = ", ".join(
f"{name.decode()}={value.decode()}" for name, value in x509.get_subject().get_components()
)
return { return {
"expired": x509.has_expired(), "expired": x509.has_expired(),
"self_signed": x509.get_issuer() == x509.get_subject(), "self_signed": issuer_str == subject_str,
"issuer": str(x509.get_issuer()), "issuer": issuer_str,
"subject": str(x509.get_subject()), "subject": subject_str,
"signing_algo": str(x509.get_signature_algorithm()), "signing_algo": str(x509.get_signature_algorithm()),
"weak_signing_algo": weak_signing_algo, "weak_signing_algo": weak_signing_algo,
"activation_date": cert_activation.strftime("%Y/%m/%d"), "activation_date": cert_activation.strftime("%Y-%m-%d"),
"not_activated": (cert_activation - datetime.now(timezone.utc)).days > 0, "not_activated": (cert_activation - datetime.now(timezone.utc)).days > 0,
"expiration_date": cert_expires.strftime("%Y/%m/%d"), "expiration_date": cert_expires.strftime("%Y-%m-%d"),
"expiring_soon": (cert_expires - datetime.now(timezone.utc)).days < 30, "expiring_soon": (cert_expires - datetime.now(timezone.utc)).days < 30,
} }

View File

@ -27,6 +27,8 @@ payloads:
- 8080 - 8080
response: response:
condition_type: or condition_type: or
subject:
reverse: false
conditions: conditions:
grouped_conditions: grouped_conditions:
condition_type: and condition_type: and

View File

@ -28,6 +28,8 @@ payloads:
response: response:
condition_type: or condition_type: or
conditions: conditions:
subject:
reverse: false
grouped_conditions_1: grouped_conditions_1:
condition_type: and condition_type: and
conditions: conditions:

View File

@ -24,10 +24,30 @@ class MockConnectionObject:
return self.Version return self.Version
class SubjectObject:
def __init__(self, subject="subject"):
self.subject = subject
def get_components(self):
return [
(b"component", str.encode(self.subject)),
]
class IssuerObject:
def __init__(self, issuer="issuer"):
self.issuer = issuer
def get_components(self):
return [
(b"component", str.encode(self.issuer)),
]
class Mockx509Object: class Mockx509Object:
def __init__(self, issuer, subject, is_expired, expire_date, activation_date, signing_algo): def __init__(self, issuer, subject, is_expired, expire_date, activation_date, signing_algo):
self.issuer = issuer self.issuer = IssuerObject(issuer)
self.subject = subject self.subject = SubjectObject(subject)
self.expired = is_expired self.expired = is_expired
self.expire_date = expire_date self.expire_date = expire_date
self.activation_date = activation_date self.activation_date = activation_date
@ -57,26 +77,28 @@ class Responses:
"ssl_version": ["TLSv1"], "ssl_version": ["TLSv1"],
"weak_version": True, "weak_version": True,
"ssl_flag": True, "ssl_flag": True,
"issuer": "test_issuer", "issuer": "NA",
"subject": "test_subject", "subject": "NA",
"expiration_date": "2100/12/07", "expiration_date": "NA",
} }
ssl_certificate_expired = { ssl_certificate_expired = {
"expired": True, "expired": True,
"expiration_date": "2023/12/07", "expiration_date": "2023-12-07",
"subject": "component=subject",
"not_activated": False, "not_activated": False,
"activation_date": "2023/12/07", "activation_date": "2023-12-07",
"expiring_soon": True, "expiring_soon": True,
"ssl_flag": True, "ssl_flag": True,
} }
ssl_certificate_deactivated = { ssl_certificate_deactivated = {
"expired": False, "expired": False,
"expiration_date": "2100/12/07", "expiration_date": "2100-12-07",
"expiring_soon": False, "expiring_soon": False,
"not_activated": True, "not_activated": True,
"activation_date": "2100/12/07", "activation_date": "2100-12-07",
"subject": "component=subject",
"ssl_flag": True, "ssl_flag": True,
} }
@ -103,16 +125,18 @@ class Substeps:
}, },
} }
ssl_expired_certificate_scan = { ssl_certificate_expired_vuln = {
"method": "ssl_certificate_scan", "method": "ssl_certificate_scan",
"response": { "response": {
"condition_type": "or", "condition_type": "or",
"conditions": { "conditions": {
"subject": {"reverse": False},
"grouped_conditions_1": { "grouped_conditions_1": {
"condition_type": "and", "condition_type": "and",
"conditions": { "conditions": {
"expired": {"reverse": False}, "expired": {"reverse": False},
"expiration_date": {"reverse": False}, "expiration_date": {"reverse": False},
"subject": {"reverse": False},
}, },
}, },
"grouped_conditions_2": { "grouped_conditions_2": {
@ -120,6 +144,7 @@ class Substeps:
"conditions": { "conditions": {
"not_activated": {"reverse": False}, "not_activated": {"reverse": False},
"activation_date": {"reverse": False}, "activation_date": {"reverse": False},
"subject": {"reverse": False},
}, },
}, },
}, },
@ -210,6 +235,7 @@ class TestSocketMethod(TestCase):
PORT = 80 PORT = 80
TIMEOUT = 60 TIMEOUT = 60
# TESTING AGAINST A CORRECT CERTIFICATE
mock_hash_check.return_value = False mock_hash_check.return_value = False
mock_connection.return_value = (MockConnectionObject(HOST, "TLSv1.3"), True) mock_connection.return_value = (MockConnectionObject(HOST, "TLSv1.3"), True)
mock_x509.return_value = Mockx509Object( mock_x509.return_value = Mockx509Object(
@ -228,18 +254,19 @@ class TestSocketMethod(TestCase):
"ssl_flag": True, "ssl_flag": True,
"service": "http", "service": "http",
"self_signed": False, "self_signed": False,
"issuer": "test_issuer", "issuer": "component=test_issuer",
"subject": "test_subject", "subject": "component=test_subject",
"expiring_soon": False, "expiring_soon": False,
"expiration_date": "2100/12/07", "expiration_date": "2100-12-07",
"not_activated": False, "not_activated": False,
"activation_date": "2023/12/07", "activation_date": "2023-12-07",
"signing_algo": "test_algo", "signing_algo": "test_algo",
"weak_signing_algo": False, "weak_signing_algo": False,
"peer_name": "example.com", "peer_name": "example.com",
}, },
) )
# TESTING AGAINST A SELF-SIGNED CERTIFICATE
mock_hash_check.return_value = True mock_hash_check.return_value = True
mock_connection.return_value = (MockConnectionObject(HOST, "TLSv1.3"), True) mock_connection.return_value = (MockConnectionObject(HOST, "TLSv1.3"), True)
mock_x509.return_value = Mockx509Object( mock_x509.return_value = Mockx509Object(
@ -257,18 +284,19 @@ class TestSocketMethod(TestCase):
"ssl_flag": True, "ssl_flag": True,
"service": "http", "service": "http",
"self_signed": True, "self_signed": True,
"issuer": "test_issuer_subject", "issuer": "component=test_issuer_subject",
"subject": "test_issuer_subject", "subject": "component=test_issuer_subject",
"expiring_soon": False, "expiring_soon": False,
"expiration_date": "2100/12/07", "expiration_date": "2100-12-07",
"not_activated": True, "not_activated": True,
"activation_date": "2100/12/07", "activation_date": "2100-12-07",
"signing_algo": "test_algo", "signing_algo": "test_algo",
"weak_signing_algo": True, "weak_signing_algo": True,
"peer_name": "example.com", "peer_name": "example.com",
}, },
) )
# TESTING IF ssl_flag is False
mock_connection.return_value = (MockConnectionObject(HOST), False) mock_connection.return_value = (MockConnectionObject(HOST), False)
self.assertEqual( self.assertEqual(
library.ssl_certificate_scan(HOST, PORT, TIMEOUT), library.ssl_certificate_scan(HOST, PORT, TIMEOUT),
@ -362,20 +390,24 @@ class TestSocketMethod(TestCase):
Substep = Substeps() Substep = Substeps()
Response = Responses() Response = Responses()
# ssl_certificate_scan_expired # ssl_certificate_expired_vuln
self.assertEqual( self.assertEqual(
engine.response_conditions_matched( engine.response_conditions_matched(
Substep.ssl_expired_certificate_scan, Response.ssl_certificate_expired Substep.ssl_certificate_expired_vuln, Response.ssl_certificate_expired
), ),
{"expired": True, "expiration_date": "2023/12/07"}, {"subject": "component=subject", "expired": True, "expiration_date": "2023-12-07"},
) )
# ssl_certificate_scan_not_activated # ssl_certificate_expired_vuln(not activated)
self.assertEqual( self.assertEqual(
engine.response_conditions_matched( engine.response_conditions_matched(
Substep.ssl_expired_certificate_scan, Substep.ssl_certificate_expired_vuln,
Response.ssl_certificate_deactivated, Response.ssl_certificate_deactivated,
), ),
{"not_activated": True, "activation_date": "2100/12/07"}, {
"subject": "component=subject",
"not_activated": True,
"activation_date": "2100-12-07",
},
) )
# ssl_weak_version_vuln # ssl_weak_version_vuln
@ -386,9 +418,9 @@ class TestSocketMethod(TestCase):
{ {
"weak_version": True, "weak_version": True,
"ssl_version": ["TLSv1"], "ssl_version": ["TLSv1"],
"issuer": "test_issuer", "issuer": "NA",
"subject": "test_subject", "subject": "NA",
"expiration_date": "2100/12/07", "expiration_date": "NA",
}, },
) )