From be8efc7d5179f771e357c4dc93c2aa3a2d5f510a Mon Sep 17 00:00:00 2001 From: Artur Zdolinski Date: Mon, 28 Sep 2020 00:18:34 +0200 Subject: [PATCH] v0.6a --- CHANGELOG.md | 7 ++--- tftp/nb_import.yml | 29 +++++++++++--------- ztp.py | 67 +++++++++++++++++++++++++++++++++------------- 3 files changed, 69 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47a60b6..72664f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [0.6] - 2020-09-25 +## [0.6a] - 2020-09-27 ### Added -- Open UDP socket to prevent ICMP Destination unreachable (Port unreachable) +- Open UDP socket to prevent ICMP Destination unreachable (Port unreachable) [0.6] +- Add Match DHCP Message Type = Release [0.6a] ### Fixed -- Fix issiue with DHCP-Relay answers. +- Fix issiue with DHCP-Relay answers. [0.6] ## [0.5] - 2020-08-07 ### Added diff --git a/tftp/nb_import.yml b/tftp/nb_import.yml index 368c8f0..5e51d4d 100644 --- a/tftp/nb_import.yml +++ b/tftp/nb_import.yml @@ -5,19 +5,20 @@ VM0020200000: lease_time: 3600 mac: '50:00:20:20:00:00' name_server: 8.8.8.8 - router: 10.240.43.254 + router: 10.240.40.1 subnet_mask: 255.255.252.0 - tftp_server_address: 10.240.40.254 + tftp_server_address: 192.168.254.91 vendor_specific: 1:nb_VM0020200000.sh,3:tftp VM0021210000: domain: juniper.lab hostname: Spine-21 ip: 10.240.40.21 lease_time: 3600 + mac: '50:00:21:21:00:00' name_server: 8.8.8.8 - router: 10.240.43.254 + router: 10.240.40.1 subnet_mask: 255.255.252.0 - tftp_server_address: 10.240.40.254 + tftp_server_address: 192.168.254.91 vendor_specific: 1:nb_VM0021210000.sh,3:tftp VM0030300000: domain: juniper.lab @@ -25,9 +26,10 @@ VM0030300000: ip: 10.240.40.30 lease_time: 3600 name_server: 8.8.8.8 - router: 10.240.43.254 + mac: '50:00:30:30:00:00' + router: 10.240.40.1 subnet_mask: 255.255.252.0 - tftp_server_address: 10.240.40.254 + tftp_server_address: 192.168.254.91 vendor_specific: 1:nb_VM0030300000.sh,3:tftp VM0031310000: domain: juniper.lab @@ -35,9 +37,10 @@ VM0031310000: ip: 10.240.40.31 lease_time: 3600 name_server: 8.8.8.8 - router: 10.240.43.254 + mac: '50:00:31:31:00:00' + router: 10.240.40.1 subnet_mask: 255.255.252.0 - tftp_server_address: 10.240.40.254 + tftp_server_address: 192.168.254.91 vendor_specific: 1:nb_VM0031310000.sh,3:tftp VM0032320000: domain: juniper.lab @@ -45,9 +48,10 @@ VM0032320000: ip: 10.240.40.32 lease_time: 3600 name_server: 8.8.8.8 - router: 10.240.43.254 + mac: '50:00:32:32:00:00' + router: 10.240.40.1 subnet_mask: 255.255.252.0 - tftp_server_address: 10.240.40.254 + tftp_server_address: 192.168.254.91 vendor_specific: 1:nb_VM0032320000.sh,3:tftp VM0033330000: domain: juniper.lab @@ -55,7 +59,8 @@ VM0033330000: ip: 10.240.40.33 lease_time: 3600 name_server: 8.8.8.8 - router: 10.240.43.254 + mac: '50:00:33:33:00:00' + router: 10.240.40.1 subnet_mask: 255.255.252.0 - tftp_server_address: 10.240.40.254 + tftp_server_address: 192.168.254.91 vendor_specific: 1:nb_VM0033330000.sh,3:tftp diff --git a/ztp.py b/ztp.py index 7a6e109..e2f3ff7 100755 --- a/ztp.py +++ b/ztp.py @@ -2,7 +2,7 @@ ########################################################## # ZTP (DHCP+TFTP+HTTP service) # Created by: Zdolinski Artur -# Version: 0.6 [20200925] +# Version: 0.6a [20200927] # # if you need - you can disable cache (__pycache__) # > bash# export PYTHONDONTWRITEBYTECODE=1 @@ -34,6 +34,14 @@ os.environ['PYTHONUNBUFFERED'] = '1' conf.sniff_promisc=True + +# handle_dhcp_packet(packet) +# get_option(dhcp_options, key) +# threaded(fn) +# handler(signal_received, frame) +# chaddr_to_mac(chaddr) +# op43(text_value) + def handle_dhcp_packet(packet): if DHCP in packet: # Write PCAP File if needed @@ -52,7 +60,7 @@ def handle_dhcp_packet(packet): chaddr = packet[BOOTP].chaddr src_mac = packet[Ether].src dhcp_src_mac = chaddr_to_mac(chaddr) - + # Direction if packet[Ether].src == kwargs['my_mac']: direction = colored(kwargs['interface']+"| ->[Snd]", 'green') @@ -74,7 +82,7 @@ def handle_dhcp_packet(packet): # Match DHCP Message Type = Replay (2) elif DHCP_message_type == 2: - subnet_mask = get_option(packet[DHCP].options, 'subnet_mask') + #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') @@ -102,7 +110,11 @@ def handle_dhcp_packet(packet): # Match DHCP Message Type = Ack (5) elif DHCP_message_type == 5: print(direction + colored('[Ack]['+str(hex(xid))+'] ', 'yellow') + "DHCP Server "+packet[IP].src+" ("+src_mac+") acked "+packet[BOOTP].yiaddr) - + + # Match DHCP Message Type = Release (7) + elif DHCP_message_type == 7: + print(direction + colored('[Release]['+str(hex(xid))+'] ', 'red') +'DHCP Release from ('+dhcp_src_mac+') - IP: ' + str(packet[BOOTP].ciaddr) ) + # Match DHCP Message Type = Inform (8) elif DHCP_message_type == 8: vendor_class_id = get_option(packet[DHCP].options, 'vendor_class_id') @@ -155,6 +167,26 @@ def chaddr_to_mac(chaddr): mac_format_fix = ":".join(map("{0:0>2}".format, mac_format.split(':'))) return str(mac_format_fix) +def op43(text_value): + ret = b"" + xparam = text_value.replace(" ","").split(",") + for param in xparam: + p = param.split(":") + try: + p[1] + except: + return + tag = int(p[0]) + value = p[1] + ret += struct.pack("BB", tag, len(str(value))) + str(value).encode() + ret += struct.pack("B", 255) + return(ret) + +# DhcpResponder +# -> __init__(self) +# -> get_parameters(self, path) +# -> send_offer(self, packet, offer) +# -> send_ack(self, packet, offer) class DhcpResponder(object): def __init__(self): pass @@ -282,6 +314,11 @@ def send_ack(self, packet, offer): packet = ethernet / ip / udp / bootp / dhcp sendp(packet, iface=kwargs['interface'], verbose=False) + +# HttpServer(object) +# -> __init__(self, port=80, **kwargs) +# -> start(self) +# -> stop(self) class HttpServer(object): def __init__(self, port=80, **kwargs): self.port = int(kwargs['port_http']) @@ -315,6 +352,10 @@ def stop(self): self.httpd.shutdown() return +# TftpServer(object) +# -> __init__(self, port=69, **kwargs) +# -> stop(self) +# -> start(self) class TftpServer(object): def __init__(self, port=69, **kwargs): self.port = int(kwargs['port_tftp']) @@ -335,21 +376,9 @@ def start(self): except OSError: print (colored('[Warning] ', 'red') + 'TFTP '+str(self.my_ip)+':'+str(self.port)+' port in use') -def op43(text_value): - ret = b"" - xparam = text_value.replace(" ","").split(",") - for param in xparam: - p = param.split(":") - try: - p[1] - except: - return - tag = int(p[0]) - value = p[1] - ret += struct.pack("BB", tag, len(str(value))) + str(value).encode() - ret += struct.pack("B", 255) - return(ret) - +############ +### MAIN ### +############ if __name__ == "__main__": signal(SIGINT, handler) while True: