Skip to content
This repository has been archived by the owner on Dec 6, 2023. It is now read-only.

Commit

Permalink
Added a new connection handler "sunsetsha1" to test for TLS certifica…
Browse files Browse the repository at this point in the history
…tes using the SHA-1 signature algorithm which expire during or after the Google Chrome SHA-1 sunset period.

Changes were made to the mitm daemon and Android client for this handler.

See Chromium blog post for more details:
http://blog.chromium.org/2014/09/gradually-sunsetting-sha-1.html
  • Loading branch information
yzninja committed Jul 24, 2015
1 parent 9353551 commit bf8dbab
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 0 deletions.
4 changes: 4 additions & 0 deletions nogotofail/clients/android/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@
<string name="vuln_sslstrip">Downgrade of HTTPS to HTTP</string>
<!-- Vulnerability: XMPP STARTTLS strip -->
<string name="vuln_xmppstarttlsstrip">Downgrade of STARTTLS-protected XMPP to cleartext</string>
<!-- Vulnerability: Certificate uses SHA-1 and expires after a Chrome sunset date -->
<string name="vuln_sunsetsha1">Certificate uses SHA-1 and expires after a Chrome sunset date</string>

<string name="notifications_pref_screen_title">Notifications</string>
<string name="vuln_notifications_enabled_pref_title">Notifications</string>
Expand Down Expand Up @@ -159,6 +161,8 @@
<string name="attack_summary_xmppauthdetection">XMPP credentials/auth token compromise</string>
<string name="attack_title_xmppstarttlsstrip">XMPP STARTTLS strip</string>
<string name="attack_summary_xmppstarttlsstrip">Downgrade of STARTTLS-protected XMPP to cleartext</string>
<string name="attack_title_sunsetsha1">Certificate uses SHA-1 and expires after sunset date</string>
<string name="attack_summary_sunsetsha1">Certificate uses SHA-1 and expires after a Chrome sunset date</string>

<string name="advanced_pref_screen_title">Advanced</string>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class AttacksPreferenceFragment extends PreferenceFragment {
BUNDLED_SUPPORTED_DATA_ATTACK_IDS.add("httpdetection");
BUNDLED_SUPPORTED_DATA_ATTACK_IDS.add("imagereplace");
BUNDLED_SUPPORTED_DATA_ATTACK_IDS.add("sslstrip");
BUNDLED_SUPPORTED_DATA_ATTACK_IDS.add("sunsetsha1");
}

private static final String ATTACK_ENABLED_PREF_KEY_PREFIX = "attack_enabled_";
Expand Down
1 change: 1 addition & 0 deletions nogotofail/mitm/connection/handlers/connection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@
from droptls import DropTLS
from ccs import EarlyCCS
from serverkeyreplace import ServerKeyReplacementMITM
from sunsetsha1 import SunsetSHA1
99 changes: 99 additions & 0 deletions nogotofail/mitm/connection/handlers/connection/sunsetsha1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
r'''
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''
import logging
from nogotofail.mitm.connection.handlers.connection import handlers
from nogotofail.mitm.connection.handlers.store import handler
from nogotofail.mitm.event import connection
from nogotofail.mitm.connection.handlers.connection import LoggingHandler
from nogotofail.mitm import util
from datetime import datetime


@handler(handlers, default=True)
class SunsetSHA1(LoggingHandler):

name = "sunsetsha1"
description = (
"Detects TLS certificates using the SHA-1 signature algorithm that "
"expire during of after the Google Chrome sunset period.")

ca = util.CertificateAuthority()
certificate = None

def on_ssl(self, client_hello):
self.ssl = True
return True

def on_certificate(self, server_cert):
CRT_DATE_FORMAT = "%Y%m%d%H%M%SZ"
subject = server_cert.get_subject()
crt_signature_algorithm = server_cert.get_signature_algorithm()

if ("sha1" in crt_signature_algorithm):
""" SHA-1 sunset dates based on Google Chrome dates published dates. See
http://googleonlinesecurity.blogspot.com/2014/09/gradually-sunsetting-sha-1.html
"""
sunset_warning_date = datetime.strptime("31-12-2015", "%d-%m-%Y")
sunset_error_date = datetime.strptime("30-06-2016", "%d-%m-%Y")
sunset_critical_date = datetime.strptime("31-12-2016", "%d-%m-%Y")
crt_CN = subject.CN
crt_not_before = server_cert.get_notBefore()
crt_not_after = server_cert.get_notAfter()
debug_message = \
["Certicate using SHA-1 with attributes - CN \"", crt_CN,
"\", notBefore \"", crt_not_before,
"\", notAfter \"", crt_not_after,
"\", signature_algorithm \"", crt_signature_algorithm, "\""]
self.log(logging.DEBUG, "".join(debug_message))

crt_not_after = datetime.strptime(crt_not_after, CRT_DATE_FORMAT)
""" Raise notification if certificate expires after a Chrome sunset
date """
if (crt_not_after > sunset_critical_date):
log_message = \
["Certificate with CN ", crt_CN,
" uses SHA-1 and expires after 31 Dec 2016"]
self.log(logging.CRITICAL, "".join(log_message))
self.log_event(logging.CRITICAL, connection.AttackEvent(
self.connection, self.name, True, ""))
self.connection.vuln_notify(util.vuln.VULN_SUNSET_SHA1)
elif (crt_not_after > sunset_error_date):
log_message = \
["Certificate with CN ", crt_CN,
" uses SHA-1 and expires after 30 Jun 2016"]
self.log(logging.ERROR, "".join(log_message))
self.log_event(logging.ERROR, connection.AttackEvent(
self.connection, self.name, True, ""))
self.connection.vuln_notify(util.vuln.VULN_SUNSET_SHA1)
elif (crt_not_after > sunset_warning_date):
log_message = \
["Certificate with CN ", crt_CN,
" uses SHA-1 and expires after 31 Dec 2015"]
self.log(logging.WARNING, "".join(log_message))
self.log_event(logging.WARNING, connection.AttackEvent(
self.connection, self.name, True, ""))
self.connection.vuln_notify(util.vuln.VULN_SUNSET_SHA1)
""" Fetch and return certificate """
for k, v in subject.get_components():
if k == "CN":
cn = v
extensions = [server_cert.get_extension(i)
for i in range(server_cert.get_extension_count())]
altnames = [extension for extension in extensions
if extension.get_short_name() == "subjectAltName"]
san = altnames[0] if len(altnames) > 0 else None
self.certificate = self.ca.get_cert(cn, san)
return self.certificate
1 change: 1 addition & 0 deletions nogotofail/mitm/util/vuln.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@
VULN_WEAK_TLS_VERSION = "weaktlsversion"
VULN_TLS_SERVER_KEY_REPLACEMENT = "serverkeyreplace"
VULN_TLS_SUPERFISH_TRUSTED = "superfishca"
VULN_SUNSET_SHA1 = "sunsetsha1"

0 comments on commit bf8dbab

Please sign in to comment.