Skip to content
This repository was archived by the owner on Dec 6, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions docs/gce/_update_dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/sh

set -e

# Directory paths used for nogotofail.
INSTALL_DIR=/opt/nogotofail
CONFIG_DIR=/etc/nogotofail
LOG_DIR=/var/log/nogotofail

# Stop the nogotofail-mitm and other associated services if they're running.
if (ps ax | grep -v grep | grep nogotofail-mitm > /dev/null) then
sudo /etc/init.d/nogotofail-mitm stop
fi
if (ps ax | grep -v grep | grep dnsmasq > /dev/null) then
sudo /etc/init.d/dnsmasq stop
fi
if (ps ax | grep -v grep | grep openvpn > /dev/null) then
sudo /etc/init.d/openvpn stop
fi
# Remove Python files and compiled versions i.e. *.py and *.pyc files.
# TODO: Find a more elegant method for uninstalling a Python program.
#rm -rf $INSTALL_DIR
#rm -rf $CONFIG_DIR
#rm -rf $LOG_DIR
find $INSTALL_DIR -type f -name '*.py' -delete
find $INSTALL_DIR -type f -name '*.pyc' -delete

# Install toolchain dependencies
sudo apt-get update
sudo apt-get -y upgrade
#sudo apt-get -y install patch make gcc libssl-dev python-openssl liblzo2-dev libpam-dev

# Install OpenVPN and dnsmasq
#sudo apt-get -y install openvpn dnsmasq

# Build and install a patched version of OpenVPN.
# This is needed because the OpenVPN 2.3.x still does not properly handle
# floating clients (those whose source IP address as seen by the server changes
# from time to time) which is a regular occurrence in the mobile world.
# OpenVPN 2.4 might ship with proper support out of the box. In that case, this
# kludge can be removed.
#./build_openvpn.sh

# Build and install a patched version of dnsmasq.
# This is needed because GCE does not support IPv6. We thus blackhole IPv6
# traffic from clients so that they are forced to use IPv4. However, default
# DNS servers will still resolve hostnames to IPv6 addresses causing clients to
# attempt IPv6. To avoid clients attempting IPv6, we run a patched dnsmasq DNS
# server which empties AAAA records thus causing clients to go for A records
# which provide IPv4 addresses.
#./build_dnsmasq.sh

# Set up OpenVPN server
#sudo ./setup_openvpn.sh

# Set up the MiTM daemons
sudo ./setup_mitm.sh

# Move dev mitm.conf file into /etc/nogotofail directory
sudo cp /home/michael/noseyp_setup/ngtf_mitm.conf /etc/nogotofail/mitm.conf

# Restart all the relevant daemons
sudo /etc/init.d/dnsmasq start
sudo /etc/init.d/openvpn start
#sudo /etc/init.d/nogotofail-mitm stop || true
sudo /etc/init.d/nogotofail-mitm start
6 changes: 5 additions & 1 deletion 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: Cipher key exchange doesn't support forward secrecy -->
<string name="vuln_noforwardsecrecy">Cipher key exchange doesn\'t support forward secrecy</string>

<string name="notifications_pref_screen_title">Notifications</string>
<string name="vuln_notifications_enabled_pref_title">Notifications</string>
Expand Down Expand Up @@ -159,7 +161,9 @@
<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_noforwardsecrecy">Cipher key exchange doesn\'t support forward secrecy</string>
<string name="attack_summary_noforwardsecrecy">Cipher suite key exchange technique doesn\'t support forward secrecy.</string>

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

<string name="mitm_server_pref_category_title">MiTM controller</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("noforwardsecrecy");
}

private static final String ATTACK_ENABLED_PREF_KEY_PREFIX = "attack_enabled_";
Expand Down
73 changes: 72 additions & 1 deletion nogotofail/mitm/connection/handlers/data/ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, TlsRecord


@handler.passive(handlers)
class InsecureCipherDetectionHandler(DataHandler):
Expand Down Expand Up @@ -49,7 +52,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" %
Expand Down Expand Up @@ -90,3 +93,71 @@ 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(DataHandler):
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")

buffer = ""
ssl = False

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

def on_response(self, response):
if not self.ssl:
return response
response = self.buffer + response
self.buffer = ""
try:
index = 0
while index < len(response):
record, size = TlsRecord.from_stream(response[index:])
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.WARNING, "".join(error_message))
self.log_event(logging.WARNING,
connection.AttackEvent(
self.connection, self.name, True, ""))
self.connection.vuln_notify(
util.vuln.VULN_NO_FORWARD_SECRECY)
return response
index += size
except ValueError:
# Failed to parse TLS, this is probably due to a short read of a TLS
# record. Buffer the response to try and get more data.
self.buffer = response
# But don't buffer too much, give up after 16k.
if len(self.buffer) > 2**14:
response = self.buffer
self.buffer = ""
return self.buffer
return ""
return response
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_NO_FORWARD_SECRECY = "noforwardsecrecy"