diff --git a/DHCP2.py b/DHCP2.py index 8dde8aa..afc7eec 100644 --- a/DHCP2.py +++ b/DHCP2.py @@ -1,121 +1,52 @@ -#!/usr/bin/env python3 -"""scapy-dhcp-listener.py -Listen for DHCP packets using scapy to learn when LAN -hosts request IP addresses from DHCP Servers. -Copyright (C) 2018 Jonathan Cutrer -License Dual MIT, 0BSD -""" +from scapy.all import Ether, IP, UDP, BOOTP, DHCP, sendp, sniff, RandMAC +import random -from __future__ import print_function -from scapy.all import * -import time +# Configuration des paramètres DHCP +DHCP_SERVER_IP = "192.168.1.10" # L'adresse IP du serveur DHCP +DHCP_POOL_START = "192.168.1.100" # Début de la plage d'adresses +DHCP_POOL_END = "192.168.1.200" # Fin de la plage d'adresses +SUBNET_MASK = "255.255.255.0" +ROUTER_IP = "192.168.1.2" # Adresse du routeur +DNS_IP = "192.168.1.2" # Adresse du serveur DNS +LEASE_TIME = 86400 # Durée de location en secondes -__version__ = "0.0.3" +allocated_ips = set() # Pour suivre les adresses IP attribuées -# Fixup function to extract dhcp_options by key -def get_option(dhcp_options, key): +def generate_ip(): + # Générer une adresse IP dans la plage DHCP + while True: + ip = f"192.168.1.{random.randint(100, 200)}" + if ip not in allocated_ips: + allocated_ips.add(ip) + return ip - must_decode = ['hostname', 'domain', 'vendor_class_id'] - try: - for i in dhcp_options: - if i[0] == key: - # If DHCP Server Returned multiple name servers - # return all as comma seperated string. - if key == 'name_server' and len(i) > 2: - return ",".join(i[1:]) - # domain and hostname are binary strings, - # decode to unicode string before returning - elif key in must_decode: - return i[1].decode() - else: - return i[1] - except: - pass +def generate_dhcp_offer(pkt): + if pkt.haslayer(DHCP) and pkt[DHCP].options[0][1] == 1: # Discover + client_mac = pkt[Ether].src + offered_ip = generate_ip() + + # Construction de la réponse DHCP Offer + dhcp_offer = ( + Ether(dst=client_mac, src=RandMAC()) / + IP(src=DHCP_SERVER_IP, dst='255.255.255.255') / + UDP(sport=67, dport=68) / + BOOTP(op=2, yiaddr=offered_ip, siaddr=DHCP_SERVER_IP, chaddr=client_mac) / + DHCP(options=[ + ("message-type", "offer"), + ("server_id", DHCP_SERVER_IP), + ("lease_time", LEASE_TIME), + ("subnet_mask", SUBNET_MASK), + ("router", ROUTER_IP), + ("dns", DNS_IP), + ("end") + ]) + ) + sendp(dhcp_offer, iface='eth0', verbose=False) # Remplacez 'eth0' par votre interface -def handle_dhcp_packet(packet): - - # Match DHCP discover - if DHCP in packet and packet[DHCP].options[0][1] == 1: - print('---') - print('New DHCP Discover') - #print(packet.summary()) - #print(ls(packet)) - hostname = get_option(packet[DHCP].options, 'hostname') - print(f"Host {hostname} ({packet[Ether].src}) asked for an IP") - - - # Match DHCP offer - elif DHCP in packet and packet[DHCP].options[0][1] == 2: - print('---') - print('New DHCP Offer') - #print(packet.summary()) - #print(ls(packet)) - - subnet_mask = get_option(packet[DHCP].options, 'subnet_mask') - lease_time = get_option(packet[DHCP].options, 'lease_time') - router = get_option(packet[DHCP].options, 'router') - name_server = get_option(packet[DHCP].options, 'name_server') - domain = get_option(packet[DHCP].options, 'domain') - - print(f"DHCP Server {packet[IP].src} ({packet[Ether].src}) " - f"offered {packet[BOOTP].yiaddr}") - - print(f"DHCP Options: subnet_mask: {subnet_mask}, lease_time: " - f"{lease_time}, router: {router}, name_server: {name_server}, " - f"domain: {domain}") - - - # Match DHCP request - elif DHCP in packet and packet[DHCP].options[0][1] == 3: - print('---') - print('New DHCP Request') - #print(packet.summary()) - #print(ls(packet)) - - requested_addr = get_option(packet[DHCP].options, 'requested_addr') - hostname = get_option(packet[DHCP].options, 'hostname') - print(f"Host {hostname} ({packet[Ether].src}) requested {requested_addr}") - - - # Match DHCP ack - elif DHCP in packet and packet[DHCP].options[0][1] == 5: - print('---') - print('New DHCP Ack') - #print(packet.summary()) - #print(ls(packet)) - - subnet_mask = get_option(packet[DHCP].options, 'subnet_mask') - lease_time = get_option(packet[DHCP].options, 'lease_time') - router = get_option(packet[DHCP].options, 'router') - name_server = get_option(packet[DHCP].options, 'name_server') - - print(f"DHCP Server {packet[IP].src} ({packet[Ether].src}) " - f"acked {packet[BOOTP].yiaddr}") - - print(f"DHCP Options: subnet_mask: {subnet_mask}, lease_time: " - f"{lease_time}, router: {router}, name_server: {name_server}") - - # Match DHCP inform - elif DHCP in packet and packet[DHCP].options[0][1] == 8: - print('---') - print('New DHCP Inform') - #print(packet.summary()) - #print(ls(packet)) - - hostname = get_option(packet[DHCP].options, 'hostname') - vendor_class_id = get_option(packet[DHCP].options, 'vendor_class_id') - - print(f"DHCP Inform from {packet[IP].src} ({packet[Ether].src}) " - f"hostname: {hostname}, vendor_class_id: {vendor_class_id}") - - else: - print('---') - print('Some Other DHCP Packet') - print(packet.summary()) - print(ls(packet)) - - return +def start_dhcp_server(): + print("Démarrage du serveur DHCP...") + sniff(filter="udp and (port 67 or port 68)", prn=generate_dhcp_offer, store=0) if __name__ == "__main__": - sniff(filter="udp and (port 67 or 68)", prn=handle_dhcp_packet) \ No newline at end of file + start_dhcp_server()