Strumenti network
Versione del 24 mar 2021 alle 10:11 di Kromeidon (discussione | contributi)
Strumenti per trovare DHCP Server:
Script Python:
Usage: ./rogue_dhcp_check.py <interface_name> [timeout in seconds]
| #!/usr/bin/env python3 | |
| # This script sends a DHCP discover on the specified interface | |
| # then waits for the specified number of seconds (default: 5) | |
| # for replies from DHCP servers and prints the results. | |
| # Install dependencies: | |
| # sudo apt install python3-pip | |
| # sudo pip3 install scapy # do not use the one in Ubuntu apt (as of 18.04) | |
| # scapy API: https://scapy.readthedocs.io/en/latest/api/scapy.layers.html | |
| # TODO | |
| # | |
| # * What if a single DHCP server replies twice | |
| # or the rogue DHCP server is spoofing MAC addresses? | |
| # * Support plain BOOTP servers | |
| # | |
| import os | |
| import sys | |
| from scapy.all import * | |
| def die(err): | |
| print(err, file=sys.stderr) | |
| sys.exit(1) | |
| def usage(file=sys.stdout): | |
| print("Usage:", sys.argv[0], "<interface_name> [timeout in seconds]", file=file) | |
| if len(sys.argv) < 2 or len(sys.argv) > 3: | |
| usage(sys.stderr) | |
| sys.exit(1) | |
| iface = sys.argv[1] | |
| timeout = 5 | |
| if len(sys.argv) == 3: | |
| try: | |
| timeout = int(sys.argv[2]) | |
| except: | |
| usage(sys.stderr) | |
| sys.exit(1) | |
| if timeout < 1: | |
| timeout = 5 | |
| if os.geteuid() != 0: | |
| die("You must be root to send DHCP packets") | |
| conf.checkIPaddr = False | |
| try: | |
| fam, hw = get_if_raw_hwaddr(iface) | |
| except OSError as e: | |
| die(e) | |
| dhcp_discover = Ether(dst="ff:ff:ff:ff:ff:ff") / IP(src="0.0.0.0", dst="255.255.255.255") / UDP(sport=68, dport=67) / BOOTP(chaddr=hw) / DHCP(options=[("message-type","discover"), "end"]) | |
| print("Sending DHCP Discover packet on interface", iface) | |
| print("Waiting", timeout, "seconds for reply") | |
| ans, unans = srp(dhcp_discover, multi=True, timeout=timeout) | |
| dhcp_servers = {} | |
| for snd, rcv in ans: | |
| # We only care about message-type == 2 | |
| # a.k.a. DHCP Offers | |
| is_offer = False | |
| for opt in rcv.payload.payload.payload.payload.options: | |
| if opt[0] == 'message-type': | |
| if opt[1] == 2: | |
| is_offer = True | |
| if not is_offer: | |
| continue | |
| # rcv.fields: list fields | |
| # rcv.payload: the decoded payload | |
| if not rcv.src in dhcp_servers: | |
| dhcp_servers[rcv.src] = {'MAC': rcv.src, 'IP': rcv.payload.src, 'offer': rcv.payload.payload.payload.yiaddr, 'options': rcv.payload.payload.payload.payload.options} | |
| print() | |
| print("Received", len(ans), "replies from", len(dhcp_servers), "different (based on MAC address) DHCP server(s)") | |
| print() | |
| if len(dhcp_servers) > 1: | |
| print("WARNING: Looks like there might be more than one DHCP server on your network") | |
| print() | |
| for mac in dhcp_servers: | |
| server = dhcp_servers[mac] | |
| print("DHCP server", mac) | |
| print(" Server IP:", server['IP']) | |
| print(" Offer IP:", server['offer']) | |
| print(" Options:") | |
| for opt in server['options']: | |
| if opt[0] == 'message-type': | |
| print(' message-type:', DHCPTypes[opt[1]]) | |
| else: | |
| print(' ' + str(opt[0])+':', opt[1]) | |
| print() | |