Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions research/fragattack.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
# See README for more details.

# Note that tests_*.py files are imported automatically
import glob, importlib, argparse
import glob, importlib, argparse, warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
from fraginternals import *

# ----------------------------------- Main Function -----------------------------------
Expand Down Expand Up @@ -90,8 +91,7 @@ def prepare_tests(opt):
elif opt.testname in ["eapol-amsdu", "eapol-amsdu-bad"]:
freebsd = opt.testname.endswith("-bad")
actions = str2actions(stractions,
[Action(Action.StartAuth, enc=False),
Action(Action.StartAuth, enc=False)])
[Action(Action.StartAuth, enc=False)])
test = EapolAmsduTest(REQ_ICMP, actions, freebsd, opt)

elif opt.testname == "linux-plain":
Expand Down
80 changes: 70 additions & 10 deletions research/fraginternals.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,57 @@
import abc, sys, socket, struct, time, subprocess, atexit, select, copy
import os.path
from wpaspy import Ctrl
from scapy.contrib.wpa_eapol import WPA_key
from scapy.arch.common import get_if_raw_hwaddr
try:
from scapy.contrib.wpa_eapol import WPA_key
def _eapol_key_info(pkt):
return pkt[WPA_key].key_info
except ImportError:
# Scapy 2.5+ removed scapy.contrib.wpa_eapol; EAPOL key handling is
# now in scapy.layers.eap as EAPOL_KEY with individual bit fields.
from scapy.layers.eap import EAPOL_KEY as WPA_key
def _eapol_key_info(pkt):
ek = pkt[WPA_key]
return (ek.key_descriptor_type_version |
(ek.key_type << 3) |
(ek.install << 6) |
(ek.key_ack << 7) |
(ek.has_key_mic << 8) |
(ek.secure << 9) |
(ek.error << 10) |
(ek.request << 11) |
(ek.encrypted_key_data << 12) |
(ek.smk_message << 13))
try:
from scapy.arch.common import get_if_raw_hwaddr
except ImportError:
try:
from scapy.arch import get_if_raw_hwaddr
except ImportError:
# Scapy 2.7+ removed get_if_raw_hwaddr on Linux; implement via ioctl
import socket as _socket, struct as _struct, fcntl as _fcntl
def get_if_raw_hwaddr(iface):
SIOCGIFHWADDR = 0x8927
s = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM, 0)
try:
d = _struct.pack('256s', iface[:15].encode())
res = _fcntl.ioctl(s.fileno(), SIOCGIFHWADDR, d)
return _struct.unpack_from('H6s', res, 16)
finally:
s.close()

# scapy.arch.get_if_index was removed in Scapy 2.7; patch it back in via ioctl
if not hasattr(scapy.arch, 'get_if_index'):
import fcntl as _fcntl
def _get_if_index(iface):
SIOCGIFINDEX = 0x8933
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
try:
d = struct.pack('256s', iface[:15].encode())
res = _fcntl.ioctl(s.fileno(), SIOCGIFINDEX, d)
return struct.unpack_from('I', res, 16)[0]
finally:
s.close()
scapy.arch.get_if_index = _get_if_index

FRAGVERSION = "1.3"

Expand Down Expand Up @@ -492,11 +541,12 @@ def trigger_eapol_events(self, eapol):
# Track return value of possible trigger Action function
result = None

key_type = eapol.key_info & 0x0008
key_ack = eapol.key_info & 0x0080
key_mic = eapol.key_info & 0x0100
key_secure = eapol.key_info & 0x0200
key_request = eapol.key_info & 0x0800
key_info = _eapol_key_info(eapol)
key_type = key_info & 0x0008
key_ack = key_info & 0x0080
key_mic = key_info & 0x0100
key_secure = key_info & 0x0200
key_request = key_info & 0x0800
# Detect Msg3/4 assumig WPA2 is used --- XXX support WPA1 as well
is_msg3_or_4 = key_secure != 0

Expand Down Expand Up @@ -537,7 +587,7 @@ def handle_eapol_tx(self, eapol, dstmac):
# - Some routers such as the RT-AC51U do the 4-way rekey HS in plaintext.

plaintext = self.options.rekey_plaintext
if WPA_key in eapol and eapol[WPA_key].key_info & 2048:
if WPA_key in eapol and _eapol_key_info(eapol) & 0x0800:
plaintext = False

self.send_mon(eapol, plaintext=plaintext)
Expand Down Expand Up @@ -779,7 +829,17 @@ def configure_interfaces(self):
scapy.arch.get_if_index(self.nic_mon)
except IOError:
subprocess.call(["iw", self.nic_mon, "del"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
subprocess.check_output(["iw", self.nic_iface, "interface", "add", self.nic_mon, "type", "monitor"])
try:
subprocess.check_output(["iw", self.nic_iface, "interface", "add", self.nic_mon, "type", "monitor"],
stderr=subprocess.PIPE)
except subprocess.CalledProcessError as ex:
log(ERROR, "Failed to create virtual monitor interface {}: {}".format(self.nic_mon, ex.stderr.decode().strip()))
log(ERROR, "Try using --inject {} to skip virtual interface creation.".format(self.nic_iface))
quit(1)
# Give the kernel time to initialise the new virtual interface before use.
# Some drivers (e.g. mt76) crash with a null-pointer dereference if we
# open a socket on the interface immediately after iw returns.
time.sleep(0.5)

# 2.A Remember whether to need to use injection workarounds.
driver = get_device_driver(self.nic_mon)
Expand Down Expand Up @@ -1242,7 +1302,7 @@ def handle_wpaspy(self, msg):
# When using a separate interface to inject, switch to correct channel
self.follow_channel()

p = re.compile("Associated with (.*)")
p = re.compile(r"Associated with (.*)")
bss = p.search(msg).group(1)
self.station.handle_connecting(bss)

Expand Down
37 changes: 30 additions & 7 deletions research/libwifi/wifi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,30 @@
# This code may be distributed under the terms of the BSD license.
# See README for more details.
from scapy.all import *
from scapy.arch import L2Socket, attach_filter
from Crypto.Cipher import AES
from datetime import datetime
import binascii

# get_if_raw_hwaddr was removed in Scapy 2.7; provide ioctl fallback for Linux
if 'get_if_raw_hwaddr' not in dir():
try:
from scapy.arch.common import get_if_raw_hwaddr
except ImportError:
try:
from scapy.arch import get_if_raw_hwaddr
except ImportError:
import socket as _socket, struct as _struct, fcntl as _fcntl
def get_if_raw_hwaddr(iface):
SIOCGIFHWADDR = 0x8927
s = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM, 0)
try:
d = _struct.pack('256s', iface[:15].encode())
res = _fcntl.ioctl(s.fileno(), SIOCGIFHWADDR, d)
return _struct.unpack_from('H6s', res, 16)
finally:
s.close()

#### Constants ####

FRAME_TYPE_MANAGEMENT = 0
Expand Down Expand Up @@ -102,7 +122,7 @@ def addr2bin(addr):

def get_channel(iface):
output = str(subprocess.check_output(["iw", iface, "info"]))
p = re.compile("channel (\d+)")
p = re.compile(r"channel (\d+)")
m = p.search(output)
if m == None: return None
return int(m.group(1))
Expand All @@ -123,7 +143,7 @@ def set_macaddress(iface, macaddr):

def get_iface_type(iface):
output = str(subprocess.check_output(["iw", iface, "info"]))
p = re.compile("type (\w+)")
p = re.compile(r"type (\w+)")
return str(p.search(output).group(1))

def set_monitor_mode(iface, up=True, mtu=1500):
Expand Down Expand Up @@ -220,9 +240,12 @@ def print_reply(self, req, reply):

#### Packet Processing Functions ####

# Compatibility with older Scapy versions
if not "ORDER" in scapy.layers.dot11._rt_txflags:
scapy.layers.dot11._rt_txflags.append("ORDER")
# Compatibility with older Scapy versions — _rt_txflags may not exist or already contain ORDER
try:
if "ORDER" not in scapy.layers.dot11._rt_txflags:
scapy.layers.dot11._rt_txflags.append("ORDER")
except AttributeError:
pass

class MonitorSocket(L2Socket):
def __init__(self, iface, dumpfile=None, detect_injected=False, **kwargs):
Expand Down Expand Up @@ -384,7 +407,7 @@ def get_ccmp_payload(p):
# Extract encrypted payload:
# - Skip extended IV (4 bytes in total)
# - Exclude first 4 bytes of the CCMP MIC (note that last 4 are saved in the WEP ICV field)
return str(p.wepdata[4:-4])
return bytes(p.wepdata[4:-4])
elif Dot11CCMP in p:
return p[Dot11CCMP].data
elif Dot11TKIP in p:
Expand Down Expand Up @@ -484,7 +507,7 @@ def create_msdu_subframe(src, dst, payload, last=False):
payload = raw(payload)

total_length = len(p) + len(payload)
padding = ""
padding = b""
if not last and total_length % 4 != 0:
padding = b"\x00" * (4 - (total_length % 4))

Expand Down
8 changes: 6 additions & 2 deletions research/pysetup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ source venv/bin/activate
pip install wheel
pip install -r requirements.txt

# Fix a bug in scapy that isn't fixed in the PyPI version yet. For background see
# Fix a bug in scapy<=2.4.3 that isn't fixed in the PyPI version yet. For background see
# https://github.com/secdev/scapy/commit/46fa40fde4049ad7770481f8806c59640df24059
sed -i 's/find_library("libc")/find_library("c")/g' venv/lib/python*/site-packages/scapy/arch/bpf/core.py
# (no-op on scapy>=2.4.4 where this was already fixed upstream)
BPF_CORE="venv/lib/python*/site-packages/scapy/arch/bpf/core.py"
for f in $BPF_CORE; do
[ -f "$f" ] && sed -i 's/find_library("libc")/find_library("c")/g' "$f"
done
27 changes: 11 additions & 16 deletions research/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
attrs==19.3.0
importlib-metadata==1.5.0
more-itertools==8.2.0
mpmath==1.1.0
packaging==20.1
pluggy==0.13.1
py==1.10.0
pycryptodome==3.9.7
pyparsing==2.4.6
pytest==5.3.5
scapy==2.4.3
simpy==3.0.11
six==1.14.0
sympy==1.5.1
wcwidth==0.1.8
zipp==3.0.0
attrs>=21.0.0
mpmath>=1.2.0
packaging>=21.0
pluggy>=1.0.0
pycryptodome>=3.9.7
pyparsing>=3.0.0
pytest>=7.0.0
scapy>=2.5.0
simpy>=4.0.0
six>=1.16.0
sympy>=1.9.0
3 changes: 3 additions & 0 deletions src/crypto/crypto_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <openssl/ec.h>
#include <openssl/x509.h>
#endif /* CONFIG_ECC */
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/provider.h>
#endif /* OpenSSL version >= 3.0 */

#include "common.h"
#include "utils/const_time.h"
Expand Down