tests: SAE anti clogging during an attack
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
f214361581
commit
e43352ff41
1 changed files with 149 additions and 0 deletions
|
@ -10,6 +10,9 @@ import os
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
import subprocess
|
||||||
|
|
||||||
import hwsim_utils
|
import hwsim_utils
|
||||||
import hostapd
|
import hostapd
|
||||||
|
@ -1372,3 +1375,149 @@ def test_sae_reauth(dev, apdev):
|
||||||
dev[0].request("PMKSA_FLUSH")
|
dev[0].request("PMKSA_FLUSH")
|
||||||
dev[0].request("REASSOCIATE")
|
dev[0].request("REASSOCIATE")
|
||||||
dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
|
dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
|
||||||
|
|
||||||
|
def test_sae_anti_clogging_during_attack(dev, apdev):
|
||||||
|
"""SAE anti clogging during an attack"""
|
||||||
|
try:
|
||||||
|
run_sae_anti_clogging_during_attack(dev, apdev)
|
||||||
|
finally:
|
||||||
|
subprocess.call(["ip", "link", "set", "dev", apdev[1]["ifname"],
|
||||||
|
"down"])
|
||||||
|
subprocess.call(["iw", apdev[1]["ifname"], "set", "type", "managed"])
|
||||||
|
|
||||||
|
def build_sae_commit(bssid, addr, group=21, token=None):
|
||||||
|
if group == 19:
|
||||||
|
scalar = binascii.unhexlify("7332d3ebff24804005ccd8c56141e3ed8d84f40638aa31cd2fac11d4d2e89e7b")
|
||||||
|
element = binascii.unhexlify("954d0f4457066bff3168376a1d7174f4e66620d1792406f613055b98513a7f03a538c13dfbaf2029e2adc6aa96aa0ddcf08ac44887b02f004b7f29b9dbf4b7d9")
|
||||||
|
elif group == 21:
|
||||||
|
scalar = binascii.unhexlify("001eec673111b902f5c8a61c8cb4c1c4793031aeea8c8c319410903bc64bcbaea134ab01c4e016d51436f5b5426f7e2af635759a3033fb4031ea79f89a62a3e2f828")
|
||||||
|
element = binascii.unhexlify("00580eb4b448ea600ea277d5e66e4ed37db82bb04ac90442e9c3727489f366ba4b82f0a472d02caf4cdd142e96baea5915d71374660ee23acbaca38cf3fe8c5fb94b01abbc5278121635d7c06911c5dad8f18d516e1fbe296c179b7c87a1dddfab393337d3d215ed333dd396da6d8f20f798c60d054f1093c24d9c2d98e15c030cc375f0")
|
||||||
|
pass
|
||||||
|
frame = binascii.unhexlify("b0003a01")
|
||||||
|
frame += bssid + addr + bssid
|
||||||
|
frame += binascii.unhexlify("1000")
|
||||||
|
auth_alg = 3
|
||||||
|
transact = 1
|
||||||
|
status = 0
|
||||||
|
frame += struct.pack("<HHHH", auth_alg, transact, status, group)
|
||||||
|
if token:
|
||||||
|
frame += token
|
||||||
|
frame += scalar + element
|
||||||
|
return frame
|
||||||
|
|
||||||
|
def sae_rx_commit_token_req(sock, radiotap, send_two=False):
|
||||||
|
msg = sock.recv(1500)
|
||||||
|
ver,pad,len,present = struct.unpack('<BBHL', msg[0:8])
|
||||||
|
frame = msg[len:]
|
||||||
|
fc,duration = struct.unpack('<HH', frame[0:4])
|
||||||
|
if fc != 0xb0:
|
||||||
|
return False
|
||||||
|
frame = frame[4:]
|
||||||
|
da = frame[0:6]
|
||||||
|
if da[0] != 0xf2:
|
||||||
|
return False
|
||||||
|
sa = frame[6:12]
|
||||||
|
bssid = frame[12:18]
|
||||||
|
body = frame[20:]
|
||||||
|
|
||||||
|
alg,seq,status,group = struct.unpack('<HHHH', body[0:8])
|
||||||
|
if alg != 3 or seq != 1 or status != 76:
|
||||||
|
return False
|
||||||
|
token = body[8:]
|
||||||
|
|
||||||
|
frame = build_sae_commit(bssid, da, token=token)
|
||||||
|
sock.send(radiotap + frame)
|
||||||
|
if send_two:
|
||||||
|
sock.send(radiotap + frame)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def run_sae_anti_clogging_during_attack(dev, apdev):
|
||||||
|
if "SAE" not in dev[0].get_capability("auth_alg"):
|
||||||
|
raise HwsimSkip("SAE not supported")
|
||||||
|
params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
|
||||||
|
params['wpa_key_mgmt'] = 'SAE'
|
||||||
|
params['sae_groups'] = '21'
|
||||||
|
hapd = hostapd.add_ap(apdev[0], params)
|
||||||
|
|
||||||
|
dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
|
||||||
|
dev[0].request("SET sae_groups 21")
|
||||||
|
dev[1].scan_for_bss(hapd.own_addr(), freq=2412)
|
||||||
|
dev[1].request("SET sae_groups 21")
|
||||||
|
|
||||||
|
subprocess.check_call(["iw", apdev[1]["ifname"], "set", "type", "monitor"])
|
||||||
|
subprocess.call(["ip", "link", "set", "dev", apdev[1]["ifname"], "up"])
|
||||||
|
subprocess.check_call(["iw", apdev[1]["ifname"], "set", "freq", "2412"])
|
||||||
|
|
||||||
|
ETH_P_ALL = 3
|
||||||
|
sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
|
||||||
|
socket.htons(ETH_P_ALL))
|
||||||
|
sock.bind((apdev[1]["ifname"], 0))
|
||||||
|
sock.settimeout(0.5)
|
||||||
|
radiotap_payload = struct.pack('BB', 0x08, 0)
|
||||||
|
radiotap_payload += struct.pack('BB', 0, 0)
|
||||||
|
radiotap_payload += struct.pack('BB', 0, 0)
|
||||||
|
radiotap_hdr = struct.pack('<BBHL', 0, 0, 8 + len(radiotap_payload),
|
||||||
|
0xc002)
|
||||||
|
radiotap = radiotap_hdr + radiotap_payload
|
||||||
|
|
||||||
|
bssid = binascii.unhexlify(hapd.own_addr().replace(':', ''))
|
||||||
|
for i in range(16):
|
||||||
|
addr = binascii.unhexlify("f2%010x" % i)
|
||||||
|
frame = build_sae_commit(bssid, addr)
|
||||||
|
sock.send(radiotap + frame)
|
||||||
|
sock.send(radiotap + frame)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for i in range(150):
|
||||||
|
if sae_rx_commit_token_req(sock, radiotap, send_two=True):
|
||||||
|
count += 1
|
||||||
|
logger.info("Number of token responses sent: %d" % count)
|
||||||
|
if count < 10:
|
||||||
|
raise Exception("Too few token responses seen: %d" % count)
|
||||||
|
|
||||||
|
for i in range(16):
|
||||||
|
addr = binascii.unhexlify("f201%08x" % i)
|
||||||
|
frame = build_sae_commit(bssid, addr)
|
||||||
|
sock.send(radiotap + frame)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for i in range(150):
|
||||||
|
if sae_rx_commit_token_req(sock, radiotap):
|
||||||
|
count += 1
|
||||||
|
if count == 10:
|
||||||
|
break
|
||||||
|
if count < 10:
|
||||||
|
raise Exception("Too few token responses in second round: %d" % count)
|
||||||
|
|
||||||
|
dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
|
||||||
|
scan_freq="2412", wait_connect=False)
|
||||||
|
dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE",
|
||||||
|
scan_freq="2412", wait_connect=False)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
connected0 = False
|
||||||
|
connected1 = False
|
||||||
|
for i in range(1000):
|
||||||
|
if sae_rx_commit_token_req(sock, radiotap):
|
||||||
|
count += 1
|
||||||
|
addr = binascii.unhexlify("f202%08x" % i)
|
||||||
|
frame = build_sae_commit(bssid, addr)
|
||||||
|
sock.send(radiotap + frame)
|
||||||
|
while dev[0].mon.pending():
|
||||||
|
ev = dev[0].mon.recv()
|
||||||
|
logger.debug("EV0: " + ev)
|
||||||
|
if "CTRL-EVENT-CONNECTED" in ev:
|
||||||
|
connected0 = True
|
||||||
|
while dev[1].mon.pending():
|
||||||
|
ev = dev[1].mon.recv()
|
||||||
|
logger.debug("EV1: " + ev)
|
||||||
|
if "CTRL-EVENT-CONNECTED" in ev:
|
||||||
|
connected1 = True
|
||||||
|
if connected0 and connected1:
|
||||||
|
break
|
||||||
|
if not connected0:
|
||||||
|
raise Exception("Real station(0) did not get connected")
|
||||||
|
if not connected1:
|
||||||
|
raise Exception("Real station(1) did not get connected")
|
||||||
|
if count < 1:
|
||||||
|
raise Exception("Too few token responses in third round: %d" % count)
|
||||||
|
|
Loading…
Reference in a new issue