from scapy.all import Ether, IP, UDP, BOOTP, DHCP, sendp, sniff, RandMAC import random # Configuration du serveur DHCP DHCP_SERVER_IP = "192.168.1.10" # 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.1" # Adresse IP du routeur DNS_IP = "192.168.1.1" # Adresse IP du serveur DNS LEASE_TIME = 86400 # Durée du bail (en secondes) allocated_ips = {} # Pour stocker les adresses IP allouées avec leurs MACs # Générer une adresse IP dans la plage DHCP def generate_ip(): while True: ip = f"192.168.1.{random.randint(100, 200)}" if ip not in allocated_ips.values(): # Éviter la réutilisation d'une IP allouée return ip # Fonction pour extraire une option DHCP par clé def get_option(dhcp_options, key): for i in dhcp_options: if i[0] == key: return i[1] return None # Générer une réponse DHCP Offer def send_dhcp_offer(packet): client_mac = packet[Ether].src offered_ip = generate_ip() allocated_ips[client_mac] = offered_ip # Allouer l'adresse IP au client # Construire et envoyer la réponse DHCP Offer dhcp_offer = ( Ether(src=RandMAC(), dst=client_mac) / 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), ("name_server", DNS_IP), ("end") ]) ) sendp(dhcp_offer, iface='ens33', verbose=False) # Utilisation de ens33 # Générer une réponse DHCP Ack def send_dhcp_ack(packet): client_mac = packet[Ether].src requested_ip = get_option(packet[DHCP].options, 'requested_addr') if requested_ip in allocated_ips.values() and allocated_ips[client_mac] == requested_ip: # Construire et envoyer la réponse DHCP Ack dhcp_ack = ( Ether(src=RandMAC(), dst=client_mac) / IP(src=DHCP_SERVER_IP, dst='255.255.255.255') / UDP(sport=67, dport=68) / BOOTP(op=2, yiaddr=requested_ip, siaddr=DHCP_SERVER_IP, chaddr=client_mac) / DHCP(options=[ ("message-type", "ack"), ("server_id", DHCP_SERVER_IP), ("lease_time", LEASE_TIME), ("subnet_mask", SUBNET_MASK), ("router", ROUTER_IP), ("name_server", DNS_IP), ("end") ]) ) sendp(dhcp_ack, iface='ens33', verbose=False) # Utilisation de ens33 print(f"IP {requested_ip} allouée à {client_mac}") # Gérer les paquets DHCP reçus def handle_dhcp_packet(packet): if DHCP in packet: dhcp_message_type = packet[DHCP].options[0][1] # Correspondance avec DHCP Discover if dhcp_message_type == 1: print(f"DHCP Discover reçu de {packet[Ether].src}") send_dhcp_offer(packet) # Correspondance avec DHCP Request elif dhcp_message_type == 3: print(f"DHCP Request reçu de {packet[Ether].src}") send_dhcp_ack(packet) # Correspondance avec d'autres paquets (ex. DHCP Release, Decline) else: print(f"Autre paquet DHCP de {packet[Ether].src}") # Démarrer le serveur DHCP if __name__ == "__main__": print("Serveur DHCP en cours d'exécution...") sniff(filter="udp and (port 67 or port 68)", prn=handle_dhcp_packet, store=0, iface='ens33')