mirror of
https://github.com/mozilla/cipherscan.git
synced 2024-11-22 14:23:41 +01:00
analyze.py more portable
- openssl_bin defaults to `which openssl`, instead of hardcoded ./openssl - new option -o /path/to/openssl_bin
This commit is contained in:
parent
cc1230efd9
commit
eedb26b958
44
analyze.py
44
analyze.py
@ -1,13 +1,22 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
#
|
#
|
||||||
# Contributor: Julien Vehent jvehent@mozilla.com [:ulfr]
|
# Contributor: Julien Vehent jvehent@mozilla.com [:ulfr]
|
||||||
|
# lazy.dogtown@gmail.com
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
import sys, os, json, subprocess, logging, argparse
|
import sys, os, json, subprocess, logging, argparse
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
|
default_openssl_bin = subprocess.Popen(['which', 'openssl'], stdout=subprocess.PIPE).communicate()[0].rstrip()
|
||||||
|
|
||||||
|
# incase you want to ship your own openssl
|
||||||
|
#default_openssl_bin= "./openssl"
|
||||||
|
|
||||||
# is_fubar assumes that a configuration is not completely messed up
|
# is_fubar assumes that a configuration is not completely messed up
|
||||||
# and looks for reasons to think otherwise. it will return True if
|
# and looks for reasons to think otherwise. it will return True if
|
||||||
# it finds one of these reason
|
# it finds one of these reason
|
||||||
@ -16,19 +25,19 @@ def is_fubar(results):
|
|||||||
fubar_ciphers = set(all_ciphers) - set(old_ciphers)
|
fubar_ciphers = set(all_ciphers) - set(old_ciphers)
|
||||||
for conn in results['ciphersuite']:
|
for conn in results['ciphersuite']:
|
||||||
if conn['cipher'] in fubar_ciphers:
|
if conn['cipher'] in fubar_ciphers:
|
||||||
logging.debug(conn['cipher'] + ' is in the list of fubar ciphers')
|
logging.debug('BAD: ' + conn['cipher'] + ' is in the list of fubar ciphers')
|
||||||
fubar = True
|
fubar = True
|
||||||
if 'SSLv2' in conn['protocols']:
|
if 'SSLv2' in conn['protocols']:
|
||||||
logging.debug('SSLv2 is in the list of fubar protocols')
|
logging.debug('BAD: SSLv2 is in the list of fubar protocols')
|
||||||
fubar = True
|
fubar = True
|
||||||
if conn['pubkey'] < 2048:
|
if conn['pubkey'] < 2048:
|
||||||
logging.debug(conn['pubkey'] + ' is a fubar pubkey size')
|
logging.debug('BAD: ' + conn['pubkey'] + ' is a fubar pubkey size')
|
||||||
fubar = True
|
fubar = True
|
||||||
if 'md5WithRSAEncryption' in conn['sigalg']:
|
if 'md5WithRSAEncryption' in conn['sigalg']:
|
||||||
logging.debug(conn['sigalg']+ ' is a fubar cert signature')
|
logging.debug('BAD: ' + conn['sigalg']+ ' is a fubar cert signature')
|
||||||
fubar = True
|
fubar = True
|
||||||
if conn['trusted'] == 'False':
|
if conn['trusted'] == 'False':
|
||||||
logging.debug('The certificate is not trusted, which is quite fubar')
|
logging.debug('BAD: The certificate is not trusted, which is quite fubar')
|
||||||
fubar = True
|
fubar = True
|
||||||
return fubar
|
return fubar
|
||||||
|
|
||||||
@ -233,7 +242,7 @@ def evaluate_all(results):
|
|||||||
status = "old ssl with bad ordering"
|
status = "old ssl with bad ordering"
|
||||||
|
|
||||||
if is_fubar(results):
|
if is_fubar(results):
|
||||||
return "bad ssl"
|
return "bad ssl (turn on debugging to see why)"
|
||||||
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
@ -299,20 +308,21 @@ def build_ciphers_lists():
|
|||||||
'AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'
|
'AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'
|
||||||
blackhole = open(os.devnull, 'w')
|
blackhole = open(os.devnull, 'w')
|
||||||
logging.debug('Loading all ciphers: ' + allC)
|
logging.debug('Loading all ciphers: ' + allC)
|
||||||
all_ciphers = subprocess.Popen(['./openssl', 'ciphers', allC],
|
all_ciphers = subprocess.Popen([openssl_bin, 'ciphers', allC],
|
||||||
stderr=blackhole, stdout=subprocess.PIPE).communicate()[0].rstrip().split(':')
|
stderr=blackhole, stdout=subprocess.PIPE).communicate()[0].rstrip().split(':')
|
||||||
logging.debug('Loading old ciphers: ' + oldC)
|
logging.debug('Loading old ciphers: ' + oldC)
|
||||||
old_ciphers = subprocess.Popen(['./openssl', 'ciphers', oldC],
|
old_ciphers = subprocess.Popen([openssl_bin, 'ciphers', oldC],
|
||||||
stderr=blackhole, stdout=subprocess.PIPE).communicate()[0].rstrip().split(':')
|
stderr=blackhole, stdout=subprocess.PIPE).communicate()[0].rstrip().split(':')
|
||||||
logging.debug('Loading intermediate ciphers: ' + intC)
|
logging.debug('Loading intermediate ciphers: ' + intC)
|
||||||
intermediate_ciphers = subprocess.Popen(['./openssl', 'ciphers', intC],
|
intermediate_ciphers = subprocess.Popen([openssl_bin, 'ciphers', intC],
|
||||||
stderr=blackhole, stdout=subprocess.PIPE).communicate()[0].rstrip().split(':')
|
stderr=blackhole, stdout=subprocess.PIPE).communicate()[0].rstrip().split(':')
|
||||||
logging.debug('Loading modern ciphers: ' + modernC)
|
logging.debug('Loading modern ciphers: ' + modernC)
|
||||||
modern_ciphers = subprocess.Popen(['./openssl', 'ciphers', modernC],
|
modern_ciphers = subprocess.Popen([openssl_bin, 'ciphers', modernC],
|
||||||
stderr=blackhole, stdout=subprocess.PIPE).communicate()[0].rstrip().split(':')
|
stderr=blackhole, stdout=subprocess.PIPE).communicate()[0].rstrip().split(':')
|
||||||
blackhole.close()
|
blackhole.close()
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
global openssl_bin
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Analyze cipherscan results and provides guidelines to improve configuration.',
|
description='Analyze cipherscan results and provides guidelines to improve configuration.',
|
||||||
usage='\n* Analyze a single target, invokes cipherscan: $ ./analyze.py -t [target]' \
|
usage='\n* Analyze a single target, invokes cipherscan: $ ./analyze.py -t [target]' \
|
||||||
@ -329,19 +339,31 @@ def main():
|
|||||||
help='target configuration level [old, intermediate, modern]')
|
help='target configuration level [old, intermediate, modern]')
|
||||||
parser.add_argument('-t', dest='target',
|
parser.add_argument('-t', dest='target',
|
||||||
help='analyze a <target>, invokes cipherscan')
|
help='analyze a <target>, invokes cipherscan')
|
||||||
|
parser.add_argument('-o', dest='openssl',
|
||||||
|
help='give path to openssl, defaults to `which openssl`')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.debug:
|
if args.debug:
|
||||||
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
|
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
|
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
if args.openssl:
|
||||||
|
openssl_bin = args.openssl
|
||||||
|
else:
|
||||||
|
openssl_bin = default_openssl_bin
|
||||||
|
|
||||||
|
logging.debug('using openssl - binary ' + openssl_bin)
|
||||||
|
|
||||||
|
|
||||||
build_ciphers_lists()
|
build_ciphers_lists()
|
||||||
|
|
||||||
if args.target:
|
if args.target:
|
||||||
# evaluate target specified as argument
|
# evaluate target specified as argument
|
||||||
logging.debug('Invoking cipherscan with target: ' + args.target)
|
logging.debug('Invoking cipherscan with target: ' + args.target)
|
||||||
data = subprocess.check_output(['./cipherscan', '-j', args.target])
|
data = subprocess.check_output(['./cipherscan', '-o', openssl_bin, '-j', args.target])
|
||||||
process_results(data, args.level)
|
process_results(data, args.level)
|
||||||
else:
|
else:
|
||||||
if os.fstat(args.infile.fileno()).st_size < 2:
|
if os.fstat(args.infile.fileno()).st_size < 2:
|
||||||
|
Loading…
Reference in New Issue
Block a user