Skip to content

Commit

Permalink
Improve compliance module analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
Odinmylord committed May 13, 2024
1 parent 70da213 commit 2156631
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 13 deletions.
2 changes: 1 addition & 1 deletion configs/mitigations/COMPLIANCE_CIPHERSUITESTLS1.3.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"Extended Name": "Compliance report for Cipher Suites supported by TLS 1.3",
"Description": "Compliance report for {sheet} against {guidelines} guidelines",
"Mitigation": {
"Textual": "Add the following cipher suites to the server configuration:{add}<br/>Remove the following cipher suites from the server configuration:{remove}",
"Textual": "Add the following cipher suites to the server configuration:{add}<br/>Remove the following cipher suites from the server configuration:{remove}<br/> If TLS 1.3 is not enabled the tool can not check the compliance of the cipher suites mentioned above.",
"Apache": "<p>- <b>Quick solution</b>: replace the instruction of the directive <code>SSLOpenSSLConfCmd Ciphersuites</code> with the following string:<br/> {total_string}<br/>- <b>Advanced solution</b>: check the directive <code>SSLOpenSSLConfCmd Ciphersuites</code> and for each element in the <b>Textual</b> section above, follow the instructions provided. The separator for this directive is <code>:</code> and to disable an element you can add either <code>-</code> (remove once) or <code>!</code> (kill) in front of it.</p>",
"Nginx": "<p>- <b>Quick solution</b>: replace the instruction of the directive <code>ssl_conf_command Ciphersuites</code> with the following string:<br/> {total_string}<br/>- <b>Advanced solution</b>: check the directive <code>ssl_conf_command Ciphersuites</code> and for each element in the <b>Textual</b> section above, follow the instructions provided. The separator for this directive is <code>:</code> and to disable an element you can add either <code>-</code> (remove once) or <code>!</code> (kill) in front of it.</p>"
}
Expand Down
35 changes: 24 additions & 11 deletions modules/compliance/compliance_base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import itertools
import json
import logging
import os.path
import re
from pathlib import Path
Expand All @@ -18,6 +19,7 @@
from utils.loader import load_configuration
from utils.logger import Logger
from utils.mitigations import MitigationLoader
from utils.prune import pruner
from utils.validation import Validator


Expand Down Expand Up @@ -85,6 +87,7 @@ def __init__(self):
self.valid_keysize = False
self.tls1_3_ciphers = get_1_3_ciphers()
self._no_psk = None
self._guidelines_string = ""

@staticmethod
def level_to_use(levels, security):
Expand Down Expand Up @@ -143,6 +146,7 @@ def input(self, **kwargs):
self._custom_guidelines = json.load(f)

guidelines_string = kwargs.get("guidelines")
self._guidelines_string = guidelines_string
openssl_version = kwargs.get("openssl_version")
ignore_openssl = kwargs.get("ignore_openssl")
self._no_psk = kwargs.get("no_psk", False)
Expand Down Expand Up @@ -244,6 +248,12 @@ def run(self, **kwargs):
return self.output()

def output(self):
if logging.getLogger().level == logging.DEBUG:
with open(f"testssl_dumps/report_{self.hostname}_{self._guidelines_string}.json", "w") as f:
for category in self._output_dict:
if self._output_dict[category].get("guidelines"):
self._output_dict[category]["guidelines"] = list(self._output_dict[category]["guidelines"])
json.dump(self._output_dict, f, indent=4)
if not self._output_dict.get("error"):
self.prune_output()
self._prepare_output()
Expand Down Expand Up @@ -494,11 +504,9 @@ def _add_certificate_signature_algorithm(self, alg):
to_return = []
if isinstance(alg, str):
alg = [alg]

for sig_alg in alg:
sig_alg = sig_alg.replace("RSASSA-PSS", "RSA")
if sig_alg.lower() not in self._cert_sig_algs:
sig_alg = "anonymous"
self._logging.warning(f"Signature algorithm {sig_alg} not found in the database")
to_return.append(sig_alg)
self._user_configuration["CertificateSignature"].add(sig_alg.lower())
return to_return
Expand Down Expand Up @@ -726,13 +734,15 @@ def update_result(self, sheet, name, entry_level, enabled, source, valid_conditi
"level": information_level,
"action": action,
"source": source,
"total_string_only": total_string_only
"total_string_only": total_string_only,
"original_level": entry_level
}
elif name not in self._output_dict[sheet]:
self._output_dict[sheet][name] = {
"level": "INFO",
"action": "NOTE: ",
"source": source,
"original_level": entry_level
}
self._output_dict[sheet]["notes"].append(name)
if not self._output_dict[sheet].get("guidelines"):
Expand Down Expand Up @@ -1073,7 +1083,9 @@ def output(self):
self._fill_user_configuration()
self._condition_parser = ConditionParser(self._user_configuration)
self._check_conditions()
return self._config_class.configuration_output()
output_dict = self._config_class.configuration_output()
output_dict = pruner(output_dict)
return output_dict

def get_sheet_filter(self, sheet):
# Dictionaries are used for specific things like a directive that enables an extension for this reason it is
Expand Down Expand Up @@ -1201,18 +1213,19 @@ def get_sheets_to_check(self, aliases, custom_guidelines):
for i, sheet in enumerate(self._sheets_versions_dict):
if sheets_to_check.get(sheet) is None:
sheets_to_check[sheet] = {}
for token in tokens[1:]:
token = token.upper()
# If it is an abbreviation get the complete name.
token = self._aliases.get(token, token)
if sheet + guideline + token in self._database_instance.table_names:
sheets_to_check[sheet][guideline] = token
if sheets_to_check[sheet].get(guideline) is None:
version = self._default_versions[sheet].get(guideline)
if version is not None:
sheets_to_check[sheet][guideline] = version
else:
self.__logging.info(f"Skipping {guideline} in {sheet} because no version is available.")
for token in tokens[1:]:
token = token.upper()
# If it is an abbreviation get the complete name.
token = self._aliases.get(token, token)
if sheet + guideline + token in self._database_instance.table_names and \
not (token == "" and sheets_to_check[sheet].get(guideline)):
sheets_to_check[sheet][guideline] = token
for sheet in custom_guidelines:
if sheets_to_check.get(sheet):
for guideline in custom_guidelines[sheet]:
Expand Down
1 change: 0 additions & 1 deletion run.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,5 +280,4 @@ def __call__(self, parser, namespace, values, option_string=""):
# todo add default aliases configurations for analysis
# configurations.add_argument()
args = parser.parse_args()
print(args)
tlsa = Tlsa(args)

0 comments on commit 2156631

Please sign in to comment.