fragattacks: draft version of README

This commit is contained in:
Mathy Vanhoef 2020-05-24 04:39:15 +04:00 committed by Mathy Vanhoef
parent 80c441ab50
commit 253d936420
5 changed files with 352 additions and 34 deletions

View File

@ -1,3 +1,31 @@
# Device checklist
1. Confirm that the device is working normally on Linux.
2. Confirm that the device can be put in monitor mode:
ifconfig wlan0 down
iw wlan0 set type monitor
ifconfig wlan0 up
2. Test normal injection using `aireplay-ng -9 wlan1` using the following command:
**Put in monitor mode using iw. Use airmong-ng as a backup method.**
3. Test advanced injection using `test-injection.py`
4. Test injection using `./fragattack.py wlan0 ping --ap --inject-test wlan1`
5. Test injection using `./fragattack.py wlan0 ping --inject-test wlan1`
6. Confirm that a normal ping works `./fragattack.py wlan0 ping I,E`.
Troubleshooting:
- If you cannot put the device in monitor mode, try executing `airmon-ng start wlan0` instead.
# Monitor mode injectin
Device that purely operate in monitor mode might overwrite certain fields of
@ -20,19 +48,17 @@ Summary: this can be used without driver/firmware changes in pure monitor mode,
1 to 0x27 as 32-bit numbers for some reason. This is a strange bug, but at
least it is not caused by our driver modifications.
- Had to patch driver to prevent sequence number and QoS TID to be overwritten
**TODO: Also in pure monitor?**
- In mixed mode: had to patch driver to prevent sequence number and QoS TID to
be overwritten
- Unable to transmit any frames from a different transmitter address. This is
because in `ieee80211_monitor_start_xmit` it cannot find a channel to transmit
on (finding a valid chandef fails).
**TODO: Also in pure monitor?**
- In mixed mode: unable to transmit any frames from a different transmitter address.
This is because in `ieee80211_monitor_start_xmit` it cannot find a channel to transmit
on (finding a valid chandef fails). We patched mac80211 to fix this.
- Cannot inject frames using a TID that is used for the first time. There's no
queue in the driver allocated for it yet it seems, and this causes issues.
- In mixed mode: cannot inject frames using a TID that is used for the first time.
There's no queue in the driver allocated for it yet it seems, and this causes issues.
To prevent this, and prevent frame reordering, we inject all frames on the
same queue in the driver.
**TODO: Also in pure monitor?**
- It ignores `IEEE80211_RADIOTAP_DATA_RETRIES` and retransmites frames 15 times
both in purely monitor more and mixed managed/monitor mode (before and after
@ -89,9 +115,13 @@ Summary: when using this device, you must use a modified driver/firmware.
- 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.
# TODOs
# hwsim mode
- When using the mac80211_hwsim trick with one monitor interface, there is
still the risk of frames with different QoS TIDs being reordered.
- Linux clients need an authentication response _fast_ and we are too slow. Perhaps
by implementing the packet forwarding in C we can become fast enough.
- For some strange reason, the Intel/mvm cannot receive data frames from Android/iPhone/iPad
after 4-way HS. This is a very strange bug.

View File

@ -1,30 +1,257 @@
This repository contains scripts to test for Wi-Fi fragmentation and aggregation vulnerabilities.
# Usage
## Installation
## Supported Network Cards
1. **Compile and install backports**
Only specific wireless network cards are supported. This is because some network cards may overwrite the
sequence number of injected frames, may overwrite the fragment number, or reorder frames of different priority,
and this interferes with our scripts (i.e. our script might incorrectly say a device is secure although it's not).
We have confirmed that the following network cards work properly with our scripts:
2. Install the dependencies in `../../requirements.txt` (Python3).
| Network Card | USB | injection mode | mixed mode | hwsim mode (experimental) |
| ---------------------- | --- | ----------------------- | ----------------------- | ------------------------- |
| Intel AX200 | No | ? | ? | ? |
| Intel Wireless-AC 8265 | No | yes | patched driver | as client |
| Intel Wireless-AC 3160 | No | yes | patched driver/firmware | as client |
| Technoethical N150 HGA | Yes | patched driver/firmware | patched driver/firmware | patched driver/firmware |
| TP-Link TL-WN722N v1.x | Yes | patched driver/firmware | patched driver/firmware | patched driver/firmware |
| Alfa AWUS036NHA | Yes | patched driver/firmware | patched driver/firmware | patched driver/firmware |
| Alfa AWUS036ACM | Yes | ? | ? | ? |
| Alfa AWUS036ACH | Yes | ? | ? | ? |
| Netgear WN111v2 | Yes | yes | patched driver | yes |
3. Compile the modified `hostapd` and `wpa_supplicant` using `cd research && ./build.sh`.
If this fails install the required dependencies. The build.sh script is also very
trivial so you can manually execute each command in that script to see
where it fails and how to fix it.
The three last colums signify:
3. Before proceding, make sure to have pulled all submodules (i.e., libwifi).
1. __Injection mode__: whether the network card can be used as a second interface to inject frames in [injection mode].
## Example Usage
2. __hwsim mode__: whether the network card can be used in [hwsim mode].
Then you can run `./fragattack.py interface tests` where the first argument
is the interface to use. This inferface should NOT be set to monitor mode
(the script will handle this). The second parameter is the test to execute.
3. __Mixed mode__: whether the network card can be used in [mixed mode].
You can first execute a simple ping to see if everything is working:
./fragattack.py wlan0 ping --ip 192.168.100.10 --peerip 192.168.100.1
We recommend the use of the Technoethical N150 HGA in either injection mode or mixed mode. It
requires the use of a patched driver and firmware, but since it's a USB dongle this can be
configured inside a virtual machine. If you are unable to find one of the above devices, you
can search for [alternative devices] that have a high chance of also working.
## Prerequisites
Our scripts were tested on Kali Linux, Ubuntu 18.04, Arch Linux, and Manjaro Linux. To install
the required dependencies, execute:
# Kali Linux and Ubuntu
apt-get update
apt-get install libnl-3-dev libnl-genl-3-dev pkg-config libssl-dev net-tools git
# Arch Linux and Manjaro Linux
pacman -S macchanger
Now clone this repository, build the tools, and configure a virtual python3 environment:
git clone git@bitbucket.org:vanhoefm/fragattack-scripts.git --recursive
cd fragattack-scripts
./build.sh
cd research
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
The above instructions only have to be executed once.
## Before every usage
Every time you want to use the script, you first have to load the virtual python environment
as root. This can be done using:
cd fragattack-scripts/research
sudo su
source venv/bin/activate
You should now disable Wi-Fi in your network manager so it will not interfere with our scripts.
Our script can test both clients and APs:
- Testing APs: configure the AP you want to test by editing `research/client.conf`. This is a standard
`wpa_supplicant` configuration file, see the [hostap documentation] on how to edit it.
- Testing clients: you must execute the script with the extra `--ap` parameter. This instructs
the script into creating an AP with as name **testnetwork** and password **abcdefgh**. Connect
to this network with the client you want to test. **By default the client must request an AP**
**using DHCP.** To edit properties of the created AP, such as the channel it's created on, you
can edit `research/hostapd.conf`.
# Testing Modes
## Injection Mode
This mode requires two devices: one will act as an AP or the client, and the other will be used to
inject frames. Execute the script in this mode using:
./fragattack wlan0 --inject wlan1 [--ap] $COMMAND
Here interface wlan0 will act as a legitimate client or AP, and wlan1 will be used to inject
frames. For wlan0, any card that supports normal client or AP mode on Linux can be used. For wlan1,
a card must be used that supports injection mode according to [Supported Network Cards].
### Mixed mode
This mode requires only one device. This disadvantage is that this mode requires a patched driver and/or firmware,
and that only a small amount of devices are supported. Execute the script in this mode using:
./fragattack wlan0 [--ap] $COMMAND
Compile and install backports.
### Hwsim mode (experimental)
**TODO: This mode isn't useful for Intel/mvm since it's too unreliable... Bootable Live CD is better!**
This mode requires only one device. The disadvantage is that this mode is the least reliable:
- Frames are handled slower, possibly causing the tested client/AP to timeout during authentication
or association.
- When injeting frames, they may be retransmitted even though an acknowledgement was recieved.
This will further slightly slowdown the handling of frames.
- Frames are not properly acknowledged depending on the wireless network card, which causes some
tested clients or APs to disconnect during authentication or association.
Nevertheless, the advantage is that is mode can, depending on the network card, be used without
patches to the driver and/or firmware. Before using this mode, create two virtual network cards:
./hwsim.sh
This will output the two created virtual "hwsim" interfaces, for example wlan1 and wlan2. Then
search for the channel of the AP you want to test, and put the real network card on this channel:
**TODO: recommend channel 1-13?**
**TODO: do we also support AP mode? I suppose for patched ath9k_htc it does work.**
./scan.sh wlan0
iw wlan0 set type monitor
ifconfig wlan0 up
iw wlan0 set channel 11
**TODO: sudo iw wlan0 set monitor otherbss. Does airmon-ng handle this better? Move to general section?**
You can now start the script as follows:
./fragattack wlan0 --hwsim wlan1,wlan2 [--ap] $COMMAND
After the script executed, you can directly run it again with a new command.
## Testing for Vulnerabilities
We recommend executing the following tests. The tests marked in bold correspond to vulnerabilities,
and the other tests are useful to understand the behaviour of the device under test.
| Test | Command | Short description
| ---------------------- | ------------------------------ | ---------------------------------
| Normal ping | ping I,E | Send a normal ping
| Fragmented ping | ping I,E,E | Send a fragmented ping
| Fragmentation timeout | ping I,E,E --delay 5 | Send a fragmented ping with a 5s delay between fragments
| **Non-consecutive** | ping I,E,E --inc-pn 2 | Send a fragmented ping with non-consecutive packet numbers.
| Seperator | ping-frag-sep | Send a fragmented ping with fragments separated by a normal frame
| **Mixed key** | ping I,R,BE,AE | As client wait for rekey and as AP force rekey, then encrypt fragments under different keys.
| | ping I,R,BE,AE --pn-per-qos | Same as above, except it also work when the device doesn't accept non-consecutive fragments.
| **Cache Poison** | ping I,E,C,AE | Inject a fragment, as client _reassociate_ and as AP force tested client to reconnect, then inject second fragment.
| | ping I,E,C,E | Same as above, except there is a longer delay before sending the second fragment.
| | ping I,E,C,AE --full-reconnect | Inject a fragment, as client _reconnect_ and as AP force tested client to reconnect, then inject second fragment.
| | ping I,E,C,E --full-reconnect | Same as above, except there is a longer delay before sending the second fragment.
| **A-MSDU** | ping I,E --msdu | Send a normal ping encapsulated in a normal A-MSDU frame.
| | ping I,E,E --msdu | Send a normal ping an a fragmented A-MSDU frame.
| **Mixed Plain/Enc** | ping I,E,P | Send a fragmented ping: first fragment encrypted, second fragment in plaintext.
| | ping I,P,E | Send a fragmented ping: first fragment in plaintext, send fragment encrypted.
| | 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.
| **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).
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).
| Test | Command | Short description
| ---------------------- | ------------------------------- | ---------------------------------
| **Mixed key** | ping I,E,R,AE | **Inspired by MediaTek case**
| | ping I,E,R,AE --rekey-plaintext | Mixed key attack against MediaTek
| | ping I,E,R,AE --rekey-request --rekey-plaintext | Mixed key attack against MediaTek
| | ping I,E,R,AE --rekey-early-install | **TODO**
| | 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 |
| **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.
Details remarks:
- Fragmentation timeout: this test is used to check the maximum accepted delay between two fragments.
If the default test doesn't work, try with `--delay 2` or lower. In case the maximum accepted delay
is low, this may impact other tests. **All fragments sent in other tests must be sent within the**
**maximum delay, otherwise the test will automatically fail (and you might conclude a device isn't.**
**vulnerable to an attack even though it might be.**
- When running the mixed key test against an AP, the AP must be configured to regularly renew the PTK
by executing a new 4-way handshake (e.g. every 30 seconds or minute). Against a low number of APs,
the client can also request the AP to renew the PTK. This can be done by adding the `--rekey-request`
parameter.
Home routers with a MediaTek driver will perform the rekey handshake in plaintext. To test these
devices, also add the `--rekey-plaintext` parameter.
**Against unknown devices,** the PTK will be installed too early. To test these devices, add the
`--rekey-early-install` parameter and retry the test.
In case you are testing a device which should be vulnerable, but the script doesn't detect that
it's vulnerable, double check the following things:
1. Check that you are using modified drivers if needed for your wireless network card.
2. Check that you are using modified firmware if needed for your wireless network card.
3. Run the [device injection tests] to make sure injection is working properly.
4. Check that he machine that executes the script doesn't generate background traffic that might interfere with
the tests. In particular, remember to disable network in your OS, manually kill your DHCP client/server, etc.
5. Confirm that you are connecting to the correct network. Double-check `client.conf`.
6. Make sure the network is using (AES-)CCMP as the encryption algorithm.
# Advanced Usage
## Static IP Configuration
In case the device you are testing doesn't support DHCP, you can manually specify the IP addresses
that the script should use. For example:
./fragattack.py wlan0 ping --inject wlan1 --ip 192.168.100.10 --peerip 192.168.100.1
Here the testing script will use address 192.168.100.10, and it will inject a ping request
to the peer IP address 192.168.100.1.
# TODOs
- Confirm each device can detect all vulnerabilities in the recommended modes.
- Test the attacks against PEAP-MSchap for eduroam tests (basic test was working).
- TODO: Is it important to disable encryption? I don't think it is. Otherwise we need sysfsutils as a dependency too.
- Include references to sections in the paper for the command overview table.
- Create an example pcap and debug output of all tests.
- Release a known vulnerable linux image to test against? Essential to confirm the tests are working!
Here `peerip` is the IP address of the AP/router we are testing, and `ip`
denotes the IP address we are assignment to the client. Edit the file
`client.conf` the specify the SSID and password of the network you are
testing. You should see a message "SUCCESSFULL INJECTION".

View File

@ -1,18 +1,28 @@
ctrl_interface=wpaspy_ctrl
# Simple home network
network={
ssid="utotnet_xx"
psk="1dog2cats!"
#key_mgmt=NONE
disable_ht=1
pairwise=CCMP
#group=CCMP
}
# Enterprise network
network={
ssid="arubatest"
disable_ht=1
ssid="peaptest"
key_mgmt=WPA-EAP
eap=PEAP
anonymous_identity="not anonymous"
identity="user"
phase2="auth=MSCHAPV2"
password="password"
key_mgmt=WPA-PSK
psk="abcdefgh"
pairwise=CCMP
#group=CCMP
}
# EAP-PWD with dynamic WEP keys
@ -22,4 +32,7 @@ network={
eap=PWD
identity="user"
password="password"
pairwise=CCMP
#group=CCMP
}

20
research/hwsim.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
set -e
if ! [ $(id -u) = 0 ]; then
echo "You must run the script as root"
exit 1
fi
# Reinitialize mac80211_hwsim
rmmod mac80211_hwsim 2> /dev/null || true
modprobe mac80211_hwsim radios=2
sleep 1
# Display the created interface names
IFACES=$(ls /sys/devices/virtual/mac80211_hwsim/hwsim*/net/*/address | cut -d/ -f8)
for IFACE in $IFACES
do
echo "Created hwsim interface $IFACE"
done

28
research/scan.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/bash
set -e
if ! [ $(id -u) = 0 ]; then
echo "You must run the script as root"
exit 1
fi
if [[ $# -ne 1 ]]; then
echo "Illegal number of parameters"
exit 2
fi
IFACE=$1
# Assure device is in managed mode
ifconfig $IFACE down
iw $IFACE set type managed
ifconfig $IFACE up
# Scan and list the results
RESULTS=( $(iwlist $IFACE scan | grep -E "Channel:|SSID") )
for chanidx in $(seq 0 2 ${#RESULTS[@]})
do
ssididx=$((chanidx+1))
echo ${RESULTS[$ssididx]} ${RESULTS[$chanidx]}
done
ifconfig $IFACE down