Exemple #1
0
    def ip_fragment(self, packet, logger):
        """
        Perform IP fragmentation.
        """
        if not packet.haslayer("IP") or not hasattr(packet["IP"], "load"):
            return packet, packet.copy(
            )  # duplicate if no TCP or no payload to segment
        load = ""
        if packet.haslayer("TCP"):
            load = bytes(packet["TCP"])
        elif packet.haslayer("UDP"):
            load = bytes(packet["UDP"])
        else:
            load = bytes(packet["IP"].load)

        # If there is no load, duplicate the packet
        if not load:
            return packet, packet.copy()

        if self.fragsize == -1 or (self.fragsize *
                                   8) > len(load) or len(load) <= 8:
            fragsize = int(int(((int(len(load) / 2)) / 8)) * 8)
            frags = self.fragment(packet.copy().packet, fragsize=fragsize)
        else:
            # packet can be fragmented as requested
            frags = self.fragment(packet.copy().packet,
                                  fragsize=self.fragsize * 8)
        packet1 = actions.packet.Packet(frags[0])
        packet2 = actions.packet.Packet(frags[1])
        if self.correct_order:
            return packet1, packet2
        else:
            return packet2, packet1
Exemple #2
0
    def handle_inbound_packet(self, divert_packet):
        """
        Handles inbound packets. Process the packet and forward it to the strategy if needed.
        """

        packet = actions.packet.Packet(IP(divert_packet.raw.tobytes()))

        self.seen_packets.append(packet)

        self.logger.debug("Received packet: %s", str(packet))

        # Run the given strategy
        packets = self.strategy.act_on_packet(packet, self.logger, direction="in")

        # GFW will send RA packets to disrupt a TCP stream
        if packet.haslayer("TCP") and packet.get("TCP", "flags") == "RA":
            self.logger.debug("Detected GFW censorship - strategy failed.")
            self.censorship_detected = True

        # Branching is disabled for the in direction, so we can only ever get
        # back 1 or 0 packets. If zero, return and do not send packet. 
        if not packets:
            return

        # If the strategy requested us to sleep before accepting on this packet, do so here
        if packets[0].sleep:
            time.sleep(packets[0].sleep)

        # Accept the modified packet
        self.mysend(packets[0], Direction.INBOUND)
Exemple #3
0
    def tcp_segment(self, packet, logger):
        """
        Segments a packet into two, given the size of the first packet (0:fragsize)
        Always returns two packets, since fragment is a branching action, so if we
        are unable to segment, it will duplicate the packet.
        """
        if not packet.haslayer("TCP") or not hasattr(
                packet["TCP"], "load") or not packet["TCP"].load:
            return packet, packet.copy(
            )  # duplicate if no TCP or no payload to segment

        # Get the original payload and delete it from the packet so it
        # doesn't come along when copying the TCP layer
        payload = packet["TCP"].load
        del (packet["TCP"].load)

        fragsize = self.fragsize
        if self.fragsize == -1 or self.fragsize > len(payload) - 1:
            fragsize = int(len(payload) / 2)

        # Craft new packets
        pkt1 = IP(packet["IP"]) / payload[:fragsize]
        pkt2 = IP(packet["IP"]) / payload[fragsize:]

        # We cannot rely on scapy's native parsing here - if a previous action has changed the
        # fragment offset, scapy will not identify this as TCP, so we must do it for scapy
        if not pkt1.haslayer("TCP"):
            pkt1 = IP(packet["IP"]) / TCP(bytes(pkt1["IP"].load))

        if not pkt2.haslayer("TCP"):
            pkt2 = IP(packet["IP"]) / TCP(bytes(pkt2["IP"].load))

        packet1 = actions.packet.Packet(pkt1)
        packet2 = actions.packet.Packet(pkt2)

        # Reset packet2's SYN number
        packet2["TCP"].seq += fragsize

        del packet1["IP"].chksum
        del packet2["IP"].chksum
        del packet1["IP"].len
        del packet2["IP"].len
        del packet1["TCP"].chksum
        del packet2["TCP"].chksum
        del packet1["TCP"].dataofs
        del packet2["TCP"].dataofs

        if self.correct_order:
            return [packet1, packet2]
        else:
            return [packet2, packet1]
Exemple #4
0
    def __packet_callback(self, scapy_packet):
        """
        This callback is called whenever a packet is applied.
        Returns true if it should finish, otherwise, returns false.
        """
        packet = actions.packet.Packet(scapy_packet)
        for proto in ["TCP", "UDP"]:
            if (packet.haslayer(proto)
                    and ((packet[proto].sport == self.port) or
                         (packet[proto].dport == self.port))):
                break
        else:
            return self.stop_sniffing_flag

        self.logger.debug(str(packet))
        self.packet_dumper.write(scapy_packet)
        return self.stop_sniffing_flag
Exemple #5
0
    def in_callback(self, nfpacket):
        """
        Callback bound to the incoming nfqueue rule. Since we can't
        manually send packets to ourself, process the given packet here.
        """
        if not self.running_nfqueue:
            return
        packet = actions.packet.Packet(IP(nfpacket.get_payload()))

        self.seen_packets.append(packet)

        self.logger.debug("Received packet: %s", str(packet))

        # Run the given strategy
        packets = self.strategy.act_on_packet(packet,
                                              self.logger,
                                              direction="in")

        # GFW will send RA packets to disrupt a TCP stream
        if packet.haslayer("TCP") and packet.get("TCP", "flags") == "RA":
            self.logger.debug("Detected GFW censorship - strategy failed.")
            self.censorship_detected = True

        # Branching is disabled for the in direction, so we can only ever get
        # back 1 or 0 packets. If zero, drop the packet.
        if not packets:
            nfpacket.drop()
            return

        # Otherwise, overwrite this packet with the packet the action trees gave back
        nfpacket.set_payload(bytes(packets[0]))

        # If the strategy requested us to sleep before accepting on this packet, do so here
        if packets[0].sleep:
            time.sleep(packets[0].sleep)

        # Accept the modified packet
        nfpacket.accept()