From 341f657e832780da3647df451669f865b26046f4 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Tue, 11 Nov 2014 03:05:54 +0100 Subject: [PATCH 1/9] better detection for EXP and low grade ciphers in stats EXP is self explanatory - export grade DES-CBC3-MD5 is available only in SSLv2 - not secure RC4-64-MD5 is also a weakened version (though not marked as export grade) --- top1m/parse_results.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 6c5326a..09766a3 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -187,7 +187,10 @@ for r,d,flist in os.walk(path): temp_client_incompat[client_name][entry['cipher']] = 1 """ store the ciphers supported """ - if 'ADH' in entry['cipher'] or 'AECDH' in entry['cipher']: + if 'ADH' in entry['cipher'] or 'AECDH' in entry['cipher'] or \ + 'EXP' in entry['cipher'] or \ + 'DES-CBC3-MD5' in entry['cipher'] or \ + 'RC4-64-MD5' in entry['cipher']: ciphertypes += 1 name = "z:" + entry['cipher'] tempcipherstats[name] = 1 From 1b360153a0a7b02e841699b4920c8c097a06d750 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Mon, 24 Nov 2014 13:21:35 +0100 Subject: [PATCH 2/9] sum servers that support SSL3 or TLS1 as the highest protocol --- top1m/parse_results.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 09766a3..e604e7c 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -464,10 +464,14 @@ for r,d,flist in os.walk(path): protocolstats['SSL3'] += 1 if not SSL2 and not TLS1 and not TLS1_1 and not TLS1_2: protocolstats['SSL3 Only'] += 1 + if not TLS1 and not TLS1_1 and not TLS1_2: + protocolstats['SSL3 or lower Only'] += 1 if TLS1: protocolstats['TLS1'] += 1 if not SSL2 and not SSL3 and not TLS1_1 and not TLS1_2: protocolstats['TLS1 Only'] += 1 + if not TLS1_1 and not TLS1_2: + protocolstats['TLS1 or lower Only'] += 1 if not SSL2 and (SSL3 or TLS1) and not TLS1_1 and not TLS1_2: protocolstats['SSL3 or TLS1 Only'] += 1 if not SSL2 and not SSL3 and not TLS1: From 82f643244e72998e4d1d6d6582c69eaff5c69f0e Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Fri, 30 Jan 2015 23:45:24 +0100 Subject: [PATCH 3/9] don't count export grade ciphers towards PFS --- top1m/parse_results.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index e604e7c..6c4d3e4 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -230,16 +230,18 @@ for r,d,flist in os.walk(path): tempcipherstats['Insecure'] = 1 """ store key handshake methods """ - if 'ECDHE' in entry['cipher']: + if 'EXP' in entry['cipher']: + pass + elif 'AECDH' in entry['cipher']: + AECDH = True + elif 'ADH' in entry['cipher']: + ADH = True + elif 'ECDHE' in entry['cipher']: ECDHE = True temppfsstats[entry['pfs']] = 1 elif 'DHE' in entry['cipher'] or 'EDH' in entry['cipher']: DHE = True temppfsstats[entry['pfs']] = 1 - elif 'AECDH' in entry['cipher']: - AECDH = True - elif 'ADH' in entry['cipher']: - ADH = True elif 'ECDH' in entry['cipher']: ECDH = True elif 'DH' in entry['cipher']: From b9b3a221cef18dc75004b2781d581a82fbfef059 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Tue, 31 Mar 2015 21:52:52 +0200 Subject: [PATCH 4/9] add Firefox 35 cipher settings --- top1m/parse_results.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 6c4d3e4..4790fe4 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -49,6 +49,24 @@ client_ciphers['FF 29']=[ 'RC4-SHA', 'RC4-MD5'] +client_ciphers['FF 35']=[ + 'ECDHE-ECDSA-AES128-GCM-SHA256', + 'ECDHE-RSA-AES128-GCM-SHA256', + 'ECDHE-ECDSA-AES256-SHA', + 'ECDHE-ECDSA-AES128-SHA', + 'ECDHE-RSA-AES128-SHA', + 'ECDHE-RSA-AES256-SHA', + 'ECDHE-ECDSA-RC4-SHA', + 'ECDHE-RSA-RC4-SHA', + 'DHE-RSA-AES128-SHA', + 'DHE-DSS-AES128-SHA', + 'DHE-RSA-AES256-SHA', + 'AES128-SHA', + 'AES256-SHA', + 'DES-CBC3-SHA', + 'RC4-SHA', + 'RC4-MD5'] + report_untrused=False cipherstats = defaultdict(int) From d773b73e451321b35a8d8577bb711da587f3fed6 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Tue, 31 Mar 2015 23:22:37 +0200 Subject: [PATCH 5/9] don't divide by zero on empty results folder --- top1m/parse_results.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 4790fe4..a44a237 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -617,6 +617,8 @@ for stat in sorted(keysize): percent = round(keysize[stat] / total * 100, 4) sys.stdout.write(stat.ljust(25) + " " + str(keysize[stat]).ljust(10) + str(percent).ljust(9) + "\n") +if total == 0: + total = 1 sys.stdout.write("RSA/ECDSA Dual Stack".ljust(25) + " " + str(dsarsastack).ljust(10) + str(round(dsarsastack/total * 100, 4)) + "\n") print("\nOCSP stapling Count Percent ") From b673fb976ab58efb92e59c5dd8ee866cad19e0eb Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Tue, 31 Mar 2015 23:23:10 +0200 Subject: [PATCH 6/9] separate AES-CBC from AES-GCM --- top1m/parse_results.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index a44a237..2a4a228 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -114,6 +114,7 @@ for r,d,flist in os.walk(path): tempcipherstats = {} ciphertypes = 0 AESGCM = False + AESCBC = False AES = False CHACHA20 = False DES3 = False @@ -215,11 +216,13 @@ for r,d,flist in os.walk(path): tempcipherstats['Insecure'] = 1 elif 'AES128-GCM' in entry['cipher'] or 'AES256-GCM' in entry['cipher']: if not AESGCM: + AES = True AESGCM = True ciphertypes += 1 elif 'AES' in entry['cipher']: - if not AES: + if not AESCBC: AES = True + AESCBC = True ciphertypes += 1 elif 'DES-CBC3' in entry['cipher']: if not DES3: @@ -402,10 +405,12 @@ for r,d,flist in os.walk(path): cipherstats['AES-GCM Only'] += 1 if AES: cipherstats['AES'] += 1 + if AESCBC: + cipherstats['AES-CBC'] += 1 if ciphertypes == 1: cipherstats['AES-CBC Only'] += 1 - if (AES and ciphertypes == 1) or (AESGCM and ciphertypes == 1)\ - or (AES and AESGCM and ciphertypes == 2): + if (AESCBC and ciphertypes == 1) or (AESGCM and ciphertypes == 1)\ + or (AESCBC and AESGCM and ciphertypes == 2): cipherstats['AES Only'] += 1 if CHACHA20: cipherstats['CHACHA20'] += 1 From 37f1d15af12ad1037cb6831e73e4f467e20b5d29 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Tue, 31 Mar 2015 23:45:51 +0200 Subject: [PATCH 7/9] count SSLv2 IDEA as insecure --- top1m/parse_results.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 2a4a228..2bf9ce6 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -209,7 +209,8 @@ for r,d,flist in os.walk(path): if 'ADH' in entry['cipher'] or 'AECDH' in entry['cipher'] or \ 'EXP' in entry['cipher'] or \ 'DES-CBC3-MD5' in entry['cipher'] or \ - 'RC4-64-MD5' in entry['cipher']: + 'RC4-64-MD5' in entry['cipher'] or \ + 'IDEA-CBC-MD5' in entry['cipher']: ciphertypes += 1 name = "z:" + entry['cipher'] tempcipherstats[name] = 1 From c55d8166c5a70c54900a53f1ed36879e608d113e Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Tue, 31 Mar 2015 23:51:43 +0200 Subject: [PATCH 8/9] don't limit client specific RC4 Only to servers with multiple ciphers --- top1m/parse_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 2bf9ce6..6eba070 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -447,7 +447,7 @@ for r,d,flist in os.walk(path): client_selected_cipherstats[client_name][client_selected[client_name]] += 1 - if client_RC4_Only[client_name] and ciphertypes != 1: + if client_RC4_Only[client_name]: cipherstats['x:' + client_name + ' RC4 Only'] += 1 for cipher in temp_client_incompat[client_name]: client_RC4_Only_cipherstats[client_name][cipher] += 1 From d8ebaf2d9f7cde86274d1b4982af7d8bf130327b Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Tue, 31 Mar 2015 23:58:30 +0200 Subject: [PATCH 9/9] report summary for clients for RC4 Preferred too --- top1m/parse_results.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 6eba070..6e37cf1 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -451,7 +451,7 @@ for r,d,flist in os.walk(path): cipherstats['x:' + client_name + ' RC4 Only'] += 1 for cipher in temp_client_incompat[client_name]: client_RC4_Only_cipherstats[client_name][cipher] += 1 - if client_RC4_Pref[client_name] and not 'RC4' in results['ciphersuite'][0]['cipher']: + if client_RC4_Pref[client_name]: cipherstats['x:' + client_name + ' RC4 Preferred'] += 1 for cipher in temp_client_incompat[client_name]: client_RC4_preferred_cipherstats[client_name][cipher] += 1 @@ -521,10 +521,6 @@ for r,d,flist in os.walk(path): effectively prefer RC4 when using given client, to make reporting more readable, sum it with sites that do that for all ciphers""" -for client_name in client_ciphers: - if 'x:' + client_name + ' RC4 Preferred' in cipherstats and 'RC4 Preferred' in cipherstats: - cipherstats['x:' + client_name + ' RC4 Preferred'] += cipherstats['RC4 Preferred'] - print("SSL/TLS survey of %i websites from Alexa's top 1 million" % total) if report_untrused == False: print("Stats only from connections that did provide valid certificates")