diff --git a/nogotofail/clients/android/app/src/main/java/net/nogotofail/AttacksPreferenceFragment.java b/nogotofail/clients/android/app/src/main/java/net/nogotofail/AttacksPreferenceFragment.java
index 68fe9d23..336ea487 100644
--- a/nogotofail/clients/android/app/src/main/java/net/nogotofail/AttacksPreferenceFragment.java
+++ b/nogotofail/clients/android/app/src/main/java/net/nogotofail/AttacksPreferenceFragment.java
@@ -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("noforwardsecrecy");
}
private static final String ATTACK_ENABLED_PREF_KEY_PREFIX = "attack_enabled_";
diff --git a/nogotofail/clients/android/app/src/main/res/values/strings.xml b/nogotofail/clients/android/app/src/main/res/values/strings.xml
index 11057cf8..eb75e941 100644
--- a/nogotofail/clients/android/app/src/main/res/values/strings.xml
+++ b/nogotofail/clients/android/app/src/main/res/values/strings.xml
@@ -94,6 +94,8 @@
Downgrade of HTTPS to HTTP
Downgrade of STARTTLS-protected XMPP to cleartext
+
+ Cipher key exchange doesn\'t support forward secrecy
Notifications
Notifications
@@ -159,7 +161,9 @@
XMPP credentials/auth token compromise
XMPP STARTTLS strip
Downgrade of STARTTLS-protected XMPP to cleartext
-
+ Cipher key exchange doesn\'t support forward secrecy
+ Cipher suite key exchange technique doesn\'t support forward secrecy.
+
Advanced
MiTM controller
diff --git a/nogotofail/mitm/connection/handlers/data/ssl.py b/nogotofail/mitm/connection/handlers/data/ssl.py
index 30e3a74e..39cd70b9 100644
--- a/nogotofail/mitm/connection/handlers/data/ssl.py
+++ b/nogotofail/mitm/connection/handlers/data/ssl.py
@@ -19,7 +19,10 @@
from nogotofail.mitm.connection.handlers.data import DataHandler
from nogotofail.mitm.connection.handlers.store import handler
from nogotofail.mitm.event import connection
+from nogotofail.mitm import util
from nogotofail.mitm.util import ssl2, tls, vuln
+from nogotofail.mitm.util.tls.types import HandshakeMessage
+
class _TlsRecordHandler(DataHandler):
"""Base class for a handler that acts on TlsRecords in a Tls connection.
@@ -131,7 +134,7 @@ def on_ssl(self, client_hello):
(", ".join(null_ciphers)))
# Check for NULL integrity ciphers
- integ_ciphers = [str(c) for c in client_hello.ciphers if str(c).endswith("_NULL")]
+ integ_ciphers = [str(c) for c in client_hello.ciphers if str(c).endswith("_NULL")]
if integ_ciphers:
self._handle_bad_ciphers(integ_ciphers,
"Client enabled NULL integrity TLS/SSL cipher suites %s" %
@@ -172,3 +175,46 @@ def on_ssl(self, client_hello):
self.log(logging.ERROR,
"Client enabled SSLv3 protocol without TLS_FALLBACK_SCSV")
self.log_attack_event(data="SSLv3")
+
+
+@handler.passive(handlers)
+class NoForwardSecrecy(_TlsRecordHandler):
+ name = "noforwardsecrecy"
+ description = (
+ "Detects selected server cipher suites which don't support "
+ "Diffie-Hellman key exchange (DHE or ECDHE) i.e. in SERVER_HELLO "
+ "response")
+
+ def on_tls_response(self, record):
+ try:
+ for i, message in enumerate(record.messages):
+ # Check for Server Hello message
+ if (isinstance(message, tls.types.HandshakeMessage) and
+ message.type == HandshakeMessage.TYPE.SERVER_HELLO):
+ server_hello = message.obj
+ selected_cipher = str(server_hello.cipher)
+ _connection = self.connection
+ destination = _connection.hostname if \
+ _connection.hostname else _connection.server_addr
+ debug_message = ["Selected cipher \"", selected_cipher,
+ "\" for connection to \"", destination, "\""]
+ self.log(logging.DEBUG, "".join(debug_message))
+ """ Check if Ephemeral Diffie-Hellman key exchange is
+ used in selected cipher """
+ fs_key_strings = ["DHE", "ECDHE"]
+ if not [fs_string for fs_string in fs_key_strings
+ if fs_string in selected_cipher]:
+ error_message = \
+ ["Cipher suite key exhange technqiue doesn't ",
+ "support forward secrecy. ",
+ "Cipher suite - [", selected_cipher, "]"]
+ self.log(logging.INFO, "".join(error_message))
+ self.log_event(logging.INFO,
+ connection.AttackEvent(
+ self.connection, self.name, True, ""))
+ self.connection.vuln_notify(
+ util.vuln.VULN_NO_FORWARD_SECRECY)
+ except AttributeError:
+ # Where TLS record contains no messages ignore exception raised.
+ pass
+ return record.to_bytes()
diff --git a/nogotofail/mitm/util/vuln.py b/nogotofail/mitm/util/vuln.py
index 2de2f0f4..a8ab9837 100644
--- a/nogotofail/mitm/util/vuln.py
+++ b/nogotofail/mitm/util/vuln.py
@@ -30,3 +30,4 @@
VULN_WEAK_TLS_VERSION = "weaktlsversion"
VULN_TLS_SERVER_KEY_REPLACEMENT = "serverkeyreplace"
VULN_TLS_SUPERFISH_TRUSTED = "superfishca"
+VULN_NO_FORWARD_SECRECY = "noforwardsecrecy"