Add Duration and Fix bugs
This commit is contained in:
parent
0f50fda384
commit
39fe43812e
76
README.md
76
README.md
@ -32,7 +32,7 @@ optional arguments:
|
|||||||
-c FILENAME.CSV, --csv FILENAME.CSV
|
-c FILENAME.CSV, --csv FILENAME.CSV
|
||||||
Enable CSV file export
|
Enable CSV file export
|
||||||
-j, --json Enable JSON in the output
|
-j, --json Enable JSON in the output
|
||||||
-a, --analyze Enable SSL security analysis on the host
|
-a, --analyze Enable SSL security analysis on the host.
|
||||||
-p, --pretty Print pretty and more human readable Json
|
-p, --pretty Print pretty and more human readable Json
|
||||||
-h, --help Show this help message and exit
|
-h, --help Show this help message and exit
|
||||||
```
|
```
|
||||||
@ -51,7 +51,7 @@ Port is optional here. The script will use 443 if not specified.
|
|||||||
|
|
||||||
`-j, --json ` Use this if you want to only have the result in JSON
|
`-j, --json ` Use this if you want to only have the result in JSON
|
||||||
|
|
||||||
`-a, --analyze` This argument will include security analyze on the certificate. It will take more time.
|
`-a, --analyze` This argument will include security analyze on the certificate. It will take more time. No result means failed to analyze.
|
||||||
|
|
||||||
`-p, --pretty ` Use this with `-j` to print indented and human readable JSON
|
`-p, --pretty ` Use this with `-j` to print indented and human readable JSON
|
||||||
|
|
||||||
@ -69,7 +69,9 @@ narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -H facebook.com
|
|||||||
|
|
||||||
[-] facebook.com Failed: [Errno 111] Connection refused
|
[-] facebook.com Failed: [Errno 111] Connection refused
|
||||||
|
|
||||||
0 successful and 1 failed
|
+------------------------------------------------------+
|
||||||
|
| Successful: 0 | Failed: 1 | Duration: 0:00:00.710470 |
|
||||||
|
+------------------------------------------------------+
|
||||||
|
|
||||||
narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -H facebook.com -s localhost:9050
|
narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -H facebook.com -s localhost:9050
|
||||||
+-------------------+
|
+-------------------+
|
||||||
@ -88,7 +90,9 @@ narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -H facebook.com -s localhost:9
|
|||||||
Certificate algorithm: sha256WithRSAEncryption
|
Certificate algorithm: sha256WithRSAEncryption
|
||||||
Expired: False
|
Expired: False
|
||||||
|
|
||||||
1 successful and 0 failed
|
+------------------------------------------------------+
|
||||||
|
| Successful: 1 | Failed: 0 | Duration: 0:00:00.710470 |
|
||||||
|
+------------------------------------------------------+
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -98,39 +102,48 @@ narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -H facebook.com -s localhost:9
|
|||||||
## Example
|
## Example
|
||||||
|
|
||||||
```
|
```
|
||||||
narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -H narbeh.org google.com:443
|
narbeh@narbeh-laptop:~/ssl-checker$ ./ssl_checker.py -H time.com github.com:443
|
||||||
+-------------------+
|
+---------------------+
|
||||||
| Analyzing 2 host(s) |
|
| Analyzing 2 host(s) |
|
||||||
+-------------------+
|
+---------------------+
|
||||||
|
[+] time.com
|
||||||
[+] narbeh.org
|
-------------
|
||||||
|
Issued domain: time.com
|
||||||
Issued domain: narbeh.org
|
|
||||||
Issued to: None
|
Issued to: None
|
||||||
Issued by: Let's Encrypt (US)
|
Issued by: Amazon (US)
|
||||||
Valid from: 2018-04-21
|
Valid from: 2018-11-07
|
||||||
Valid to: 2018-07-20 (88 days left)
|
Valid to: 2019-12-07 (159 days left)
|
||||||
Validity days: 90
|
Validity days: 395
|
||||||
Certificate S/N: 338163108483756707389368573553026254634358
|
Certificate S/N: 10018094209647532371913518187860771165
|
||||||
|
Certificate SHA1 FP: 64:C4:2E:AF:38:2A:28:64:A0:A8:B8:6B:02:05:86:1F:E7:F6:E5:FF
|
||||||
Certificate version: 2
|
Certificate version: 2
|
||||||
Certificate algorithm: sha256WithRSAEncryption
|
Certificate algorithm: sha256WithRSAEncryption
|
||||||
Expired: False
|
Expired: False
|
||||||
|
Certificate SAN's:
|
||||||
|
\_ DNS:time.com
|
||||||
|
\_ DNS:*.time.com
|
||||||
|
|
||||||
[+] google.com
|
|
||||||
|
|
||||||
Issued domain: *.google.com
|
[+] github.com
|
||||||
Issued to: Google Inc
|
---------------
|
||||||
Issued by: Google Inc (US)
|
Issued domain: github.com
|
||||||
Valid from: 2018-03-28
|
Issued to: GitHub, Inc.
|
||||||
Valid to: 2018-06-20 (58 days left)
|
Issued by: DigiCert Inc (US)
|
||||||
Validity days: 83
|
Valid from: 2018-05-08
|
||||||
Certificate S/N: 2989116342670522968
|
Valid to: 2020-06-03 (338 days left)
|
||||||
|
Validity days: 757
|
||||||
|
Certificate S/N: 13324412563135569597699362973539517727
|
||||||
|
Certificate SHA1 FP: CA:06:F5:6B:25:8B:7A:0D:4F:2B:05:47:09:39:47:86:51:15:19:84
|
||||||
Certificate version: 2
|
Certificate version: 2
|
||||||
Certificate algorithm: sha256WithRSAEncryption
|
Certificate algorithm: sha256WithRSAEncryption
|
||||||
Expired: False
|
Expired: False
|
||||||
|
Certificate SAN's:
|
||||||
|
\_ DNS:github.com
|
||||||
|
\_ DNS:www.github.com
|
||||||
|
|
||||||
|
+------------------------------------------------------+
|
||||||
2 successful and 0 failed
|
| Successful: 2 | Failed: 0 | Duration: 0:00:01.429145 |
|
||||||
|
+------------------------------------------------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -141,9 +154,9 @@ By passing `-a/--analyze` to the script, it will scan the certificate for securi
|
|||||||
|
|
||||||
```
|
```
|
||||||
narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -j -p -H narbeh.org:443 -a
|
narbeh@narbeh-xps:~/ssl-checker$ ./ssl_checker.py -j -p -H narbeh.org:443 -a
|
||||||
+-------------------+
|
+---------------------+
|
||||||
|Analyzing 2 host(s)|
|
| Analyzing 1 host(s) |
|
||||||
+-------------------+
|
+---------------------+
|
||||||
|
|
||||||
Warning: -a/--analyze is enabled. It takes more time...
|
Warning: -a/--analyze is enabled. It takes more time...
|
||||||
|
|
||||||
@ -167,8 +180,9 @@ Warning: -a/--analyze is enabled. It takes more time...
|
|||||||
Drown vulnerability: False
|
Drown vulnerability: False
|
||||||
Expired: False
|
Expired: False
|
||||||
|
|
||||||
|
+------------------------------------------------------+
|
||||||
1 successful and 0 failed
|
| Successful: 1 | Failed: 0 | Duration: 0:00:01.429145 |
|
||||||
|
+------------------------------------------------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -64,20 +64,20 @@ def analyze_ssl(host, context):
|
|||||||
api_url = 'https://api.ssllabs.com/api/v3/'
|
api_url = 'https://api.ssllabs.com/api/v3/'
|
||||||
while True:
|
while True:
|
||||||
main_request = loads(urlopen(api_url + 'analyze?host={}'.format(host)).read().decode('utf-8'))
|
main_request = loads(urlopen(api_url + 'analyze?host={}'.format(host)).read().decode('utf-8'))
|
||||||
if main_request['status'] == 'DNS':
|
if main_request['status'] in ('DNS', 'IN_PROGRESS'):
|
||||||
print('Analyzing the security of {}. Please wait...'.format(host))
|
|
||||||
sleep(5)
|
sleep(5)
|
||||||
continue
|
continue
|
||||||
if main_request['status'] == 'IN_PROGRESS':
|
|
||||||
# We can find a way to show the progress
|
|
||||||
sleep(5)
|
|
||||||
pass
|
|
||||||
elif main_request['status'] == 'READY':
|
elif main_request['status'] == 'READY':
|
||||||
break
|
break
|
||||||
|
|
||||||
context[host]['grade'] = main_request['endpoints'][0]['grade']
|
endpoint_data = loads(urlopen(api_url + 'getEndpointData?host={}&s={}'.format(
|
||||||
endpoint_data = loads(urlopen(api_url + 'getEndpointData?host={}&s={}'.format(host, main_request['endpoints'][0]['ipAddress'])).read().decode('utf-8'))
|
host, main_request['endpoints'][0]['ipAddress'])).read().decode('utf-8'))
|
||||||
|
|
||||||
|
# if the certificate is invalid
|
||||||
|
if endpoint_data['statusMessage'] == 'Certificate not valid for domain name':
|
||||||
|
return context
|
||||||
|
|
||||||
|
context[host]['grade'] = main_request['endpoints'][0]['grade']
|
||||||
context[host]['poodle_vuln'] = endpoint_data['details']['poodle']
|
context[host]['poodle_vuln'] = endpoint_data['details']['poodle']
|
||||||
context[host]['heartbleed_vuln'] = endpoint_data['details']['heartbleed']
|
context[host]['heartbleed_vuln'] = endpoint_data['details']['heartbleed']
|
||||||
context[host]['heartbeat_vuln'] = endpoint_data['details']['heartbeat']
|
context[host]['heartbeat_vuln'] = endpoint_data['details']['heartbeat']
|
||||||
@ -117,7 +117,7 @@ def get_cert_info(host, cert):
|
|||||||
context['issuer_ou'] = cert.get_issuer().organizationalUnitName
|
context['issuer_ou'] = cert.get_issuer().organizationalUnitName
|
||||||
context['issuer_cn'] = cert.get_issuer().commonName
|
context['issuer_cn'] = cert.get_issuer().commonName
|
||||||
context['cert_sn'] = cert.get_serial_number()
|
context['cert_sn'] = cert.get_serial_number()
|
||||||
context['cert_sha1'] = cert.digest('sha1')
|
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'] = get_cert_sans(cert)
|
||||||
@ -143,7 +143,7 @@ def print_status(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
|
||||||
|
|
||||||
print('\t{}[+]{} {}\n'.format(Clr.GREEN, Clr.RST, host))
|
print('\t{}[+]{} {}\n\t{}'.format(Clr.GREEN, Clr.RST, host, '-' * (len(host) + 5)))
|
||||||
print('\t\tIssued domain: {}'.format(context[host]['issued_to']))
|
print('\t\tIssued domain: {}'.format(context[host]['issued_to']))
|
||||||
print('\t\tIssued to: {}'.format(context[host]['issued_o']))
|
print('\t\tIssued to: {}'.format(context[host]['issued_o']))
|
||||||
print('\t\tIssued by: {} ({})'.format(context[host]['issuer_o'], context[host]['issuer_c']))
|
print('\t\tIssued by: {} ({})'.format(context[host]['issuer_o'], context[host]['issuer_c']))
|
||||||
@ -155,7 +155,7 @@ def print_status(host, context, analyze=False):
|
|||||||
print('\t\tCertificate version: {}'.format(context[host]['cert_ver']))
|
print('\t\tCertificate version: {}'.format(context[host]['cert_ver']))
|
||||||
print('\t\tCertificate algorithm: {}'.format(context[host]['cert_alg']))
|
print('\t\tCertificate algorithm: {}'.format(context[host]['cert_alg']))
|
||||||
|
|
||||||
if analyze:
|
if analyze and context.get('grade', False): # If analyze part fails
|
||||||
print('\t\tCertificate grade: {}'.format(context[host]['grade']))
|
print('\t\tCertificate grade: {}'.format(context[host]['grade']))
|
||||||
print('\t\tPoodle vulnerability: {}'.format(context[host]['poodle_vuln']))
|
print('\t\tPoodle vulnerability: {}'.format(context[host]['poodle_vuln']))
|
||||||
print('\t\tHeartbleed vulnerability: {}'.format(context[host]['heartbleed_vuln']))
|
print('\t\tHeartbleed vulnerability: {}'.format(context[host]['heartbleed_vuln']))
|
||||||
@ -177,6 +177,7 @@ def show_result(user_args):
|
|||||||
"""Get the context."""
|
"""Get the context."""
|
||||||
context = {}
|
context = {}
|
||||||
failed_cnt = 0
|
failed_cnt = 0
|
||||||
|
start_time = datetime.now()
|
||||||
hosts = user_args.hosts
|
hosts = user_args.hosts
|
||||||
|
|
||||||
if not user_args.json_true:
|
if not user_args.json_true:
|
||||||
@ -211,7 +212,8 @@ 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 and {} failed '.format(len(hosts) - failed_cnt, failed_cnt))
|
border_msg(' Successful: {} | Failed: {} | Duration: {} '.format(
|
||||||
|
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:
|
||||||
@ -230,7 +232,7 @@ def export_csv(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:
|
||||||
csv_writer = DictWriter(csv_file, context.items()[0][1].keys())
|
csv_writer = DictWriter(csv_file, list(context.items())[0][1].keys())
|
||||||
csv_writer.writeheader()
|
csv_writer.writeheader()
|
||||||
for host in context.keys():
|
for host in context.keys():
|
||||||
csv_writer.writerow(context[host])
|
csv_writer.writerow(context[host])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user