mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-02-17 17:43:06 -05:00
fragattack: improve DHCP handling
This commit is contained in:
parent
ff8ca7f186
commit
c726feed53
@ -156,14 +156,13 @@ class Test(metaclass=abc.ABCMeta):
|
|||||||
self.generate(station)
|
self.generate(station)
|
||||||
self.generated = True
|
self.generated = True
|
||||||
|
|
||||||
return self.actions[0]
|
act = self.actions[0]
|
||||||
|
del self.actions[0]
|
||||||
|
return act
|
||||||
|
|
||||||
def get_actions(self, action):
|
def get_actions(self, action):
|
||||||
return [act for act in self.actions if act.action == action]
|
return [act for act in self.actions if act.action == action]
|
||||||
|
|
||||||
def pop_action(self):
|
|
||||||
del self.actions[0]
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def generate(self, station):
|
def generate(self, station):
|
||||||
pass
|
pass
|
||||||
@ -368,6 +367,7 @@ class Station():
|
|||||||
self.txed_before_auth = False
|
self.txed_before_auth = False
|
||||||
self.txed_before_auth_done = False
|
self.txed_before_auth_done = False
|
||||||
self.obtained_ip = False
|
self.obtained_ip = False
|
||||||
|
self.waiting_on_ip = False
|
||||||
|
|
||||||
# Don't reset PN to have consistency over rekeys and reconnects
|
# Don't reset PN to have consistency over rekeys and reconnects
|
||||||
self.reset_keys()
|
self.reset_keys()
|
||||||
@ -394,6 +394,7 @@ class Station():
|
|||||||
self.othermac = None
|
self.othermac = None
|
||||||
self.otherip = None
|
self.otherip = None
|
||||||
|
|
||||||
|
# To trigger Connected event 1-2 seconds after Authentication
|
||||||
self.time_connected = None
|
self.time_connected = None
|
||||||
|
|
||||||
def reset_keys(self):
|
def reset_keys(self):
|
||||||
@ -550,23 +551,12 @@ class Station():
|
|||||||
while self.test.next_trigger_is(trigger):
|
while self.test.next_trigger_is(trigger):
|
||||||
act = self.test.next_action(self)
|
act = self.test.next_action(self)
|
||||||
|
|
||||||
# GetIp is a special case. It is only popped when we actually
|
|
||||||
# have an IP. So handle if first as a special case.
|
|
||||||
# TODO: Actually "complete" the action once we have an IP.
|
|
||||||
if act.action == Action.GetIp and not self.obtained_ip:
|
if act.action == Action.GetIp and not self.obtained_ip:
|
||||||
# (Re)transmit DHCP frames (or as AP print status message)
|
self.waiting_on_ip = True
|
||||||
self.daemon.get_ip(self)
|
self.daemon.get_ip(self)
|
||||||
# Either schedule a new Connected event, or the initial one. Use 2 seconds
|
|
||||||
# because requesting IP generally takes a bit of time.
|
|
||||||
# TODO: Add an option to configure this timeout.
|
|
||||||
self.time_connected = time.time() + 1
|
|
||||||
log(WARNING, f"Scheduling next Action.Connected at {self.time_connected}")
|
|
||||||
break
|
break
|
||||||
|
|
||||||
# All the other actions are always popped
|
elif act.action == Action.Func:
|
||||||
self.test.pop_action()
|
|
||||||
|
|
||||||
if act.action == Action.Func:
|
|
||||||
log(STATUS, "[Executing Function]")
|
log(STATUS, "[Executing Function]")
|
||||||
if act.func(self) != None:
|
if act.func(self) != None:
|
||||||
break
|
break
|
||||||
@ -636,10 +626,12 @@ class Station():
|
|||||||
self.peerip = peerip
|
self.peerip = peerip
|
||||||
self.obtained_ip = True
|
self.obtained_ip = True
|
||||||
|
|
||||||
|
if self.waiting_on_ip:
|
||||||
|
self.waiting_on_ip = False
|
||||||
|
self.perform_actions(Action.Connected)
|
||||||
|
|
||||||
def time_tick(self):
|
def time_tick(self):
|
||||||
if self.time_connected != None and time.time() > self.time_connected:
|
if self.time_connected != None and time.time() > self.time_connected:
|
||||||
# Note that handle_connected may schedule a new Connected event, so it's
|
|
||||||
# important to clear time_connected *before* calling handle_connected.
|
|
||||||
self.time_connected = None
|
self.time_connected = None
|
||||||
self.handle_connected()
|
self.handle_connected()
|
||||||
|
|
||||||
@ -905,6 +897,8 @@ class Supplicant(Daemon):
|
|||||||
self.station = None
|
self.station = None
|
||||||
self.arp_sock = None
|
self.arp_sock = None
|
||||||
self.dhcp_xid = None
|
self.dhcp_xid = None
|
||||||
|
self.dhcp_offer_frame = False
|
||||||
|
self.time_retrans_dhcp = None
|
||||||
|
|
||||||
def get_tk(self, station):
|
def get_tk(self, station):
|
||||||
tk = wpaspy_command(self.wpaspy_ctrl, "GET tk")
|
tk = wpaspy_command(self.wpaspy_ctrl, "GET tk")
|
||||||
@ -914,7 +908,12 @@ class Supplicant(Daemon):
|
|||||||
return bytes.fromhex(tk)
|
return bytes.fromhex(tk)
|
||||||
|
|
||||||
def get_ip(self, station):
|
def get_ip(self, station):
|
||||||
self.send_dhcp_discover()
|
if not self.dhcp_offer_frame:
|
||||||
|
self.send_dhcp_discover()
|
||||||
|
else:
|
||||||
|
self.send_dhcp_request(self.dhcp_offer_frame)
|
||||||
|
|
||||||
|
self.time_retrans_dhcp = time.time() + 1
|
||||||
|
|
||||||
def rekey(self, station):
|
def rekey(self, station):
|
||||||
# WAG320N: does not work (Broadcom - no reply)
|
# WAG320N: does not work (Broadcom - no reply)
|
||||||
@ -930,6 +929,9 @@ class Supplicant(Daemon):
|
|||||||
log(STATUS, "Client cannot force rekey. Waiting on AP to start PTK rekey.", color="orange")
|
log(STATUS, "Client cannot force rekey. Waiting on AP to start PTK rekey.", color="orange")
|
||||||
|
|
||||||
def time_tick(self):
|
def time_tick(self):
|
||||||
|
if self.time_retrans_dhcp != None and time.time() > self.time_retrans_dhcp:
|
||||||
|
self.get_ip(self)
|
||||||
|
|
||||||
self.station.time_tick()
|
self.station.time_tick()
|
||||||
|
|
||||||
def send_dhcp_discover(self):
|
def send_dhcp_discover(self):
|
||||||
@ -968,14 +970,16 @@ class Supplicant(Daemon):
|
|||||||
if req_type == 2:
|
if req_type == 2:
|
||||||
log(STATUS, "Received DHCP offer, sending DHCP request.")
|
log(STATUS, "Received DHCP offer, sending DHCP request.")
|
||||||
self.send_dhcp_request(p)
|
self.send_dhcp_request(p)
|
||||||
self.initialize_peermac(p.src)
|
self.dhcp_offer_frame = p
|
||||||
|
|
||||||
# DHCP Ack
|
# DHCP Ack
|
||||||
elif req_type == 5:
|
elif req_type == 5:
|
||||||
clientip = p[BOOTP].yiaddr
|
clientip = p[BOOTP].yiaddr
|
||||||
serverip = p[IP].src
|
serverip = p[IP].src
|
||||||
|
self.time_retrans_dhcp = None
|
||||||
log(STATUS, f"Received DHCP ack. My ip is {clientip} and router is {serverip}.")
|
log(STATUS, f"Received DHCP ack. My ip is {clientip} and router is {serverip}.")
|
||||||
|
|
||||||
|
self.initialize_peermac(p.src)
|
||||||
self.initialize_ips(clientip, serverip)
|
self.initialize_ips(clientip, serverip)
|
||||||
|
|
||||||
def initialize_peermac(self, peermac):
|
def initialize_peermac(self, peermac):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user