fragattack: bugfixes and move to new scapy

This commit is contained in:
Mathy Vanhoef 2021-01-13 04:18:13 +04:00
parent d3dcc2c449
commit cab3422a38
6 changed files with 19 additions and 13 deletions

View File

@ -24,11 +24,11 @@ the paper also briefly discusses the applicability of the attacks against WEP.
- This version is based on hostap commit `a337c1d7c` ("New TWT operations and attributes to TWT Setup and Nudge"). - This version is based on hostap commit `a337c1d7c` ("New TWT operations and attributes to TWT Setup and Nudge").
- Added a clarification to this README on how to use tcpdump to verify the result of certain tests.
- Added instructions on how to test WPA3/SAE devices using either the hunting-and-pecking or hash-to-element method. - Added instructions on how to test WPA3/SAE devices using either the hunting-and-pecking or hash-to-element method.
This also implies that Management Frame Protection (MFP) is supported by the test tool. This also implies that Management Frame Protection (MFP) is supported by the test tool.
- Added a clarification to this README on how to use tcpdump to verify the result of certain tests.
- Added the extra test `ping BP --bcast-ra --bcast-dst` to this README to be able to test for CVE-2020-26145 - Added the extra test `ping BP --bcast-ra --bcast-dst` to this README to be able to test for CVE-2020-26145
against APs that cannot run tcpdump (with this test tcpdump has to be run on an independent connected client). against APs that cannot run tcpdump (with this test tcpdump has to be run on an independent connected client).
@ -40,6 +40,9 @@ the paper also briefly discusses the applicability of the attacks against WEP.
- The python `requirements.txt` file now references a patched Scapy version to work around an - The python `requirements.txt` file now references a patched Scapy version to work around an
[incompatibility](https://github.com/secdev/scapy/commit/46fa40fde4049ad7770481f8806c59640df24059) with Python 3.9. [incompatibility](https://github.com/secdev/scapy/commit/46fa40fde4049ad7770481f8806c59640df24059) with Python 3.9.
- Fixed the `ping-frag-sep` test. Previously it behaved like `ping-frag-sep --pn-per-qos`. Note that this test
is not used to detect vulnerabilities but only to better understand implementations.
**Version 1.2 (15 November 2020)**: **Version 1.2 (15 November 2020)**:
- This version (and lower) is based on hostap commit `1c67a0760` ("tests: Add basic power saving tests for ap_open"). - This version (and lower) is based on hostap commit `1c67a0760` ("tests: Add basic power saving tests for ap_open").
@ -660,9 +663,9 @@ Finally, in case the test `ping-frag-sep` doesn't succeed, you should try the fo
## 8.4. Mixed plain/encrypt attack (§6.3 -- CVE-2020-26147) ## 8.4. Mixed plain/encrypt attack (§6.3 -- CVE-2020-26147)
- `ping I,E,E --amsdu`: This test sends a fragmented A-MSDU frame, which not all devices can properly receive. - `ping I,E,E --amsdu`: This test sends a fragmented A-MSDU frame, which not all devices can properly receive.
This test is useful to determine the practical exploitability of the "Mixed plain/encrypt attack". It does not test for a vulnerability. Instead, this test is useful to determine the practical exploitability
Summarized, if this tests succeeds, it's easier to attack the device if the second fragment can be sent of the "Mixed plain/encrypt attack". Namely, if this tests succeeds, it's easier to attack the device if the
in plaintext (test `ping I,E,P`). See Section 6.3 of the paper for details. second fragment can be sent in plaintext (test `ping I,E,P`). See Section 6.3 of the paper for details.
- `ping I,E,P,E` and `linux-plain 3`: If all the other mixed plain/encrypt attack tests didn't succeed, you - `ping I,E,P,E` and `linux-plain 3`: If all the other mixed plain/encrypt attack tests didn't succeed, you
can try these two extra tests as well. I think it's quite unlikely this will uncover a new vulnerability. can try these two extra tests as well. I think it's quite unlikely this will uncover a new vulnerability.

View File

@ -73,7 +73,7 @@ def prepare_tests(opt):
test = PingTest(REQ_ICMP, test = PingTest(REQ_ICMP,
[Action(Action.Connected, action=Action.GetIp), [Action(Action.Connected, action=Action.GetIp),
Action(Action.Connected, enc=True), Action(Action.Connected, enc=True),
Action(Action.Connected, enc=True, inc_pn=0)], Action(Action.Connected, enc=True)],
separate_with=separator, opt=opt) separate_with=separator, opt=opt)
elif opt.testname in ["eapol-inject", "eapol-inject-large"]: elif opt.testname in ["eapol-inject", "eapol-inject-large"]:

View File

@ -59,7 +59,7 @@ def freebsd_encap_eapolmsdu(p, src, dst, payload):
p.addr1 = "ff:ff:ff:ff:ff:ff" p.addr1 = "ff:ff:ff:ff:ff:ff"
# Encapsulate EAPOL in malformed EAPOL/A-MSDU fragment # Encapsulate EAPOL in malformed EAPOL/A-MSDU fragment
p.Reserved = 1 p.A_MSDU_Present = 1
p = p/freebsd_create_eapolmsdu(src, dst, payload) p = p/freebsd_create_eapolmsdu(src, dst, payload)
@ -624,6 +624,9 @@ class Station():
self.time_connected = None self.time_connected = None
self.handle_connected() self.handle_connected()
elif self.time_authdone != None and time.time() > self.time_authdone: elif self.time_authdone != None and time.time() > self.time_authdone:
if self.options.freebsd_cache:
log(ERROR, "The 4-way handshake has timed out, perhaps due to usage of the --freebsd parameter.")
else:
log(ERROR, "The 4-way handshake has timed out for an unknown reason.") log(ERROR, "The 4-way handshake has timed out for an unknown reason.")
self.time_authdone = None self.time_authdone = None
self.stop_test() self.stop_test()

@ -1 +1 @@
Subproject commit 8c6a23dfae62da61c88bfcc18bbb4bc4fd578aa9 Subproject commit efd0f0f571f286768d057d81731ca63bdb3eb75c

View File

@ -42,7 +42,7 @@ class AmsduInject(Test):
p = header/LLC()/SNAP()/IP(dst="192.168.1.2", src="3.5.1.1")/TCP()/Raw(b"A" * 748) p = header/LLC()/SNAP()/IP(dst="192.168.1.2", src="3.5.1.1")/TCP()/Raw(b"A" * 748)
p = p/create_msdu_subframe(src, dst, request, last=True) p = p/create_msdu_subframe(src, dst, request, last=True)
p[Dot11QoS].Reserved = 1 p[Dot11QoS].A_MSDU_Present = 1
# Schedule transmission of frame # Schedule transmission of frame
self.actions[0].frame = p self.actions[0].frame = p

View File

@ -58,12 +58,12 @@ class PingTest(Test):
if self.as_msdu == 1: if self.as_msdu == 1:
# Set the A-MSDU frame type flag in the QoS header # Set the A-MSDU frame type flag in the QoS header
header.Reserved = 1 header.A_MSDU_Present = 1
# Encapsulate the request in an A-MSDU payload # Encapsulate the request in an A-MSDU payload
request = create_msdu_subframe(station.mac, station.get_peermac(), request) request = create_msdu_subframe(station.mac, station.get_peermac(), request)
elif self.as_msdu == 2: elif self.as_msdu == 2:
# Set A-MSDU flag but include a normal payload (fake A-MSDU) # Set A-MSDU flag but include a normal payload (fake A-MSDU)
header.Reserved = 1 header.A_MSDU_Present = 1
# Generate all the individual (fragmented) frames # Generate all the individual (fragmented) frames
num_frags = len(self.get_actions(Action.Inject)) num_frags = len(self.get_actions(Action.Inject))
@ -237,7 +237,7 @@ class EapolAmsduTest(Test):
# Generate the single frame # Generate the single frame
header, request, check_fn = generate_request(station, self.ptype, dport=self.dport) header, request, check_fn = generate_request(station, self.ptype, dport=self.dport)
# Set the A-MSDU frame type flag in the QoS header # Set the A-MSDU frame type flag in the QoS header
header.Reserved = 1 header.A_MSDU_Present = 1
# We can automatically detect the result if the last fragment was sent after a connected event. # We can automatically detect the result if the last fragment was sent after a connected event.
# Note we might get a reply during a rekey handshake, and this will be handled properly. # Note we might get a reply during a rekey handshake, and this will be handled properly.