Transformed to class

This commit is contained in:
Matthias Maes 2020-06-23 09:08:28 +02:00
parent 16cc5969ba
commit 98a8b08875

View File

@ -25,11 +25,13 @@ class Clr:
YELLOW = '\033[33m' YELLOW = '\033[33m'
def get_cert(host, port, user_args): class SSLChecker:
def get_cert(self, host, port, user_args):
"""Connection to the host.""" """Connection to the host."""
if user_args.socks: if user_args.socks:
import socks import socks
socks_host, socks_port = filter_hostname(user_args.socks) socks_host, socks_port = self.filter_hostname(user_args.socks)
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, socks_host, int(socks_port), True) socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, socks_host, int(socks_port), True)
socket.socket = socks.socksocket socket.socket = socks.socksocket
@ -46,7 +48,7 @@ def get_cert(host, port, user_args):
return cert return cert
def border_msg(message): def border_msg(self, message):
"""Print the message in the box.""" """Print the message in the box."""
row = len(message) row = len(message)
h = ''.join(['+'] + ['-' * row] + ['+']) h = ''.join(['+'] + ['-' * row] + ['+'])
@ -54,7 +56,7 @@ def border_msg(message):
print(result) print(result)
def analyze_ssl(host, context): def analyze_ssl(self, host, context):
"""Analyze the security of the SSL certificate.""" """Analyze the security of the SSL certificate."""
try: try:
from urllib.request import urlopen from urllib.request import urlopen
@ -88,7 +90,7 @@ def analyze_ssl(host, context):
return context return context
def get_cert_sans(x509cert): def get_cert_sans(self, x509cert):
""" """
Get Subject Alt Names from Certificate. Shameless taken from stack overflow: Get Subject Alt Names from Certificate. Shameless taken from stack overflow:
https://stackoverflow.com/users/4547691/anatolii-chmykhalo https://stackoverflow.com/users/4547691/anatolii-chmykhalo
@ -104,7 +106,7 @@ def get_cert_sans(x509cert):
return san return san
def get_cert_info(host, cert): def get_cert_info(self, host, cert):
"""Get all the information about cert and create a JSON file.""" """Get all the information about cert and create a JSON file."""
context = {} context = {}
@ -121,7 +123,7 @@ def get_cert_info(host, cert):
context['cert_sha1'] = cert.digest('sha1').decode() context['cert_sha1'] = cert.digest('sha1').decode()
context['cert_alg'] = cert.get_signature_algorithm().decode() context['cert_alg'] = cert.get_signature_algorithm().decode()
context['cert_ver'] = cert.get_version() context['cert_ver'] = cert.get_version()
context['cert_sans'] = get_cert_sans(cert) context['cert_sans'] = self.get_cert_sans(cert)
context['cert_exp'] = cert.has_expired() context['cert_exp'] = cert.has_expired()
# Valid from # Valid from
@ -144,7 +146,7 @@ def get_cert_info(host, cert):
return context return context
def print_status(host, context, analyze=False): def print_status(self, host, context, analyze=False):
"""Print all the usefull info about host.""" """Print all the usefull info about host."""
days_left = (datetime.strptime(context[host]['valid_till'], '%Y-%m-%d') - datetime.now()).days days_left = (datetime.strptime(context[host]['valid_till'], '%Y-%m-%d') - datetime.now()).days
@ -178,7 +180,7 @@ def print_status(host, context, analyze=False):
print('\n') print('\n')
def show_result(user_args): def show_result(self, user_args):
"""Get the context.""" """Get the context."""
context = {} context = {}
failed_cnt = 0 failed_cnt = 0
@ -186,29 +188,29 @@ def show_result(user_args):
hosts = user_args.hosts hosts = user_args.hosts
if not user_args.json_true: if not user_args.json_true:
border_msg(' Analyzing {} host(s) '.format(len(hosts))) self.border_msg(' Analyzing {} host(s) '.format(len(hosts)))
if not user_args.json_true and user_args.analyze: if not user_args.json_true and user_args.analyze:
print('{}Warning: -a/--analyze is enabled. It takes more time...{}\n'.format(Clr.YELLOW, Clr.RST)) print('{}Warning: -a/--analyze is enabled. It takes more time...{}\n'.format(Clr.YELLOW, Clr.RST))
for host in hosts: for host in hosts:
host, port = filter_hostname(host) host, port = self.filter_hostname(host)
# Check duplication # Check duplication
if host in context.keys(): if host in context.keys():
continue continue
try: try:
cert = get_cert(host, port, user_args) cert = self.get_cert(host, port, user_args)
context[host] = get_cert_info(host, cert) context[host] = self.get_cert_info(host, cert)
context[host]['tcp_port'] = int(port) context[host]['tcp_port'] = int(port)
# Analyze the certificate if enabled # Analyze the certificate if enabled
if user_args.analyze: if user_args.analyze:
context = analyze_ssl(host, context) context = self.analyze_ssl(host, context)
if not user_args.json_true: if not user_args.json_true:
print_status(host, context, user_args.analyze) self.print_status(host, context, user_args.analyze)
except SSL.SysCallError: except SSL.SysCallError:
if not user_args.json_true: if not user_args.json_true:
print('\t{}[-]{} {:<20s} Failed: Misconfigured SSL/TLS\n'.format(Clr.RED, Clr.RST, host)) print('\t{}[-]{} {:<20s} Failed: Misconfigured SSL/TLS\n'.format(Clr.RED, Clr.RST, host))
@ -222,12 +224,12 @@ def show_result(user_args):
sys.exit(1) sys.exit(1)
if not user_args.json_true: if not user_args.json_true:
border_msg(' Successful: {} | Failed: {} | Duration: {} '.format( self.border_msg(' Successful: {} | Failed: {} | Duration: {} '.format(
len(hosts) - failed_cnt, failed_cnt, datetime.now() - start_time)) len(hosts) - failed_cnt, failed_cnt, datetime.now() - start_time))
# CSV export if -c/--csv is specified # CSV export if -c/--csv is specified
if user_args.csv_enabled: if user_args.csv_enabled:
export_csv(context, user_args.csv_enabled) self.export_csv(context, user_args.csv_enabled)
# Enable JSON output if -j/--json argument specified # Enable JSON output if -j/--json argument specified
if user_args.json_true: if user_args.json_true:
@ -239,7 +241,7 @@ def show_result(user_args):
fp.write(json.dumps(context[host])) fp.write(json.dumps(context[host]))
def export_csv(context, filename): def export_csv(self, context, filename):
"""Export all context results to CSV file.""" """Export all context results to CSV file."""
# prepend dict keys to write column headers # prepend dict keys to write column headers
with open(filename, 'w') as csv_file: with open(filename, 'w') as csv_file:
@ -249,7 +251,7 @@ def export_csv(context, filename):
csv_writer.writerow(context[host]) csv_writer.writerow(context[host])
def filter_hostname(host): def filter_hostname(self, host):
"""Remove unused characters and split by address and port.""" """Remove unused characters and split by address and port."""
host = host.replace('http://', '').replace('https://', '').replace('/', '') host = host.replace('http://', '').replace('https://', '').replace('/', '')
port = 443 port = 443
@ -259,7 +261,7 @@ def filter_hostname(host):
return host, port return host, port
def get_args(): def get_args(self):
"""Set argparse options.""" """Set argparse options."""
parser = ArgumentParser(prog='ssl_checker.py', add_help=False, parser = ArgumentParser(prog='ssl_checker.py', add_help=False,
description="""Collects useful information about given host's SSL certificates.""") description="""Collects useful information about given host's SSL certificates.""")
@ -303,6 +305,6 @@ def get_args():
return args return args
if __name__ == '__main__': if __name__ == '__main__':
show_result(get_args()) SSLCheckerObject = SSLChecker()
SSLCheckerObject.show_result(SSLCheckerObject.get_args())