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").
- 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.
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
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
[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)**:
- 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)
- `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".
Summarized, if this tests succeeds, it's easier to attack the device if the second fragment can be sent
in plaintext (test `ping I,E,P`). See Section 6.3 of the paper for details.
It does not test for a vulnerability. Instead, this test is useful to determine the practical exploitability
of the "Mixed plain/encrypt attack". Namely, if this tests succeeds, it's easier to attack the device if the
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
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,
[Action(Action.Connected, action=Action.GetIp),
Action(Action.Connected, enc=True),
Action(Action.Connected, enc=True, inc_pn=0)],
Action(Action.Connected, enc=True)],
separate_with=separator, opt=opt)
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"
# Encapsulate EAPOL in malformed EAPOL/A-MSDU fragment
p.Reserved = 1
p.A_MSDU_Present = 1
p = p/freebsd_create_eapolmsdu(src, dst, payload)
@ -624,7 +624,10 @@ class Station():
self.time_connected = None
self.handle_connected()
elif self.time_authdone != None and time.time() > self.time_authdone:
log(ERROR, "The 4-way handshake has timed out for an unknown reason.")
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.")
self.time_authdone = None
self.stop_test()
elif self.test != None and self.test.timedout():

@ -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 = p/create_msdu_subframe(src, dst, request, last=True)
p[Dot11QoS].Reserved = 1
p[Dot11QoS].A_MSDU_Present = 1
# Schedule transmission of frame
self.actions[0].frame = p

View File

@ -58,12 +58,12 @@ class PingTest(Test):
if self.as_msdu == 1:
# 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
request = create_msdu_subframe(station.mac, station.get_peermac(), request)
elif self.as_msdu == 2:
# 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
num_frags = len(self.get_actions(Action.Inject))
@ -237,7 +237,7 @@ class EapolAmsduTest(Test):
# Generate the single frame
header, request, check_fn = generate_request(station, self.ptype, dport=self.dport)
# 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.
# Note we might get a reply during a rekey handshake, and this will be handled properly.