Example #1
0
    def connect(self, ip, port):  #Ajouter support du dns
        """
        This method try to connect to the given ip and port. If the
        TCP session is not CLOSED the operations are aborted. Else a local
        port is generated, an entry is added in iptables to preven the kernel
        to disturbe our connection and then a SYN packet is sent. Then the
        connection state is switched to SYN_SENT. The method will then loop
        for 20 seconds checking if the state has changed to ESTABLISHED. If 
        not it means that a problem occured and everything is rolled back.
        """
        if isinstance(self.state, State_CLOSED):
            self.localPort = random.randrange(1200, 65535)
            self.remoteIP = ip
            self.remotePort = port

            if not re.match(self.ipregex, ip):  #Then this is a dn
                realip = transversal_layer_access["DNS"].nslookup(ip)
                if realip:
                    self.remoteIP = realip
                else:
                    raise Exception(
                        "[Errno -5] No address associated with hostname")

            #starting from here remoteIP contains the destination IP not DN or whatever
            block_outgoing_packets('tcp', None, None, self.remoteIP, port)
            self.connectionID = (
                self.remoteIP, self.remotePort, self.localIP, self.localPort
            )  #Switch order because we are interested in receiving incoming packet so src dst is switch
            self.lowerLayers["default"].register_upper_layer(
                self.connectionID, self)
            self._send_SYN()
            self.switch_state(State_SYN_SENT(self))
            #---- Wait for the connection to be established ----

            exponential_backoff_values = [
                3 * pow(2, x) for x in range(self.syn_retries)
            ]  #Precompute waiting intervals
            for timeout in exponential_backoff_values:
                instant = time.time()
                while (instant + timeout > time.time()):
                    if isinstance(self.state, State_ESTABLISHED):
                        return True
                self._send_SYN()

            #We have not received syn/ack so rollback connection
            unblock_outgoing_packets('tcp', None, None, self.remoteIP, port)
            self.lowerLayers["default"].unregister_upper_layer(
                self.connectionID)
            return False  #No connection can occur if port is not open, arp request failed..
            #----------------------------------------------------
        else:
            print("Not in consistent state (" + str(self.state) + ")")
            return False
Example #2
0
    def packet_received(self, packet, **kwargs):
        if packet.flags == SYN:  #Don't check if the dstport is the same because it has been check in tcp
            #--- Check we have not exceeded the number of connections
            count = 0
            for sess in self.session.connections:
                if not isinstance(sess.state, State_CLOSED):
                    count += 1
            if count >= self.session.nbconntoaccept:
                self.session.sendRST(packet, **kwargs)
                return
            #--------------------------------------------------
            session = TCPSession(self.session.interface)
            session.seqNo = packet.ack
            session.ackNo = packet.seq + 1
            session.localPort = packet.dport
            session.remoteIP = kwargs["IP"]["src"]
            session.remotePort = packet.sport

            block_outgoing_packets('tcp', None, None, session.remoteIP,
                                   session.remotePort)

            connID = (session.remoteIP, session.remotePort, session.localIP,
                      session.localPort)
            session.connectionID = connID

            self.session.lowerLayers["default"].register_layer_full(
                connID, session)
            if self.session.newinstance:
                newapp = self.session.app.__new__(type(self.session.app))
                newapp.__init__()
                session.register_layer(newapp)
                session.upperLayers["Raw"].hook_incoming(
                    packet, **kwargs
                )  #Cause if a new instance is created the SYN packet is received by the socket server in listen, and not the application itself so call hook again here
            else:
                session.register_upper_layer("Raw", self.session.app)
                self.session.app.register_lower_layer(session.connectionID,
                                                      session)
                #session.register_layer_full("Raw", self.session.app)
            session._send_SYNACK(packet)
            session.switch_state(State_SYN_RCVD(session))
            self.session.connections.append(session)
        elif _has_flags(packet.flags,
                        RST):  #(TCP/IP illustrated Volume 2 p.999)
            pass  #Ignore the packet
        elif _has_flags(packet.flags, ACK):
            print 'state_listen2'
            self.session.sendRST(packet, **kwargs)
        else:
            pass  #What should we do ?
Example #3
0
 def bind(self, port, app=None, newinstance=False):
     """
     The bind method is quite ligthweight. It justs register
     itself to the TCP protocol as a handler and an entry is added
     to iptables to prevent the Hosting host to reply with RST.
     Note app and newinstance define on which TCPApplication client
     connections should be redirected and if the TCPApplication should
     be forked for every client or not.
     """
     self.app = app if app else TCPApplication()
     self.newinstance = newinstance
     self.localPort = port
     block_outgoing_packets("tcp", self.localIP, self.localPort, None, None)
     self.connectionID = (self.localIP, self.localPort)
     self.lowerLayers['default'].register_upper_layer(self.connectionID, self)
Example #4
0
 def bind(self, port, app=None, newinstance=False):
     """
     The bind method is quite ligthweight. It justs register
     itself to the TCP protocol as a handler and an entry is added
     to iptables to prevent the Hosting host to reply with RST.
     Note app and newinstance define on which TCPApplication client
     connections should be redirected and if the TCPApplication should
     be forked for every client or not.
     """
     self.app = app if app else TCPApplication()
     self.newinstance = newinstance
     self.localPort = port
     block_outgoing_packets("tcp", self.localIP, self.localPort, None, None)
     self.connectionID = (self.localIP, self.localPort)
     self.lowerLayers['default'].register_upper_layer(
         self.connectionID, self)
Example #5
0
 def connect(self, ip, port):  #Ajouter support du dns
     """
     This method try to connect to the given ip and port. If the
     TCP session is not CLOSED the operations are aborted. Else a local
     port is generated, an entry is added in iptables to preven the kernel
     to disturbe our connection and then a SYN packet is sent. Then the
     connection state is switched to SYN_SENT. The method will then loop
     for 20 seconds checking if the state has changed to ESTABLISHED. If 
     not it means that a problem occured and everything is rolled back.
     """
     if isinstance(self.state, State_CLOSED):
         self.localPort = random.randrange(1200, 65535)
         self.remoteIP = ip
         self.remotePort = port
         
         if not re.match(self.ipregex, ip): #Then this is a dn
             realip = transversal_layer_access["DNS"].nslookup(ip)
             if realip:
                 self.remoteIP = realip
             else:
                 raise Exception("[Errno -5] No address associated with hostname")
         
         #starting from here remoteIP contains the destination IP not DN or whatever
         block_outgoing_packets('tcp', None, None, self.remoteIP, port)
         self.connectionID = (self.remoteIP, self.remotePort, self.localIP, self.localPort)  #Switch order because we are interested in receiving incoming packet so src dst is switch
         self.lowerLayers["default"].register_upper_layer(self.connectionID, self)
         self._send_SYN()
         self.switch_state(State_SYN_SENT(self))
         #---- Wait for the connection to be established ----
         
         exponential_backoff_values = [3*pow(2, x) for x in range(self.syn_retries)]  #Precompute waiting intervals
         for timeout in exponential_backoff_values:
             instant = time.time()
             while (instant + timeout > time.time()):
                 if isinstance(self.state, State_ESTABLISHED):
                     return True
             self._send_SYN()
         
         #We have not received syn/ack so rollback connection
         unblock_outgoing_packets('tcp', None, None, self.remoteIP, port)
         self.lowerLayers["default"].unregister_upper_layer(self.connectionID)
         return False #No connection can occur if port is not open, arp request failed..
         #----------------------------------------------------
     else:
         print("Not in consistent state ("+str(self.state)+")")
         return False
Example #6
0
 def packet_received(self, packet, **kwargs):
     if packet.flags == SYN:  #Don't check if the dstport is the same because it has been check in tcp
         #--- Check we have not exceeded the number of connections
         count = 0
         for sess in self.session.connections:
             if not isinstance(sess.state, State_CLOSED):
                 count += 1
         if count >= self.session.nbconntoaccept:
             self.session.sendRST(packet, **kwargs)
             return
         #--------------------------------------------------
         session = TCPSession(self.session.interface)
         session.seqNo = packet.ack
         session.ackNo = packet.seq + 1
         session.localPort = packet.dport
         session.remoteIP = kwargs["IP"]["src"]
         session.remotePort = packet.sport
                          
         block_outgoing_packets('tcp', None, None, session.remoteIP, session.remotePort)
         
         connID = (session.remoteIP, session.remotePort, session.localIP, session.localPort)
         session.connectionID = connID
         
         self.session.lowerLayers["default"].register_layer_full(connID, session)
         if self.session.newinstance:
             newapp = self.session.app.__new__(type(self.session.app))
             newapp.__init__()
             session.register_layer(newapp)
             session.upperLayers["Raw"].hook_incoming(packet, **kwargs) #Cause if a new instance is created the SYN packet is received by the socket server in listen, and not the application itself so call hook again here
         else:
             session.register_upper_layer("Raw", self.session.app)
             self.session.app.register_lower_layer(session.connectionID, session)
             #session.register_layer_full("Raw", self.session.app)
         session._send_SYNACK(packet)
         session.switch_state(State_SYN_RCVD(session))
         self.session.connections.append(session)
     elif _has_flags(packet.flags, RST): #(TCP/IP illustrated Volume 2 p.999)
         pass  #Ignore the packet
     elif _has_flags(packet.flags, ACK):
         self.session.sendRST(packet, **kwargs)
     else:
         pass  #What should we do ?