From e94b04ff57060fa2aae7990c07413e3551bbe4ab Mon Sep 17 00:00:00 2001 From: Mathy Vanhoef Date: Wed, 4 Nov 2020 12:26:50 +0400 Subject: [PATCH] fragattack: check if hostapd/wpa_sup was recompiled on updates --- hostapd/ctrl_iface.c | 4 ++++ research/fragattack.py | 6 ++---- research/fraginternals.py | 12 +++++++++++- wpa_supplicant/ctrl_iface.c | 4 ++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index e7596bcb2..cbe074a95 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -80,6 +80,8 @@ static unsigned char gcookie[COOKIE_LEN]; #define HOSTAPD_GLOBAL_CTRL_IFACE_PORT_LIMIT 50 #endif /* CONFIG_CTRL_IFACE_UDP */ +const char *FRAGATTACK_VERSION = "1.2"; + static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level, enum wpa_msg_type type, const char *buf, size_t len); @@ -3384,6 +3386,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, reply_len = hostapd_get_gtk(hapd, reply, reply_size); } else if (os_strcmp(buf, "GET_CHANNEL") == 0) { reply_len = hostapd_get_channel(hapd, reply, reply_size); + } else if (os_strcmp(buf, "GET_VERSION") == 0) { + reply_len = os_snprintf(reply, reply_size, "%s\n", FRAGATTACK_VERSION); #endif /* CONFIG_TESTING_OPTIONS */ } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12)) diff --git a/research/fragattack.py b/research/fragattack.py index 69971557c..c3f4af62a 100755 --- a/research/fragattack.py +++ b/research/fragattack.py @@ -8,8 +8,6 @@ import glob, importlib, argparse from fraginternals import * -FRAGVERSION = "1.1 - 20 October 2020" - # ----------------------------------- Main Function ----------------------------------- def cleanup(): @@ -167,7 +165,7 @@ def args2msdu(args): return None if __name__ == "__main__": - parser = argparse.ArgumentParser(description=f"Test for fragmentation vulnerabilities (v{FRAGVERSION}).") + parser = argparse.ArgumentParser(description=f"Test for fragmentation vulnerabilities (v{FRAGVERSION} - {FRAGDATE}).") parser.add_argument('iface', help="Interface to use for the tests.") parser.add_argument('testname', help="Name or identifier of the test to run.") parser.add_argument('actions', nargs='?', help="Optional textual descriptions of actions") @@ -242,7 +240,7 @@ if __name__ == "__main__": change_log_level(-options.debug) # Now start the tests --- TODO: Inject Deauths before connecting with client... - log(STATUS, f"This is fragattack version {FRAGVERSION}.") + log(STATUS, f"This is fragattack version {FRAGVERSION} - {FRAGDATE}.") if options.ap: daemon = Authenticator(options) else: diff --git a/research/fraginternals.py b/research/fraginternals.py index 65ed188a4..389f99d92 100644 --- a/research/fraginternals.py +++ b/research/fraginternals.py @@ -11,6 +11,9 @@ from wpaspy import Ctrl from scapy.contrib.wpa_eapol import WPA_key from scapy.arch.common import get_if_raw_hwaddr +FRAGVERSION = "1.2" +FRAGDATE = "27 October 2020" + # ----------------------------------- Utility Commands ----------------------------------- def croprepr(p, length=175): @@ -683,7 +686,7 @@ class Daemon(metaclass=abc.ABCMeta): response = self.wpaspy_ctrl.recv() if "UNKNOWN COMMAND" in response: - log(ERROR, "wpa_supplicant did not recognize the command %s. Did you (re)compile wpa_supplicant?" % cmd.split()[0]) + log(ERROR, "wpa_supplicant did not recognize the command %s. Did you (re)compile wpa_supplicant/hostapd?" % cmd.split()[0]) quit(1) elif "FAIL" in response: log(ERROR, f"Failed to execute command {cmd}") @@ -854,6 +857,13 @@ class Daemon(metaclass=abc.ABCMeta): if self.nic_hwsim: self.sock_hwsim = MonitorSocket(type=ETH_P_ALL, iface=self.nic_hwsim) + # Verify that hostap got recompiled on updates + version = self.wpaspy_command("GET_VERSION").strip() + if version != FRAGVERSION: + log(ERROR, f"Script has test tool version {FRAGVERSION} but compiled wpa_supplicant/hostapd is {version}.") + log(ERROR, f"Please recompile hostapd/wpa_supplicant using `build.sh`.") + quit(1) + # Post-startup configuration of the supplicant or AP self.wpaspy_command("SET ext_eapol_frame_io 1") self.configure_daemon() diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index c621a1074..6d996c473 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -68,6 +68,8 @@ #include #endif +const char *FRAGATTACK_VERSION = "1.2"; + static int wpa_supplicant_global_iface_list(struct wpa_global *global, char *buf, int len); static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, @@ -10865,6 +10867,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, reply_len = wpa_supplicant_ctrl_iface_get_gtk(wpa_s, reply, reply_size); } else if (os_strcmp(buf, "GET_CHANNEL") == 0) { reply_len = wpa_supplicant_ctrl_iface_get_channel(wpa_s, reply, reply_size); + } else if (os_strcmp(buf, "GET_VERSION") == 0) { + reply_len = os_snprintf(reply, reply_size, "%s\n", FRAGATTACK_VERSION); } else if (os_strcmp(buf, "GET_ASSOC_RESP_IES") == 0) { reply_len = wpas_ctrl_get_assoc_resp_ies(wpa_s, reply, reply_size); } else if (os_strncmp(buf, "SET_ASSOC_RESP_IES ", 19) == 0) {