keycroc-payloads/payloads/library/general/keyos-croc/scripts/wlanFencing.py

153 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import subprocess
from time import sleep
# execute a passed shell-command via subprocess
def shell(cmd):
try:
process = subprocess.check_output(cmd, shell=True, stderr=subprocess.DEVNULL)
return process
except subprocess.CalledProcessError as err:
print(err)
return False
# scan for WLAN access points in the range and return result
def scan_aps(interface):
scan_result = shell("iw dev {} scan | grep SSID | awk '{{ print substr($0, index($0,$2)) }}'".format(interface))
wlan_aps_list = []
# scanning to often can result in "device is busy"-errors
if scan_result:
wlan_aps_list = scan_result.decode("utf-8").split("\n")
return wlan_aps_list
# check if WLAN interface exists and is up, try to start if down
def prepare_interface(interface):
output = shell("cat /sys/class/net/{}/flags".format(interface))
if output:
# 0x1002 is down, 0x1003 is up
if "0x1003" in output.decode("utf-8"):
return True
else:
# try to start interface
print("interface is down - starting ...")
shell("ifconfig {} up".format(interface))
sleep(1)
return True
else:
# device does not exist
return False
# check if scanned aps_list does not contain any denylisted AP entries
def denylist_check(denylist, wlan_aps_list):
found_denied = False
for rule in denylist:
if set(rule).issubset(set(wlan_aps_list)):
found_denied = True
break
return found_denied
# check if scanned aps_list does contain any allowlisted AP entries
def allowlist_check(allowlist, wlan_aps_list):
found_allowed = False
for rule in allowlist:
if (rule[0] == "*") or set(rule).issubset(set(wlan_aps_list)):
found_allowed = True
break
return found_allowed
if __name__ == "__main__":
# ----------------------------------------------
## syntax examples for -a / -d
# ./wlanFencing.py -a "AP1" -a "AP2"
# --> AP1 or AP2
# ./wlanFencing.py -a "AP1" "AP2"
# --> AP1 and AP2
# ./wlanFencing.py -a "AP1" "AP2" -a "AP3"
# --> (AP1 and AP2) or AP3
# ----------------------------------------------
## real world examples
# continue if AP1 is present
# ./wlanFencing.py -a "AP1"
# continue if AP1 and AP2 are present
# ./wlanFencing.py -a "AP1" "AP2"
# continue if AP1 is absent
# ./wlanFencing.py -a "*" -d "AP1"
# continue if AP1 and AP2 are absent
# ./wlanFencing.py -a "*" -d "AP1" "AP2"
# ----------------------------------------------
parser = argparse.ArgumentParser(prog='wlan_fencing', description='check if WLAN APs are in the range')
parser.add_argument("-a", "--allow_ap", nargs="+", action='append', help="SSID(s) of the AP(s) that have to be present")
parser.add_argument("-d", "--deny_ap", nargs="+", action='append', help="SSID(s) of the AP(s) that have to be absent")
parser.add_argument("-t", "--timeout", help="exit(1) after 30 seconds", action="store_true")
args = parser.parse_args()
timeout = args.timeout
allowlist = args.allow_ap if (args.allow_ap) else []
denylist = args.deny_ap if (args.deny_ap) else []
print("Allow:", allowlist)
print("Deny:", denylist, "\n")
# default values
interface = "wlan0"
sleep_seconds = 2
max_tries = 15
iterations = 0
if not prepare_interface(interface):
print("WLAN interface does not exist or failed to start - stopping.")
exit(1)
while True:
wlan_aps_list = scan_aps(interface)
# wlan_aps_list contains at least one element
if len(wlan_aps_list) != 0:
print(wlan_aps_list)
if not denylist_check(denylist, wlan_aps_list):
print("[+] no bad device [+]\n")
if allowlist_check(allowlist, wlan_aps_list):
print("A device is found, no denylisted device found.")
exit(0)
# exit if waited longer than max_tries
if timeout and (iterations >= max_tries):
print("Max tries reached - stopping.")
exit(1)
sleep(sleep_seconds)
iterations += 1