mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-02-17 17:43:06 -05:00
fragattack: code to rekey the PTK
This commit is contained in:
parent
22f603ceac
commit
9f44009b47
@ -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;
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user