Beispiel #1
0
    def sendTCP(self, IP, TCP, dest_address, port_list:list, num_sended):
        #Verificando si se ha llegado al limite de retransmiciones
        if (num_sended > self.MAX_RETRANS): return

        #Inicializando contador de paquetes recibidos
        self.tcp_rcv_list[dest_address] = {
            'EVENT': threading.Event(), 'COUNT': 0, 'MAX': len(port_list)
        }

        #Recorriendo lista de puertos a enviar TCP
        for dest_port in port_list:
            #Campos cabecera TCP
            TCP.Destination_Port = dest_port
            TCP.setSequence()
            
            #Enviando paquete
            self.SENDER.sendto(IP.to_bytes() + TCP.to_bytes(IP), (dest_address, dest_port))

            #Añadiendo paquetes a la lista de espera
            if num_sended == 1:
                self.tcp_wait_list[dest_address][dest_port] = {
                    'TIME': time(),
                    'SEND': num_sended
                }
            #else: self.tcp_list[dest_address][dest_port]['SEND'] = num_sended

        #Si no se recibieron los tres paquetes antes de que se venciera el timeout
        if not self.tcp_rcv_list[dest_address]['EVENT'].wait(timeout=self.TIME_OUT * num_sended):
            #Obteniendo puertos aun pendientes
            port_list = self.getPendingPorts(dest_address, port_list, TCP = True)

            if len(port_list) == 0: return

            #Retransmitir
            self.sendTCP(IP, TCP, dest_address, port_list, num_sended + 1)        
Beispiel #2
0
    def detectUDP(self, IP, UDP):
        #Campos cabecera IP
        IP.setID()

        #Variables utiles
        dest_address = IP.Destination_IP.exploded

        #Inicializando entrada de las listas
        self.udp_wait_list[dest_address] = {} #Lista de espera
        self.udp_ready_list[dest_address] = {} #Lista de sondeados

        #Creando socket de recepcion
        SOCKET_RCV = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
        SOCKET_RCV.setblocking(False)

        #Lanzando hilo de recepcion
        thread_rcv_finish = threading.Event() #Creando evento para terminar el hilo
        thread_rcv = threading.Thread(
            target=self.receiveUDP, name = "RCV UDP: " + dest_address, args=(
                thread_rcv_finish, SOCKET_RCV, dest_address
            )
        )
        thread_rcv.start()

        #Obteniendo lista de puertos
        range_ports = iter(range(self.MIN_PORT, self.MAX_PORT))

        #Recorriendo lista de puertos
        while True:
            #Eligiendo puertos a sondear
            port_list = self.getPorts(range_ports, self.UDP_SIMULTANEOUS_PORT) #2**16 de 3 en 3.

            #Si no faltan puertos
            if port_list == None: break

            #Enviando UDP a los puertos elegidos.
            self.sendUDP(IP, UDP, port_list, num_sended = 1)

        #Esperando finalizacion del hilo de recepcion
        thread_rcv_finish.set()
        thread_rcv.join()

        #Eliminando host de la lista de espera
        del self.udp_wait_list[dest_address]

        #Cerrando socket de recepcion
        SOCKET_RCV.close()
Beispiel #3
0
    def receiveTCP(self, stop_event:threading.Event, Socket, source_address):
        while not stop_event.is_set():
            #Si hay algo que leer          
            if len(select([Socket], [], [], self.TIME_OUT)[0]): #Si hay algo que leer
                data, address = Socket.recvfrom(80) #Cabecera IP + Cabecera TCP
                address = address[0]

                #Si la direccion ip no es la esperada, saltar iteracion
                if address != source_address: continue

                #Obteniendo tiempo de respuesta
                time_rcv = time()

                #Desempaquetando IP
                ip = IP.from_bytes(data)

                #Desempaquetando TCP
                tcp = TCP.from_bytes(ip.Data)
                source_port = tcp.Source_Port

                #Si el puerto no esta en la lista de espera
                if source_port not in self.tcp_wait_list[address]: continue

                #Obteniendo tiempo de envio
                time_rtt = time_rcv - self.tcp_wait_list[address][source_port]['TIME']
                num_sended = self.tcp_wait_list[address][source_port]['SEND']

                #Si tiene los flags esperados
                if (tcp.Flag_SYN and tcp.Flag_ACK) or tcp.Flag_RST:
                    #Notificando la recepcion del paquete
                    self.tcp_rcv_list[address]['COUNT'] += 1 #Aumentando contador de recibidos para esta IP

                    #Si se recibieron todos los paquetes enviados
                    if self.tcp_rcv_list[address]['COUNT'] == self.tcp_rcv_list[address]['MAX']:
                        self.tcp_rcv_list[address]['EVENT'].set() #Activar evento

                    #Eliminando de la lista de espera
                    del self.tcp_wait_list[address][source_port]

                    #Si el puerto esta abierto
                    if tcp.Flag_SYN and tcp.Flag_ACK:
                        #Agregando a lista de puertos como abierto
                        self.tcp_ready_list[address][source_port] = {
                            'TYPE': 'tcp',
                            'STATE': PortStates.open,
                            'SEND': num_sended,
                            'RTT': time_rtt   
                        }

                    #Si el puerto esta cerrado
                    elif tcp.Flag_RST: #Puerto cerrado
                        #Agregando a lista de puertos como cerrado
                        self.tcp_ready_list[address][source_port] = {
                            'TYPE': 'tcp',
                            'STATE': PortStates.closed,
                            'SEND': num_sended,
                            'RTT': time_rtt   
                        }
Beispiel #4
0
    def receiveICMP(self, type_waited:list, code_waited:list):
        Socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
        stop_event = self.rcv_ICMP_event

        #Mientras no se notifique la detencion
        while not stop_event.is_set():
            #Esperar por mensajes
            if len(select([Socket], [], [], self.TIME_OUT)[0]):
                #Leer mensajes
                data, address = Socket.recvfrom(80)
                address = address[0]

                #Guardando tiempo de recepcion
                time_rcv = time()

                #Si es una IP que no esta en lista de espera
                if (address not in self.udp_wait_list) and (address not in self.tcp_wait_list):
                    continue

                #Desempaquetando IP e ICMP
                ip = IP.from_bytes(data)
                icmp = ICMP.from_bytes(ip.Data)

                #Si no es del tipo y codigo esperado
                if (icmp.Type not in type_waited) and (icmp.Code not in code_waited):
                    continue

                if icmp.Type == 3:
                    #Desempaquetando paquete original
                    ip_origin = IP.from_bytes(icmp.Data)

                    #Si fue recibido en respuesta a mensaje UDP
                    if ip_origin.Protocol == socket.IPPROTO_UDP:
                        self.rcv_ICMP_UDP(icmp, UDP.from_bytes(ip_origin.Data), address, time_rcv)

                    #Si fue recibido en respuesta a mensaje TCP
                    elif ip_origin.Protocol == socket.IPPROTO_TCP:
                        self.rcv_ICMP_TCP(icmp, TCP.from_bytes(ip_origin.Data), address, time_rcv)

            #Si se notifico la detencion
            if stop_event.is_set(): Socket.close()
Beispiel #5
0
    def receiveUDP(self, stop_event:threading.Event, Socket, source_address):
        while not stop_event.is_set():
            #Si hay algo que leer          
            if len(select([Socket], [], [], self.TIME_OUT)[0]): #Si hay algo que leer
                data, address = Socket.recvfrom(80) #Cabecera IP + Cabecera UDP
                address = address[0]

                #Si la direccion ip no es la esperada, saltar iteracion
                if address != source_address: continue

                #Obteniendo tiempo de respuesta
                time_rcv = time()

                #Desempaquetando IP
                ip = IP.from_bytes(data)

                #Desempaquetando UDP
                udp = UDP.from_bytes(ip.Data)
                source_port = udp.Source_Port

                #Si el puerto no esta en la lista de espera
                if source_port not in self.udp_wait_list[address]: continue

                #Obteniendo tiempo de envio
                time_rtt = time_rcv - self.udp_wait_list[address][source_port]['TIME']
                num_sended = self.udp_wait_list[address][source_port]['SEND']

                #Notificando la recepcion del paquete
                self.udp_rcv_list[address]['COUNT'] += 1 #Aumentando contador de recibidos para esta IP

                #Si se recibieron todos los paquetes enviados
                if self.udp_rcv_list[address]['COUNT'] == self.udp_rcv_list[address]['MAX']:
                    self.udp_rcv_list[address]['EVENT'].set() #Activar evento

                #Eliminando de la lista de espera
                del self.udp_wait_list[address][source_port]

                #Agregando a lista de puertos como filtrado
                self.udp_ready_list[address][udp.Destination_Port] = {
                    'TYPE': 'udp',
                    'STATE': PortStates.open_filtered,
                    'SEND': num_sended,
                    'RTT': time_rtt                    
                }
Beispiel #6
0
    def to_bytes(self, IP_H:IP):    
        Checksum = self.Checksum
            
        if (Checksum == None):
            #Obteniendo pseudocabecera IP
            Pseudo_IPHeader = IP_H.getPseudoHeader(self.Length)

            #Obteniendo copia de objeto UDP
            UDP_COPY = self.copy()
            UDP_COPY.Checksum = 0 # 0 para forzar el calculo del checksum

            #Calculando checksum (Pseudo cabecera IP + Cabecera UDP + Datos)
            Checksum = Tools.Checksum(Pseudo_IPHeader + UDP_COPY.to_bytes(None))
        
        #Empaquetando segmento y devolviendolo
        return struct.pack("!HHHH",
            self.Source_Port,        # 2 Bytes -> 16 bits
            self.Destination_Port,   # 2 Bytes -> 16 bits
            self.Length,             # 2 Bytes -> 16 bits
            Checksum            # 2 Bytes -> 16 bits
        ) + self.Data
Beispiel #7
0
    def to_bytes(self, IP_HEADER:IP):
        Checksum = self.Checksum

        if (Checksum == None):
            #Longitud del segmento TCP (Cabecera + Datos)
            Length = self.Header_Length + len(self.Data)

            #Obteniendo pseudocabecera IP
            Pseudo_IPHeader = IP_HEADER.getPseudoHeader(Length)

            #Obteniendo copia objeto TCP y modificando campos
            TCP_COPY = self.copy()
            TCP_COPY.Checksum = 0 #Forzar el calculo del checksum

            #Calculando checksum (Pseudo cabecera IP + Cabecera TCP + Datos)
            Checksum = Tools.Checksum(Pseudo_IPHeader + TCP_COPY.to_bytes(None))
        
        #Empaquetando segmento y devolviendolo
        return struct.pack("!HHLLBBHHH",
            self.Source_Port,        # 2 Bytes -> 16 bits
            self.Destination_Port,   # 2 Bytes -> 16 bits
            self.Sequence,           # 4 Bytes -> 32 bits
            self.Sequence_ACK,       # 4 Bytes -> 32 bits
            (int((self.Header_Length / 4)) << 4),   # 1 Bytes -> 4 bits + 4 bits sin usar
            (
                             # 2 bits sin usar
                (self.Flag_URG << 5) + # 1 bits
                (self.Flag_ACK << 4) + # 1 bits
                (self.Flag_PSH << 3) + # 1 bits
                (self.Flag_RST << 2) + # 1 bits
                (self.Flag_SYN << 1) + # 1 bits
                (self.Flag_FIN)        # 1 bits
            ),
            self.Announced_Window,             # 2 Bytes -> 16 bits
            Checksum,           # 2 Bytes -> 16 bits
            self.Urg_Pointer,            # 2 Bytes -> 16 bits
        ) + self.Data
Beispiel #8
0
            IP_RECEIVE_NAME = socket.gethostbyaddr(IP_RECEIVE[0])[0]
        except socket.herror:
            #Si la IP no tiene asociada ningun nombre, entonces guardamos "-"
            IP_RECEIVE_NAME = '-'

        #Imprimiendo la IP y el nombre (si lo tiene) del que envio el ICMP, mas el RTT de cada respuesta.
        print("{} ({})\t\t{}\n".format(IP_RECEIVE[0], IP_RECEIVE_NAME,
                                       [str(n) + " ms" for n in timer]))

    #Imprimiendo informe avanzado
    if (ADVANCED_MODE == True and len(packets) > 0):
        print("    Paquetes de respuesta (IP):")
        #Recorriendo la lista que contiene cada paquete IP recibido anteriormente.
        for packet in packets:
            ip = IPPacket(
                packet
            )  #Obteniendo un objeto de la clase IP, que se encarga de
            #separar cada campo del paquete IP.

            #Imprimiendo campos mas relevantes del paquete IP actual.
            print(
                "    {} | ( {} => {} )\tVersion = {} , ID = {} , Longitud datagrama = {} , DF = {} , MF = {} , TTL = {}"
                .format(
                    packets.index(packet) + 1, ip.getSourceAddress(),
                    ip.getDestinationAddress(), ip.version, ip.identificador,
                    ip.longitud_trama, ip.DontFragment, ip.MoreFragment,
                    ip.TTL))

            #Guardando en la lista, el paquete ICMP contenido dentro de este paquete IP.
            packets_icmp.append(ip.Data)