def __restore_ntp_pck(self, ntp: NTP) -> NTP: self.log.debug('Send timestamp for reconstruction: ' + str(ntp.sent)) sent_time_stamp = datetime.fromtimestamp( ntplib.ntp_to_system_time(ntp.sent)) sent_time_stamp = sent_time_stamp.replace(year=datetime.now().year) sent_time_stamp_as_ntp = ntplib.system_to_ntp_time( sent_time_stamp.timestamp()) ntp.sent = sent_time_stamp_as_ntp self.log.debug('Send timestamp after reconstruction: ' + str(ntp.sent)) pck = CP3Package(ntp) if NTPMode.from_bit_string(pck.mode()) is NTPMode.CLIENT: self.log.debug("Restored in Client mode") ntp.ref = 0 ntp.orig = 0 ntp.recv = 0 if NTPMode.from_bit_string(pck.mode()) is NTPMode.SERVER \ or NTPMode.from_bit_string(pck.mode()) is NTPMode.BROADCAST_SERVER: self.log.debug("Restored in Server mode") origin_last_32 = pck.origin_timestamp()[32:64] received_last_32 = pck.receive_timestamp()[32:64] transmit_first_32 = pck.origin_timestamp()[0:32] pck.set_origin_timestamp(transmit_first_32 + origin_last_32) pck.set_receive_timestamp(transmit_first_32 + received_last_32) ntp = pck.ntp() self.log.debug("Reconstruction complete.") #ntp.show() return ntp
def run(self, with_response: bool = True): """ Starts the sniffing for incoming NTP client packages. Note that further packages are not sniffed while one package is processed. """ print('Starting server.... listening on interface ' + self.sniff_interface) while True: pck = self.next_ntp_packet() received_time = ntp_time_now() if pck[IP].dst != self._host_ip: print('This package was not meant for the server...') continue pck_ntp = pck[NTP] if pck_ntp.mode != 3: continue self._req_interceptor.intercept_req(pck_ntp) if not with_response: continue if self.debug: print('Got a NTP client request, creating response.') # ntp_resp = self._send_ntp_client_request(ntp=pck_ntp) response_from_server_ntp = NTP() # ntp_resp[NTP] response_from_server_ntp.recv = received_time response_from_server_ntp.ref = self.reference_time # response_from_server_ntp.id = str(pck[IP].dst) response_from_server_ntp = self._res_interceptor.intercept_res( response_from_server_ntp) response = IP(dst=pck[IP].src, src=pck[IP].dst) / UDP() / response_from_server_ntp if self.debug: response.show() send(response)
def init_ntp_pck(num_of_digits_to_fill_up: int = 12) -> NTP: """ Creates a new NTP package, fills all 4 64 bit timestamps with the current time and fills up the last bits with random values, since they are set to 0 by Scapy :param num_of_digits_to_fill_up: The amount of digits to fill up. :return: The newly created NTP package """ ntp = NTP() ntp.ref = ntp_time_now() ntp.sent = ntp_time_now() ntp.orig = ntp_time_now() ntp.recv = ntp_time_now() raw_ntp = RawNTP(ntp) f_ref = raw_ntp.reference_timestamp() f_trans = raw_ntp.transmit_timestamp() f_orig = raw_ntp.origin_timestamp() f_recv = raw_ntp.receive_timestamp() for i in range(num_of_digits_to_fill_up): pos = 64 - i f_ref = f_ref[:pos - 1] + str(random.randint(0, 1)) + f_ref[pos:] f_trans = f_trans[:pos - 1] + str(random.randint(0, 1)) + f_trans[pos:] f_orig = f_orig[:pos - 1] + str(random.randint(0, 1)) + f_orig[pos:] f_recv = f_recv[:pos - 1] + str(random.randint(0, 1)) + f_recv[pos:] assert len(f_ref) == 64 assert len(f_trans) == 64 assert len(f_orig) == 64 assert len(f_recv) == 64 raw_ntp.set_reference_timestamp(f_ref) raw_ntp.set_transmit_timestamp(f_trans) raw_ntp.set_origin_timestamp(f_orig) raw_ntp.set_receive_timestamp(f_recv) ntp = raw_ntp.ntp() return ntp
def init_ntp_client_pck(num_of_digits_to_fill_up: int = 12): """ Creates a new NTP package, fills only the transmit 64 bit timestamps with the current time and fills up the last bits with random values, since they are set to 0 by Scapy :param num_of_digits_to_fill_up: The amount of digits to fill up. :return: The newly created NTP package """ ntp = NTP() ntp.sent = ntp_time_now() ntp.ref = 0 ntp.orig = 0 ntp.recv = 0 raw_ntp = RawNTP(ntp) f_trans = raw_ntp.transmit_timestamp() for i in range(num_of_digits_to_fill_up): pos = 64 - i f_trans = f_trans[:pos - 1] + str(random.randint(0, 1)) + f_trans[pos:] assert len(f_trans) == 64 raw_ntp.set_transmit_timestamp(f_trans) ntp = raw_ntp.ntp() return ntp