From 83c4ef27e0220d3f11ab56471f429039a66f507d Mon Sep 17 00:00:00 2001 From: Mathy Vanhoef Date: Sun, 28 Jun 2020 12:55:11 +0400 Subject: [PATCH] fragattack: improved injection tests --- research/DEVICES.md | 16 +++++++++------- research/README.md | 36 ++++++++++++++++++++++++++++++------ research/fraginternals.py | 2 +- research/libwifi | 2 +- research/test-injection.py | 13 +++++-------- 5 files changed, 46 insertions(+), 23 deletions(-) diff --git a/research/DEVICES.md b/research/DEVICES.md index cc468c0ab..96d659baf 100644 --- a/research/DEVICES.md +++ b/research/DEVICES.md @@ -97,8 +97,15 @@ Summary: when using this device, you must use a modified driver/firmware. and commenting out the two lines that modify `i_seq`. Note that these changes are in the firmware of the device. -- See also the comment in Station.perform_actions to avoid other bugs with - ath9k_htc when injecting frames with the MF flag and while being in AP mode. +- After injecting a _fragmented_ frame with a valid sender MAC + address, it will not properly inject other frames with a valid sender MAC + address. This was not tested in other orders (i.e. it might be possible that + using a spoofed MAC address to inject a fragmented frame, injecting frames + afterwards with the same spoofed MAC address might also fail). + +- In mixed AP/monitor mode, when injecting the first fragment of a frame, it will + be injected properly, but afterards the chip won't second beacons for one second. + This can be prevented by injected a dummy packet after the injected fragment. - The at9k_htc dongle, like other Wi-Fi devices, will reorder frames with different QoS priorities. This means injected frames with differen priorities @@ -116,11 +123,6 @@ Summary: when using this device, you must use a modified driver/firmware. used). When connecting using wpa_supplicant, it seems we can only inject frames after the association request has been sent. -- In mixed AP/monitor mode, when injecting the first fragment of a frame, it will - be injected properly, but afterards the chip won't second beacons for one second. - This can be prevented by injected a dummy packet after the injected fragment. - In other modes this doesn't seem to be a problem. - # hwsim mode - Linux clients need an authentication response _fast_ and we are too slow. Perhaps diff --git a/research/README.md b/research/README.md index 9bc60cbaa..f2808f586 100644 --- a/research/README.md +++ b/research/README.md @@ -35,6 +35,8 @@ We have confirmed that the following network cards work properly with our script **TODO: AWUS036ACM `iw set wlanX monitor active` in injection mode (but in mixed mode that crashes)** +**TODO: Always recommend running our backported drivers to assure there are not unexpected regressions?** + The three last colums signify: 1. Injection mode: whether the network card can be used as a second interface to inject frames in [injection mode](#Injection-mode). @@ -243,22 +245,30 @@ Notable remarks: Certain clients install the key too early during a pairwise session rekey. To test these devices, add the `--rekey-early-install` parameter and retry the test. +### Checklist + In case the script doesn't appear to be working, check the following: 1. Check that no other process is using the network card (e.g. kill your network manager). 2. Check that you are using modified drivers if needed for your wireless network card. + If you updated your kernel, you will need to recompile and reinstall the drivers. 3. Check that you are using modified firmware if needed for your wireless network card. -4. Run the [injection tests](#Network-card-injection-test) to make sure injection is working properly. +4. Assure the device you are testing doesn't enter sleep mode (causing it to miss injected frames). + **Or use a compatible device in mixed mode?** -5. Check that you machine isn't generating background traffic that interferes with the tests. In +5. Run the [injection tests](#Network-card-injection-test) to make sure injection is working properly. + +6. Check that you machine isn't generating background traffic that interferes with the tests. In particular, disable networking in your OS, manually kill your DHCP client/server, etc. -6. Confirm that you are connecting to the correct network. Double-check `client.conf`. +7. Confirm that you are connecting to the correct network. Double-check `client.conf`. -7. Make sure the network is using (AES-)CCMP as the encryption algorithm. +8. Make sure the AP being tested is using (AES-)CCMP as the encryption algorithm. + +9. If your Wi-Fi dongle is unreliable, use it from a live CD or USB. A virtual machine can be unreliable. ## Extended Vulnerability Tests @@ -306,7 +316,12 @@ using _injection mode_: ./test-injection.py wlan0 wlan1 Here we test if network card `wlan0` properly injects frames and we use network card `wlan1` -to monitor whether frames are properly injected. In case you do not have a second network +to monitor whether frames are properly injected. + +**TODO: Testing the TP-Link against the Intel 3160 was very unreliable: many frames were not** +**received although they in fact were sent by the device.** + +In case you do not have a second network card, you can execute a partial injection test using: ./test-injection.py wlan0 @@ -393,6 +408,8 @@ to confirm that the network card is compatible. ### Notes on device support +**TODO: Reference or include the DEVICES.md file** + #### ath9k_htc There is a known problem with the `ath9k_htc` driver, used by the Technoethical N150 HGA, TP-Link @@ -435,9 +452,16 @@ it was used. We found that: **Note: with an ath9k_htc we cannot inject frames with spoofed MAC addresses before and after** **authenticating in AP/monitor mode? It does inject frames (incorrectly) in client/monitor mode.** + _This was likely because capturing with the Intel 3160 was very unreliable._ -- On kernel **X.Y.Z** +- On kernel 5.6.13 on Arch Linux, client mode didn't work properly when using an USB3.0 port. But + AP mode did work properly on a USB3.0 port. + In mixed mode, non-EAPOL data frames were not sent when injected before authentication. After + authentication, these were transmitted. **Is that patchable?** + + **Note: with an ath9k_htc we can inject frames with spoofed MAC addresses before and after** + **authenticating in client/monitor mode. Same thing in AP/monitor mode. But capturing is unreliable.** ## TODOs diff --git a/research/fraginternals.py b/research/fraginternals.py index 99f5c88ee..ac989dfb8 100644 --- a/research/fraginternals.py +++ b/research/fraginternals.py @@ -718,7 +718,7 @@ class Daemon(metaclass=abc.ABCMeta): log(WARNING, "Unable to detect driver of interface!") log(WARNING, "Injecting fragments may be unreliable.") elif driver in ["ath9k_htc", "iwlwifi"]: - # We use this workaround in more cases than required. See DEVICES.md for more info. + # Assure that fragmented frames are reliably injected on certain iwlwifi and ath9k_htc devices self.options.inject_mf_workaround = True log(STATUS, f"Detected {driver}, using injection bug workarounds") diff --git a/research/libwifi b/research/libwifi index fa141ba0f..bc0a98e09 160000 --- a/research/libwifi +++ b/research/libwifi @@ -1 +1 @@ -Subproject commit fa141ba0f3a0b34fe02e171bd5a299fc794e72fc +Subproject commit bc0a98e09c3a168a07b7da3e5975785ff094ba30 diff --git a/research/test-injection.py b/research/test-injection.py index 0e1ae2b78..a06d5a894 100755 --- a/research/test-injection.py +++ b/research/test-injection.py @@ -11,14 +11,15 @@ def main(): parser = argparse.ArgumentParser(description="Test packet injection properties of a device.") parser.add_argument('inject', help="Interface to use to inject frames.") parser.add_argument('monitor', nargs='?', help="Interface to use to monitor for frames.") + parser.add_argument('--debug', type=int, default=0, help="Debug output level.") options = parser.parse_args() peermac = "00:11:22:33:44:55" - - # TODO: Add a --debug parameter similar to fragattack - subprocess.check_output(["rfkill", "unblock", "wifi"]) + # Parse remaining options + change_log_level(-options.debug) + set_monitor_mode(options.inject) if options.monitor: set_monitor_mode(options.monitor) @@ -30,12 +31,8 @@ def main(): log(ERROR, "Both devices are not on the same channel") quit(1) peermac = get_mac_address(options.monitor) - else: - log(WARNING, "Only performing selftest. This can detect only injection issues caused by") - log(WARNING, "the kernel. Many other issues cannot be detected in this self-test, so you") - log(WARNING, "should not trust the output of the tests unless you know what you're doing.") - log(STATUS, "Performing injection tests ...") + log(STATUS, "Performing injection tests") try: test_injection(options.inject, options.monitor, peermac) except OSError as ex: