def cb(payload): global count print "python callback called !" count += 1 data = payload.get_data() pkt = ip.IP(data) if pkt.p == ip.IP_PROTO_TCP: print " len %d proto %s src: %s:%s dst %s:%s " % ( payload.get_length(), pkt.p, inet_ntoa(pkt.src), pkt.tcp.sport, inet_ntoa(pkt.dst), pkt.tcp.dport, ) else: print " len %d proto %s src: %s dst %s " % ( payload.get_length(), pkt.p, inet_ntoa(pkt.src), inet_ntoa(pkt.dst), ) payload.set_verdict(nfqueue.NF_ACCEPT) sys.stdout.flush() return 1
def _write_SOCKS5_address(self, addr, file): """ Return the host and port packed for the SOCKS5 protocol, and the resolved address as a tuple object. """ host, port = addr proxy_type, _, _, rdns, username, password = self.proxy # If the given destination address is an IP address, we'll # use the IPv4 address request even if remote resolving was specified. try: addr_bytes = socket.inet_aton(host) file.write(b"\x01" + addr_bytes) host = socket.inet_ntoa(addr_bytes) except socket.error: # Well it's not an IP number, so it's probably a DNS name. if rdns: # Resolve remotely host_bytes = host.encode('idna') file.write( b"\x03" + chr(len(host_bytes)).encode() + host_bytes) else: # Resolve locally addr_bytes = socket.inet_aton(socket.gethostbyname(host)) file.write(b"\x01" + addr_bytes) host = socket.inet_ntoa(addr_bytes) file.write(struct.pack(">H", port)) return host, port
def handle_log_http(self, pkt, pkt_dir): ip_section, transport_section, app_section = self.split_by_layers(pkt) if pkt_dir == PKT_DIR_OUTGOING: # is a HTTP request internal_port = struct.unpack("!H", transport_section[0:2])[0] ext_IP_address = socket.inet_ntoa(ip_section[16:20]) if not self.http_tcp_conns.has_key((ext_IP_address, internal_port)): self.http_tcp_conns[(ext_IP_address, internal_port)] = HttpTcpConnection(HttpTcpConnection.INACTIVE) connection = self.http_tcp_conns[(ext_IP_address, internal_port)] if connection.analyze(ip_section, transport_section, app_section, pkt_dir): self.iface_ext.send_ip_packet(pkt) self.log_http(connection) else: # is a HTTP response internal_port = struct.unpack("!H", transport_section[2:4])[0] ext_IP_address = socket.inet_ntoa(ip_section[12:16]) if self.http_tcp_conns.has_key((ext_IP_address, internal_port)): connection = self.http_tcp_conns[(ext_IP_address, internal_port)] if connection.analyze(ip_section, transport_section, app_section, pkt_dir): self.iface_int.send_ip_packet(pkt) self.log_http(connection) else: self.iface_int.send_ip_packet(pkt)
def read_ip_pac(link_packet, link_layer_parser): # ip header n_protocol, ip_packet = link_layer_parser(link_packet) if n_protocol == NetworkProtocol.IP or n_protocol == NetworkProtocol.PPP_IP: src_mac = ":".join("{:02x}".format(ord(c)) for c in link_packet[6:12]) ip_base_header_len = 20 ip_header = ip_packet[0:ip_base_header_len] (ip_info, ip_length, protocol) = struct.unpack(b'!BxH5xB10x', ip_header) # real ip header len. ip_header_len = (ip_info & 0xF) * 4 ip_version = (ip_info >> 4) & 0xF # skip all extra header fields. if ip_header_len > ip_base_header_len: pass # not tcp, skip. if protocol != TransferProtocol.TCP: return 0, None, None, None, None source = socket.inet_ntoa(ip_header[12:16]) dest = socket.inet_ntoa(ip_header[16:]) return 1, source, dest, ip_packet[ip_header_len:ip_length], src_mac elif n_protocol == NetworkProtocol.IPV6: # TODO: deal with ipv6 package return 0, None, None, None, None else: # skip return 0, None, None, None, None
def handleDpMessage(self, msgType, data): """ Handles messages from the OFX data path component. struct FlowEntryNoHash{ struct FlowKey key; uint32_t permission; uint32_t added; // Has the rule been added? uint32_t byteCt; // how many bytes have we seen? }; """ if msgType == FLOWSTATS: flowCt = len(data)/24 idx = 0 ptr = 0 while idx<flowCt: ptr = idx * (24) src = socket.inet_ntoa(data[ptr:ptr+4]) dst = socket.inet_ntoa(data[ptr+4:ptr+8]) sport,dport = struct.unpack("!HH", data[ptr+8:ptr+12]) permission,added,byteCt = struct.unpack("!III",data[ptr+12:ptr+24]) # print ("DP AGENT flow %s: %s (%s) --> %s (%s) -- %s bytes"%(idx, src, sport, dst, dport, byteCt)) key = (src,dst,sport,dport) if key not in self.flowStatsOFX: self.flowStatsOFX[key] = 0 self.flowStatsOFX[key] =byteCt idx += 1 else: print ("DDoS module: unknown message type.")
def _ParseOtherStreams(self, other_list, trunc_list): """Process PCAP packets that are not IP packets. For all packets that were not IP packets, create stream containers depending on the type of packet. Args: other_list: List of non-ip packets. trunc_list: A list of packets that truncated strangely and could not be turned into a stream. Returns: A list of stream objects (instances of Stream). """ other_streams = [] for packet_values in other_list: stream_object = self._ParseOtherPacket(packet_values) if stream_object: other_streams.append(stream_object) for packet_values in trunc_list: ip_packet = packet_values[2] source_ip_address = socket.inet_ntoa(ip_packet.src) destination_ip_address = socket.inet_ntoa(ip_packet.dst) stream_object = Stream( packet_values, ip_packet.data, source_ip_address, destination_ip_address, u'BAD') stream_object.protocolData = u'Bad truncated IP packet' other_streams.append(stream_object) return other_streams
def domainsandips(pcappath, allips=False): domains = set([]) ips = set([]) pcap = Reader(file(pcappath, 'rb')) for _, data in pcap: eth = Ethernet(data) ip = eth.data trans = ip.data try: if type(trans) == dpkt.tcp.TCP: ips.add(socket.inet_ntoa(ip.src)) ips.add(socket.inet_ntoa(ip.dst)) if type(trans) == dpkt.udp.UDP and \ (trans.sport == 53 or trans.dport == 53): dns = dpkt.dns.DNS(ip.data.data) for query in dns.qd: # asciify is the standard for normalizing domains # to ascii. Also we don't want any tab characters to # f**k up our R script. domains.add(asciify(query.name).replace('\t', '')) if allips: for answer in dns.an: try: ips.add(socket.inet_ntoa(answer.rdata)) except socket.error as e: pass except Exception as e: pass return (domains, ips)
def cb(i,payload): print "payload len ", payload.get_length() data = payload.get_data() pkt = ip.IP(data) print "proto:", pkt.p print "source: %s" % inet_ntoa(pkt.src) print "dest: %s" % inet_ntoa(pkt.dst) if pkt.p == ip.IP_PROTO_TCP: print " sport: %s" % pkt.tcp.sport print " dport: %s" % pkt.tcp.dport print " flags: %s" % pkt.tcp.flags if pkt.tcp.flags & tcp.TH_PUSH: pkt2 = pkt print "PUSH *****" print pkt2.tcp.data old_len = len(pkt2.tcp.data) #pkt2.tcp.data = "GET /\r\n" pkt2.tcp.data = str(pkt2.tcp.data).replace('love','hate') print pkt2.tcp.data pkt2.len = pkt2.len - old_len + len(pkt2.tcp.data) pkt2.tcp.sum = 0 pkt2.sum = 0 ret = payload.set_verdict_modified(nfqueue.NF_ACCEPT,str(pkt2),len(pkt2)) print "ret = ",ret return 0 payload.set_verdict(nfqueue.NF_ACCEPT) sys.stdout.flush() return 1
def report_detail(self, ioc, type, result): events = self.cb.process_events(result["id"], result["segment_id"]) proc = events["process"] if type == "domain" and proc.has_key("netconn_complete"): for netconn in proc["netconn_complete"]: ts, ip, port, proto, domain, dir = netconn.split("|") if ioc in domain: str_ip = socket.inet_ntoa(struct.pack("!i", int(ip))) print "%s\t%s (%s:%s)" % (ts, domain, str_ip, port) elif type == "ipaddr" and proc.has_key("netconn_complete"): for netconn in proc["netconn_complete"]: ts, ip, port, proto, domain, direction = netconn.split("|") packed_ip = struct.unpack("!i", socket.inet_aton(ioc))[0] #import code; code.interact(local=locals()) if packed_ip == int(ip): str_ip = socket.inet_ntoa(struct.pack("!i", int(ip))) print "%s\t%s (%s:%s)" % (ts, domain, str_ip, port) elif type == "md5" and proc.has_key("modload_complete"): for modload in proc["modload_complete"]: ts, md5, path = modload.split("|") if ioc in md5: print "%s\t%s %s" % (ts, md5, path) if result["process_md5"] == ioc: print "%s\t%s %s" % (result["start"], result["process_md5"], result["path"])
def show_ft(key = None, row_count = 100, detail=0): c_ft = pycassa.ColumnFamily(pool, 'FlowTable') l_ft = list(c_ft.get_range(row_count = row_count)) sl_ft=sorted(l_ft, key=lambda le: le[1].get('setup_time', 0)) x = PrettyTable(['setup_time', 'flow_id', 'sourcevn', 'sourceip', 'destvn', 'destip', 'dir', 'prot', 'sprt', 'dprt']) for l in sl_ft: setuptime = l[1].get('setup_time', None) if not setuptime: continue if (setuptime > 135300693300): setuptime = setuptime / 1000000 try: message_dt = datetime.datetime.fromtimestamp(setuptime) except: import pdb;pdb.set_trace() message_ts = message_dt.strftime('%Y-%m-%d %H:%M:%S') x.add_row([message_ts, str(l[0]) if detail else get_substring(str(l[0])), l[1]['sourcevn'] if detail else get_substring(l[1]['sourcevn']), socket.inet_ntoa(hex(l[1]['sourceip'] & 0xffffffff)[2:].zfill(8).decode('hex')), l[1]['destvn'] if detail else get_substring(l[1]['destvn']), socket.inet_ntoa(hex(l[1]['destip'] & 0xffffffff)[2:].zfill(8).decode('hex')), 'ing' if l[1]['direction_ing']==1 else 'egr', l[1]['protocol'], l[1]['sport'], l[1]['dport']]) print x print 'max row_count - %d, num elements = %d' %(row_count, len(l_ft))
def from_raw_message(raw_message): message_type = 0 options_raw = '' if len(raw_message) < DHCP_HEADER_LENGTH: return None dhcp_header = __dhcp_struct__.unpack(raw_message[:DHCP_HEADER_LENGTH]) # Bypass Magic Cookie if raw_message[DHCP_HEADER_LENGTH:DHCP_HEADER_LENGTH+4] == MAGIC_COOKIE: options_raw = raw_message[DHCP_HEADER_LENGTH+4:] else: options_raw = raw_message[DHCP_HEADER_LENGTH:] # parse raw options options = _parse_raw_options(options_raw) for option in options: if option[0]==__OPTION_MESSAGE_TYPE__: break if not option: raise Exception("No Message Type Specified in Packet") else: message_type = option[1] return dhcp_packet(message_type=message_type, htype=dhcp_header[1], hlen=dhcp_header[2], hops=dhcp_header[3], xid=dhcp_header[4], secs=dhcp_header[5], broadcast=True if dhcp_header[6]==1<<15 else False, ciaddr=socket.inet_ntoa(dhcp_header[7]), yiaddr=socket.inet_ntoa(dhcp_header[8]), siaddr=socket.inet_ntoa(dhcp_header[9]), giaddr=socket.inet_ntoa(dhcp_header[10]), mac=dhcp_header[11][0:6].encode('hex'), sname=dhcp_header[12], file=dhcp_header[13], options=options)
def _generate_subnet_config(self): dns = self.get_dns_servers() masked_ip = "" for i in range(4): masked_ip += chr(ord(self.netconf.ip4_address[i]) & ord(self.netconf.ip4_mask[i])) start = self.netconf.ip4_address[:3] + chr(ord(self.netconf.ip4_address[3])+1) end = self.netconf.ip4_address[:3] + "\xfe" #.254 subnet = "#### BLUEMAN AUTOMAGIC SUBNET ####\n" subnet += "# Everything inside this section is destroyed after config change\n" subnet += """subnet %(ip_mask)s netmask %(netmask)s { option domain-name-servers %(dns)s; option subnet-mask %(netmask)s; option routers %(rtr)s; range %(start)s %(end)s; }\n""" % {"ip_mask": socket.inet_ntoa(masked_ip), "netmask": socket.inet_ntoa(self.netconf.ip4_mask), "dns": dns, "rtr": socket.inet_ntoa(self.netconf.ip4_address), "start": socket.inet_ntoa(start), "end": socket.inet_ntoa(end) } subnet += "#### END BLUEMAN AUTOMAGIC SUBNET ####\n" return subnet
def recv_sequence_number_packets(destination): #create an INET, raw socket neg_ack=set() s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0800)) first_packet=0 last_packet=time.time() while True: now=time.time() if (now-last_packet>4 and first_packet==1): print "Breaking ",now-last_packet break packet = s.recvfrom(65565) packet = packet[0] ip_header = packet[14:34] iph = unpack('!BBHHHBBH4s4s' , ip_header) version_ihl = iph[0] version = version_ihl >> 4 ihl = version_ihl & 0xF iph_length = ihl * 4 ttl = iph[5] protocol = iph[6] s_addr = socket.inet_ntoa(iph[8]); d_addr = socket.inet_ntoa(iph[9]); seq_number="" if (s_addr==destination): first_packet=1 last_packet=time.time() write_a=packet[42:] if ',' in write_a: write_a=write_a.split(',') for item in write_a: item=int(item.strip('\0')) neg_ack.add(item) s.close() return list(neg_ack)
def migrate_routes(device): ''' Sample output of /proc/net/route : Iface Destination Gateway Flags RefCnt Use Metric \ Mask MTU Window IRTT p4p1 00000000 FED8CC0A 0003 0 0 0 \ 00000000 0 0 0 ''' with open('/etc/sysconfig/network-scripts/route-vhost0', 'w') as route_cfg_file: for route in open('/proc/net/route', 'r').readlines(): if route.startswith(device): route_fields = route.split() destination = int(route_fields[1], 16) gateway = int(route_fields[2], 16) flags = int(route_fields[3], 16) mask = int(route_fields[7], 16) if flags & 0x2: if destination != 0: route_cfg_file.write( socket.inet_ntoa(struct.pack('I', destination))) route_cfg_file.write( '/' + str(bin(mask).count('1')) + ' ') route_cfg_file.write('via ') route_cfg_file.write( socket.inet_ntoa(struct.pack('I', gateway)) + ' ') route_cfg_file.write('dev vhost0')
def unpack(self, packet): _ip = layer() _ip.ihl = (ord(packet[0]) & 0xf) * 4 iph = struct.unpack("!BBHHHBBH4s4s", packet[:_ip.ihl]) _ip.ver = iph[0] >> 4 _ip.tos = iph[1] _ip.length = iph[2] _ip.ids = iph[3] _ip.flags = iph[4] >> 13 _ip.offset = iph[4] & 0x1FFF _ip.ttl = iph[5] _ip.protocol = iph[6] _ip.checksum = hex(iph[7]) _ip.src = socket.inet_ntoa(iph[8]) _ip.dst = socket.inet_ntoa(iph[9]) _ip.list = [ _ip.ihl, _ip.ver, _ip.tos, _ip.length, _ip.ids, _ip.flags, _ip.offset, _ip.ttl, _ip.protocol, _ip.src, _ip.dst] return _ip
def generateRandoms(self, filterCount, traffic, seed): """ should generate random IP's, Port numbers """ dectionary = {"sourcIP": [], "destIP": [], "sourcePortNo": [], "destPortNo": []} sourceIP = "" destIP = "" random.seed(seed) for i in range(0, filterCount): if "IPV4" in traffic[i]: sourceIP = socket.inet_ntoa(struct .pack('>I', random .randint(1, 0xffffffff))) destIP = socket.inet_ntoa(struct .pack('>I', random .randint(1, 0xffffffff))) else: sourceIP = str(IPAddress('0::0:0') + random.getrandbits(16)) destIP = str(IPAddress('0::0:0') + random.getrandbits(16)) sourcePort = random.randint(0, 0xffff) destPort = random.randint(0, 0xffff) dectionary["sourcIP"].append(sourceIP) dectionary["destIP"].append(destIP) dectionary["sourcePortNo"].append(sourcePort) dectionary["destPortNo"].append(destPort) return dectionary
def parsetcp(connections): conn = sqlite3.connect('connections.db') c = conn.cursor() for connection in connections: connection = connection.strip() connection = connection.split() if connection[1] != '00000000:0000' and connection[2] != '00000000:0000': print connection sourceip = connection[1].split(':')[0] sourceport = connection[1].split(':')[1] sourceip = int(sourceip,16) sourceip = struct.pack('<L',sourceip) sourceip = socket.inet_ntoa(sourceip) sourceport = int(sourceport,16) destip = connection[2].split(':')[0] destport = connection[2].split(':')[1] destip = int(destip,16) destip = struct.pack('<L',destip) destip = socket.inet_ntoa(destip) destport = int(destport,16) retrans = connection[6] print sourceip, sourceport, destip, destport, retrans query = 'SELECT * FROM conns WHERE sourceip = \"{sip}\" AND sourceport = \"{spo}\" AND destip = \"{dip}\" AND destport = \"{dpo}\"'.format(retr=int(retrans), sip=str(sourceip), spo=str(sourceport), dip=str(destip), dpo=str(destport)) print query c.execute(query) print(c.fetchall()) query = 'UPDATE conns SET retrans = {retr} WHERE sourceip = \"{sip}\" AND sourceport = \"{spo}\" AND destip = \"{dip}\" AND destport = \"{dpo}\"'.format(retr=int(retrans), sip=str(sourceip), spo=str(sourceport), dip=str(destip), dpo=str(destport)) print query c.execute(query) conn.commit() c.execute('SELECT * FROM conns') print(c.fetchall()) conn.close()
def handle(self): sock = self.connection data = sock.recv(262) sock.send("\x05\x00") data = self.rfile.read(4) or '\x00' * 4 mode = ord(data[1]) if mode != 1: logging.warn('mode != 1') return addrtype = ord(data[3]) if addrtype == 1: remote_addr = socket.inet_ntoa(self.rfile.read(4)) elif addrtype == 3: addr_len = self.rfile.read(1) remote_addr = self.rfile.read(ord(addr_len)) elif addrtype == 4: remote_addr = socket.inet_ntoa(self.rfile.read(16)) else: logging.warn('addr_type not support:%d' % addrtype) return remote_port = struct.unpack('>H', self.rfile.read(2))[0] try: remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) remote.connect((remote_addr, remote_port)) logging.info('connecting %s:%d' % (remote_addr, remote_port)) except socket.error, e: logging.warn(e) return
def _process_arpbuf(self, buf=bytes()): # this is an ARP request or response: arpop = ord(buf[21:22]) # 1) check if it requests for one of our IP if arpop == 1: ipreq = inet_ntoa(buf[38:42]) if ipreq in self.IP_POOL: # reply to it with our MAC ADDR try: self.sk_arp.sendto( '{0}{1}\x08\x06\0\x01\x08\0\x06\x04\0\x02{2}{3}{4}{5}'\ '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'.format( buf[6:12], self.GGSN_MAC_BUF, # Ethernet hdr self.GGSN_MAC_BUF, buf[38:42], # ARP sender buf[6:12], buf[28:32]), # ARP target (self.GGSN_ETH_IF, 0x0806)) except Exception as err: self._log('ERR', 'external network error (sendto) on ARP '\ 'response: {0}'.format(err)) else: self._log('DBG', 'ARP response sent for IP: {0}'.format( ipreq)) # 2) check if it responses something useful for us elif arpop == 2: ipres = inet_ntoa(buf[28:32]) if ipres.split('.')[:3] == self.SUBNET_PREFIX \ and ipres not in self.ARP_RESOLV_TABLE: # WNG: no protection (at all) against ARP cache poisoning self.ARP_RESOLV_TABLE[ipres] = buf[22:28] self._log('DBG', 'got ARP response for new local IP: {0}'\ .format(ipres))
def netmask_recon(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) int_ip = socket.inet_ntoa(fcntl.ioctl(s.fileno(),0x8915, struct.pack('256s', ifname[:15]))[20:24]) netmask = socket.inet_ntoa(fcntl.ioctl(socket.socket(socket.AF_INET, socket.SOCK_DGRAM), 35099, struct.pack('256s', ifname))[20:24]) return netmask
def output(self, output_file='ip.txt'): '''输出所有IP信息到文件 ''' fp = codecs.open(output_file, 'w', 'utf8') idx = self.idx_start while idx <= self.idx_end: ip_int = self.read_ip(idx) ip_start = socket.inet_ntoa(pack('!I', ip_int)) ip_end_offset = self.read_offset(idx + 4) ip_int = self.read_ip(ip_end_offset) ip_end = socket.inet_ntoa(pack('!I', ip_int)) a_raw, b_raw = self.read_record(ip_end_offset+4) a_info = decode_str(a_raw) b_info = decode_str(b_raw) fp.write(u'%15s\t%15s\t%s,%s\n' %( ip_start, ip_end, a_info.decode('utf8'), b_info.decode('utf8'))) # 步进7字节:4字节的起始IP值 + 3字节的结束IP偏移值 idx += 7 fp.close()
def handle_time_exceeded(ip_packet): global MAX_TTL_TO_GFW global MIN_TTL_TO_GFW global RANGE_OF_TTL_TO_GFW time_exceed = ip_packet.icmp.data if not isinstance(time_exceed.data, dpkt.ip.IP): return te_ip_packet = time_exceed.data dst_ip = socket.inet_ntoa(te_ip_packet.dst) if dst_ip in to_gfw_ttls: return if not isinstance(te_ip_packet.data, dpkt.icmp.ICMP): return te_icmp_packet = te_ip_packet.data if not isinstance(te_icmp_packet.data, dpkt.icmp.ICMP.Echo): return te_icmp_echo = te_icmp_packet.data ttl = te_icmp_echo.id router_ip = socket.inet_ntoa(ip_packet.src) is_china_router = fqsocks.china_ip.is_china_ip(router_ip) probe_result = probe_results.get(dst_ip) if not probe_result: return probe_result.routers[ttl] = (router_ip, is_china_router) ttl_to_gfw = probe_result.analyze_ttl_to_gfw() if not ttl_to_gfw: return LOGGER.info('found ttl to gfw: %s %s' % (dst_ip, ttl_to_gfw)) to_gfw_ttls[dst_ip] = ttl_to_gfw probe_results.pop(dst_ip, None) if ttl_to_gfw == MAX_TTL_TO_GFW: MIN_TTL_TO_GFW += 2 MAX_TTL_TO_GFW += 2 LOGGER.info('slide ttl range to [%s ~ %s]' % (MIN_TTL_TO_GFW, MAX_TTL_TO_GFW)) RANGE_OF_TTL_TO_GFW = range(MIN_TTL_TO_GFW, MAX_TTL_TO_GFW + 1)
def get_IP_header(pkt): fmt = "!6H4s4s" (vit, total_len, id, ffo, ttl_proto, checksum, raw_src, raw_dst) = struct.unpack(fmt, pkt[:20]) #vit has version, IHL, and TOS ver = vit >> 12 ihl = (vit >> 8) & 0xf tos = vit & 0xff #ffo has flags and fragment offset flags = ffo >> 13 f_offest = ffo & 0x1fff #ttl_proto has ttl and protocol ttl = ttl_proto >> 8 protocol = ttl_proto & 0xff #format the src and dst with socket src_adr = socket.inet_ntoa(raw_src) dst_adr = socket.inet_ntoa(raw_dst) if protocol == 6: next_proto = "TCP" elif protocol == 17: next_proto = "UDP" else: next_proto = "Other" paPrint.print_ip_head(src_adr, dst_adr, protocol, next_proto) return pkt[20:], next_proto
def IP_preview(packet): ipHeader = packet[0:20] #unpack the data found in the ip datagram, there are 10 items ipDatagram = unpack("!BBHHHBBH4s4s",ipHeader) version_IPHeaderLength = ipDatagram[0] ipVer = version_IPHeaderLength >> 4 #0xF is 15 and the '&' operand copies a bit to the result if it exists #in both operands ipHeaderLength = version_IPHeaderLength & 0xF # iphl = ipHeaderLength * 4 totalLength = ipDatagram[2] #transport protocol protocol = ipDatagram[6] sourceIP = socket.inet_ntoa(ipDatagram[8]) destinationIP = socket.inet_ntoa(ipDatagram[9]) print "\n\nVersion: \t\t" + str(ipVer) print "Length:\t\t\t" + str(totalLength) print "Protocol:\t\t" + getProtocol(protocol) #print "SourceIP:\t\t" + sourceIP #print "DestinationIP:\t\t" + destinationIP #this will be used to find the max and average size of the packets captured return totalLength
def __init__(self, data): self.age = mkNetInt(data[0:2]) self.options = ord(data[2]) self.type = ord(data[3]) self.lsid = netaddr.IPAddress(socket.inet_ntoa(data[4:8])) self.advrouter = netaddr.IPAddress(socket.inet_ntoa(data[8:12])) self.seq = mkNetInt(data[12:16])
def log(q, ip, r, i1, i2, tss, ts, key): if q: cip = q[0] sip = q[1] did = q[2] try: rtype = QTYPE[r.a.rtype] except: rtype = "UNK" syslog.syslog('type=QR, cip=' + cip + ', sip=' + sip + ', did=' + did + ', qtype=' + q[4] + ', q=' + q[3] + ', r=' + str(r.a.rdata) + ', rtype=' + rtype + ', qlen=' + str(len(q[3])) + ', rlen=' + str(len(str(r.a.rdata)))) tss.remove(i2[key]) i1.pop(i2.pop(key)) else: cip = socket.inet_ntoa(ip.dst) sip = socket.inet_ntoa(ip.src) did = str(dns.header.id) try: rtype = QTYPE[dns.a.rtype] except: rtype = "UNK" syslog.syslog('type=R, cip=' + cip + ', sip=' + sip + ', did=' + did + ', q=' + str(dns.a.rname) + ', r=' + str(dns.a.rdata) + 'rtype=' + rtype + ', qlen=' + str(len(str(dns.a.rname))) + ', rlen' + str(len(str(dns.a.rdata)))) for i in r.rr[1:]: #Log any additional responses try: rtype = QTYPE[i.rtype] except: rtype = 'UNK' syslog.syslog('type=AR, cip=' + cip + ', sip=' + sip + ', did=' + did + ', q=' + str(i.rname) + ', r=' + str(i.rdata) + ', rtype=' + rtype + ', qlen=' + str(len(str(i.rname))) + ', rlen=' + str(len(str(i.rdata))))
def get_details(self, packet): ''' Description : Assigns values to the IP header class attributes from the details present in the given packet input_param : packet - packet received in the interface input_type : bytes array ''' iph = unpack('!BBHHHBBH4s4s' , packet) version_ihl = iph[0] version = version_ihl >> 4 ihl = version_ihl & 0xF iph_length = ihl * 4 ttl = iph[5] protocol = iph[6] s_addr = socket.inet_ntoa(iph[8]); d_addr = socket.inet_ntoa(iph[9]); self.version = version self.hdr_length = iph_length self.ttl = ttl self.proto = protocol self.src_addr = s_addr self.dst_addr= d_addr
def migrate_routes(self, device): ''' Sample output of /proc/net/route : Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT p4p1 00000000 FED8CC0A 0003 0 0 0 00000000 0 0 0 ''' temp_dir_name = self._temp_dir_name cfg_file = '/etc/sysconfig/network-scripts/route-vhost0' tmp_file = '%s/route-vhost0'%(temp_dir_name) with open(tmp_file, 'w') as route_cfg_file: for route in open('/proc/net/route', 'r').readlines(): if route.startswith(device): route_fields = route.split() destination = int(route_fields[1], 16) gateway = int(route_fields[2], 16) flags = int(route_fields[3], 16) mask = int(route_fields[7], 16) if flags & 0x2: if destination != 0: route_cfg_file.write(socket.inet_ntoa(struct.pack('I', destination))) route_cfg_file.write('/' + str(bin(mask).count('1')) + ' ') route_cfg_file.write('via ') route_cfg_file.write(socket.inet_ntoa(struct.pack('I', gateway)) + ' ') route_cfg_file.write('dev vhost0') #end if detination... #end if flags &... #end if route.startswith... #end for route... #end with open... local("sudo mv -f %s %s" %(tmp_file, cfg_file)) #delete the route-dev file if os.path.isfile('/etc/sysconfig/network-scripts/route-%s'%device): os.unlink('/etc/sysconfig/network-scripts/route-%s'%device)
def _decodeIPFrame(buf): ip_header = buf[0:20] iph = unpack("!BBHHHBBH4s4s", ip_header) version_ihl = iph[0] version = (version_ihl >> 4) & 0xF ihl = version_ihl & 0xF iph_length = ihl * 4 ttl = iph[5] protocol = iph[6] s_addr = socket.inet_ntoa(iph[8]) d_addr = socket.inet_ntoa(iph[9]) payload = buf[iph_length:] ip_meta = { "version": version, "length": str(ihl), "TTL": ttl, "protocol": protocol, "src": str(s_addr), "dst": str(d_addr), } return ip_meta, payload
def findCommon(pcap): remote_ip_list=[] remote_size_list=[] for (ts,buf) in pcap: try: eth = dpkt.ethernet.Ethernet(buf) ip = eth.data src = socket.inet_ntoa(ip.src) dst = socket.inet_ntoa(ip.dst) if (type(ip.data) != UDP): continue if src != '192.168.100.110': continue if dst == '255.255.255.255': continue if dst in remote_ip_list: continue remote_ip_list.append(dst) content_bytes = ip.data.data print type(content_bytes) udpResultData = ZeroDecrypt(content_bytes[0:44]) print udpResultData.encode('hex')[0:87] #print udpResultData #print content_bytes.encode('hex')[0:21] #print 'Src ' + src + ' --> Dst '+dst #print len(content_bytes) remote_size_list.append(len(content_bytes)) except: raise
def toPrettyString(self): hostname = socket.gethostbyaddr(socket.inet_ntoa(struct.pack('<L', int(self.networkId))))[0] return self.userName + "@" + hostname + ":" + self.progName + ":" + str(self.pid) + ":" + str(self.threadId)
msg[0]) + " Message " + msg[1] sys.exit() print "[*] Waiting for data on port " + str(clientsDestPort) # receive a packet while True: packet = s.recvfrom(65565) packet = packet[0] #parse the packet.. ip_header = packet[0:20] iph = unpack('!BBHHHBBH4s4s', ip_header) version_ihl = iph[0] version = version_ihl >> 4 ihl = version_ihl & 0xF iph_length = ihl * 4 s_addr = socket.inet_ntoa(iph[8]) tcp_header = packet[iph_length:iph_length + 20] tcph = unpack('!HHLLBBHHH', tcp_header) dest_port = tcph[1] doff_reserved = tcph[4] tcph_length = doff_reserved >> 4 h_size = iph_length + tcph_length * 4 data_size = len(packet) - h_size #we got something.. if dest_port == clientsDestPort and data_size > 0: print "[*] Received packet from " + str( s_addr) + " on port : " + str(dest_port) print "[*] Looking for data.." data = packet[h_size:] print "[*] Captured : \n\n" + data print "[*] Appending into " + capturedFile
daddr) = struct.unpack(">ssHHHssHLL", ipdata) iphdrlen = ord(vl) & 0x0F iphdrlen *= 4 # read TCP standard header tcpdata = file.read(stdtcp) (sport, dport, seq, ack_seq, pad1, win, check, urgp) = struct.unpack(">HHLLHHHH", tcpdata) tcphdrlen = pad1 & 0xF000 tcphdrlen = tcphdrlen >> 12 tcphdrlen = tcphdrlen * 4 # skip data skip = file.read(iplensave - linklen - iphdrlen - stdtcp) print socket.inet_ntoa(struct.pack('i', socket.htonl(saddr))) src_tag = socket.inet_ntoa(struct.pack('i', socket.htonl(saddr))) dst_tag = socket.inet_ntoa(struct.pack('i', socket.htonl(daddr))) sp_tag = str(sport) dp_tag = str(dport) # 此即将四元组按照固定顺序排位,两个方向变成一个方向,保证四元组的唯一性 if saddr > daddr: temp = dst_tag dst_tag = src_tag src_tag = temp if sport > dport: temp = sp_tag sp_tag = dp_tag dp_tag = temp
def deserialize(self, f): self.nServices = struct.unpack("<Q", f.read(8))[0] self.pchReserved = f.read(12) self.ip = socket.inet_ntoa(f.read(4)) self.port = struct.unpack(">H", f.read(2))[0]
def long_to_ip(decimal) -> str: ''' decimal to ip ''' return inet_ntoa(pack("!L", decimal))
##<<====--- ETHERNET HEADER ====--->> ethernetHeader = pkt[0][0:14] #https://docs.python.org/2/library/struct.html # check above link for exclamation and s eth_hdr = struct.unpack("!6s6s2s", ethernetHeader) print eth_hdr #hexlify will print all the above in hex print binascii.hexlify(eth_hdr[0]) print binascii.hexlify(eth_hdr[1]) print binascii.hexlify(eth_hdr[2]) ##<<====--- IP HEADER ---====>> ipHeader = pkt[0][14:34] ip_hdr = struct.unpack("!12s4s4s", ipHeader) #ntoa is network to ascii print "Source IP address: " + socket.inet_ntoa(ip_hdr[1]) print "Destination IP address: " + socket.inet_ntoa(ip_hdr[2]) ##<<====--- TCP HEADER ---====>> tcpHeader = pkt[0][34:54] #www.binarytides.com/python-packet-sniffer-code-linux/ #www.stackoverflow/questions/20768107/regarding-struct-unpack-in-python tcp_hdr = struct.unpack("!HH16s", tcpHeader) sourcePort = tcp_hdr[0] destinationPort = tcp_hdr[1] print "Source Port: " + str(sourcePort) print "Destination Port: " + str(destinationPort)
def get_ip_address(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa( fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])
def handle_packet(self, pkt_dir, pkt): # TODO: Your main firewall code will be here. iph_len = (struct.unpack('!B', pkt[0:1])[0] & 0xf) * 4 # Set the offset to the size of the IPV4 header if iph_len >= 20: protocol = struct.unpack( '!B', pkt[9:10])[0] # Get the transport protocol type ext_ip = socket.inet_ntoa( pkt[12:16] ) if pkt_dir == PKT_DIR_INCOMING else socket.inet_ntoa(pkt[16:20]) # Handle ICMP packets if protocol == self.protocols['icmp']: icmp_type = struct.unpack('!B', pkt[iph_len:iph_len + 1])[0] self.handle_general(ext_ip, 'icmp', icmp_type, pkt, pkt_dir) #Handle UDP and TCP packets elif protocol == self.protocols[ 'tcp'] or protocol == self.protocols['udp']: if pkt_dir == PKT_DIR_INCOMING: port = struct.unpack('!H', pkt[iph_len:iph_len + 2])[0] elif pkt_dir == PKT_DIR_OUTGOING: port = struct.unpack('!H', pkt[iph_len + 2:iph_len + 4])[0] # Handle UDP packets if protocol == self.protocols['udp']: dns = None qtype = None if port == 53 and pkt_dir == PKT_DIR_OUTGOING: #deals with udp curr_pos = iph_len + 8 #why is this curr_pos+4 and curr_pos+6? #shouldn't it be curr_pos+12 and curr_pos+14? qdcount = struct.unpack('!H', pkt[curr_pos + 4:curr_pos + 6])[0] # Parse the QNAME # Only consider packets w/ single question entry if qdcount == 1: qname = "" curr_pos += 12 # Size of the DNS header qname_len = struct.unpack( '!B', pkt[curr_pos:curr_pos + 1])[0] curr_pos += 1 #not quite sure what this does while qname_len != 0: qname += struct.unpack( '!%ds' % qname_len, pkt[curr_pos:curr_pos + qname_len])[0] + "." curr_pos += qname_len qname_len = struct.unpack( '!B', pkt[curr_pos:curr_pos + 1])[0] curr_pos += 1 # Cutoff the last '.' if length of QNAME > 0 if len(qname) > 0: qname = qname[:len(qname) - 1] # Parse the QTYPE qtype = struct.unpack('!H', pkt[curr_pos:curr_pos + 2])[0] curr_pos += 2 # Parse the QCLASS qclass = struct.unpack( '!H', pkt[curr_pos:curr_pos + 2])[0] # Set dns only if all conditions are met if (qtype == 1 or qtype == 28) and qclass == 1: dns = qname.lower() # Should just pass dns packets where QCount != 1 self.handle_general(ext_ip, 'udp', port, pkt, pkt_dir, dns, qtype) # Handle TCP packets else: iph_len = (struct.unpack('!B', pkt[0:1])[0] & 0xf) * 4 self.src_addr = struct.unpack('!L', pkt[12:16])[0] self.dst_addr = struct.unpack('!L', pkt[16:20])[0] self.src_port = struct.unpack('!H', pkt[iph_len:iph_len + 2])[0] self.dst_port = struct.unpack('!H', pkt[iph_len + 2:iph_len + 4])[0] hostname = self.gethostname(ext_ip) self.handle_general(ext_ip, 'tcp', port, pkt, pkt_dir, hostname) #Blindly pass all non-IPv4 packets else: self.send(pkt_dir, pkt)
def run(self): """Process PCAP. @return: dict with network analysis data. """ log = logging.getLogger("Processing.Pcap") if not IS_DPKT: log.error("Python DPKT is not installed, aborting PCAP analysis.") return self.results if not os.path.exists(self.filepath): log.warning("The PCAP file does not exist at path \"%s\".", self.filepath) return self.results if os.path.getsize(self.filepath) == 0: log.error("The PCAP file at path \"%s\" is empty." % self.filepath) return self.results try: file = open(self.filepath, "rb") except (IOError, OSError): log.error("Unable to open %s" % self.filepath) return self.results try: pcap = dpkt.pcap.Reader(file) except dpkt.dpkt.NeedData: log.error("Unable to read PCAP file at path \"%s\".", self.filepath) return self.results except ValueError: log.error("Unable to read PCAP file at path \"%s\". File is " "corrupted or wrong format." % self.filepath) return self.results offset = file.tell() first_ts = None for ts, buf in pcap: if not first_ts: first_ts = ts try: ip = iplayer_from_raw(buf, pcap.datalink()) connection = {} if isinstance(ip, dpkt.ip.IP): connection["src"] = socket.inet_ntoa(ip.src) connection["dst"] = socket.inet_ntoa(ip.dst) elif isinstance(ip, dpkt.ip6.IP6): connection["src"] = socket.inet_ntop( socket.AF_INET6, ip.src) connection["dst"] = socket.inet_ntop( socket.AF_INET6, ip.dst) else: offset = file.tell() continue self._add_hosts(connection) if ip.p == dpkt.ip.IP_PROTO_TCP: tcp = ip.data if not isinstance(tcp, dpkt.tcp.TCP): tcp = dpkt.tcp.TCP(tcp) connection["sport"] = tcp.sport connection["dport"] = tcp.dport if len(tcp.data) > 0: self._tcp_dissect(connection, tcp.data) src, sport, dst, dport = (connection["src"], connection["sport"], connection["dst"], connection["dport"]) if not ( (dst, dport, src, sport) in self.tcp_connections_seen or (src, sport, dst, dport) in self.tcp_connections_seen): self.tcp_connections.append( (src, sport, dst, dport, offset, ts - first_ts)) self.tcp_connections_seen.add((src, sport, dst, dport)) elif ip.p == dpkt.ip.IP_PROTO_UDP: udp = ip.data if not isinstance(udp, dpkt.udp.UDP): udp = dpkt.udp.UDP(udp) connection["sport"] = udp.sport connection["dport"] = udp.dport if len(udp.data) > 0: self._udp_dissect(connection, udp.data) src, sport, dst, dport = (connection["src"], connection["sport"], connection["dst"], connection["dport"]) if not ( (dst, dport, src, sport) in self.udp_connections_seen or (src, sport, dst, dport) in self.udp_connections_seen): self.udp_connections.append( (src, sport, dst, dport, offset, ts - first_ts)) self.udp_connections_seen.add((src, sport, dst, dport)) elif ip.p == dpkt.ip.IP_PROTO_ICMP: icmp = ip.data if not isinstance(icmp, dpkt.icmp.ICMP): icmp = dpkt.icmp.ICMP(icmp) self._icmp_dissect(connection, icmp) offset = file.tell() except AttributeError: continue except dpkt.dpkt.NeedData: continue except Exception as e: log.exception("Failed to process packet: %s", e) file.close() # Post processors for reconstructed flows. self._process_smtp() # Remove hosts that have an IP which correlate to a whitelisted domain if enabled_whitelist: for delip in self.ip_whitelist: if delip in self.unique_hosts: self.unique_hosts.remove(delip) # Build results dict. self.results["hosts"] = self._enrich_hosts(self.unique_hosts) self.results["domains"] = self.unique_domains self.results["tcp"] = [ conn_from_flowtuple(i) for i in self.tcp_connections ] self.results["udp"] = [ conn_from_flowtuple(i) for i in self.udp_connections ] self.results["icmp"] = self.icmp_requests self.results["http"] = self.http_requests.values() self.results["dns"] = self.dns_requests.values() self.results["smtp"] = self.smtp_requests self.results["irc"] = self.irc_requests self.results["ja3"] = self.ja3_records if enabled_whitelist: for host in self.results["hosts"]: for delip in self.ip_whitelist: if delip == host["ip"]: self.results["hosts"].remove(host) for host in self.results["tcp"]: for delip in self.ip_whitelist: if delip == host["src"] or delip == host["dst"]: self.results["tcp"].remove(host) for host in self.results["udp"]: for delip in self.ip_whitelist: if delip == host["src"] or delip == host["dst"]: self.results["udp"].remove(host) for host in self.results["icmp"]: for delip in self.ip_whitelist: if delip == host["src"] or delip == host["dst"]: self.results["icmp"].remove(host) return self.results
def get_local_addresses(): """ @return: known local addresses. Not affected by ROS_IP/ROS_HOSTNAME @rtype: [str] """ # cache address data as it can be slow to calculate global _local_addrs if _local_addrs is not None: return _local_addrs local_addrs = None if _use_netifaces: # #552: netifaces is a more robust package for looking up # #addresses on multiple platforms (OS X, Unix, Windows) local_addrs = [] # see http://alastairs-place.net/netifaces/ for i in netifaces.interfaces(): try: local_addrs.extend([ d['addr'] for d in netifaces.ifaddresses(i)[netifaces.AF_INET] ]) except KeyError: pass elif _is_unix_like_platform(): # unix-only branch # adapted from code from Rosen Diankov ([email protected]) # and from ActiveState recipe import fcntl import array ifsize = 32 if platform.system() == 'Linux' and platform.architecture( )[0] == '64bit': ifsize = 40 # untested # 32 interfaces allowed, far more than ROS can sanely deal with max_bytes = 32 * ifsize # according to http://docs.python.org/library/fcntl.html, the buffer limit is 1024 bytes buff = array.array('B', '\0' * max_bytes) # serialize the buffer length and address to ioctl sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) info = fcntl.ioctl(sock.fileno(), SIOCGIFCONF, struct.pack('iL', max_bytes, buff.buffer_info()[0])) retbytes = struct.unpack('iL', info)[0] buffstr = buff.tostring() if platform.system() == 'Linux': local_addrs = [ socket.inet_ntoa(buffstr[i + 20:i + 24]) for i in range(0, retbytes, ifsize) ] else: # in FreeBSD, ifsize is variable: 16 + (16 or 28 or 56) bytes # When ifsize is 32 bytes, it contains the interface name and address, # else it contains the interface name and other information # This means the buffer must be traversed in its entirety local_addrs = [] bufpos = 0 while bufpos < retbytes: bufpos += 16 ifreqsize = ord(buffstr[bufpos]) if ifreqsize == 16: local_addrs += [ socket.inet_ntoa(buffstr[bufpos + 4:bufpos + 8]) ] bufpos += ifreqsize else: # cross-platform branch, can only resolve one address local_addrs = [socket.gethostbyname(socket.gethostname())] _local_addrs = local_addrs return local_addrs
def get_myip(interface): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa( fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', interface[:15]))[20:24])
def num2ip(num): """Convert long integer to IP string""" return socket.inet_ntoa(struct.pack("!L", num))
def my_ntoa(n): s = struct.pack("!I", n) ip = inet_ntoa(s) return ip
def _add_dns(self, udpdata): """Adds a DNS data flow. @param udpdata: UDP data flow. """ dns = dpkt.dns.DNS(udpdata) # DNS query parsing. query = {} if dns.rcode == dpkt.dns.DNS_RCODE_NOERR or \ dns.qr == dpkt.dns.DNS_R or \ dns.opcode == dpkt.dns.DNS_QUERY or True: # DNS question. try: q_name = dns.qd[0].name q_type = dns.qd[0].type except IndexError: return False query["request"] = q_name if q_type == dpkt.dns.DNS_A: query["type"] = "A" if q_type == dpkt.dns.DNS_AAAA: query["type"] = "AAAA" elif q_type == dpkt.dns.DNS_CNAME: query["type"] = "CNAME" elif q_type == dpkt.dns.DNS_MX: query["type"] = "MX" elif q_type == dpkt.dns.DNS_PTR: query["type"] = "PTR" elif q_type == dpkt.dns.DNS_NS: query["type"] = "NS" elif q_type == dpkt.dns.DNS_SOA: query["type"] = "SOA" elif q_type == dpkt.dns.DNS_HINFO: query["type"] = "HINFO" elif q_type == dpkt.dns.DNS_TXT: query["type"] = "TXT" elif q_type == dpkt.dns.DNS_SRV: query["type"] = "SRV" # DNS answer. query["answers"] = [] for answer in dns.an: ans = {} if answer.type == dpkt.dns.DNS_A: ans["type"] = "A" try: ans["data"] = socket.inet_ntoa(answer.rdata) except socket.error: continue elif answer.type == dpkt.dns.DNS_AAAA: ans["type"] = "AAAA" try: ans["data"] = socket.inet_ntop(socket.AF_INET6, answer.rdata) except (socket.error, ValueError): continue elif answer.type == dpkt.dns.DNS_CNAME: ans["type"] = "CNAME" ans["data"] = answer.cname elif answer.type == dpkt.dns.DNS_MX: ans["type"] = "MX" ans["data"] = answer.mxname elif answer.type == dpkt.dns.DNS_PTR: ans["type"] = "PTR" ans["data"] = answer.ptrname elif answer.type == dpkt.dns.DNS_NS: ans["type"] = "NS" ans["data"] = answer.nsname elif answer.type == dpkt.dns.DNS_SOA: ans["type"] = "SOA" ans["data"] = ",".join([ answer.mname, answer.rname, str(answer.serial), str(answer.refresh), str(answer.retry), str(answer.expire), str(answer.minimum) ]) elif answer.type == dpkt.dns.DNS_HINFO: ans["type"] = "HINFO" ans["data"] = " ".join(answer.text) elif answer.type == dpkt.dns.DNS_TXT: ans["type"] = "TXT" ans["data"] = " ".join(answer.text) # TODO: add srv handling query["answers"].append(ans) if dns.rcode == dpkt.dns.DNS_RCODE_NXDOMAIN: ans = {} ans["type"] = "NXDOMAIN" ans["data"] = "" query["answers"].append(ans) if enabled_whitelist: for reject in self.domain_whitelist: if reject.startswith("#") or len(reject.strip()) == 0: continue # comment or empty line if re.search(reject, query["request"]): if query["answers"]: for addip in query["answers"]: if addip["type"] == "A" or addip[ "type"] == "AAAA": self.ip_whitelist.add(addip["data"]) return True self._add_domain(query["request"]) reqtuple = query["type"], query["request"] if reqtuple not in self.dns_requests: self.dns_requests[reqtuple] = query new_answers = set((i["type"], i["data"]) for i in query["answers"]) - self.dns_answers self.dns_answers.update(new_answers) self.dns_requests[reqtuple]["answers"] += [ dict(type=i[0], data=i[1]) for i in new_answers ] return True
def extract_config(filebuf): conf_dict = {} pe = None try: pe = pefile.PE(data=filebuf, fast_load=False) except Exception: pass if pe is None: return image_base = pe.OPTIONAL_HEADER.ImageBase c2found = False c2list_va_offset = 0 c2_list_offset = 0 delta = 0 yara_matches = yara_scan(filebuf) if yara_matches.get("$snippet3"): c2list_va_offset = int(yara_matches["$snippet3"]) c2_list_va = struct.unpack( "I", filebuf[c2list_va_offset + 2:c2list_va_offset + 6])[0] c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x20000 else c2_list_va - image_base try: c2_list_offset = pe.get_offset_from_rva(c2_list_rva) except pefile.PEFormatError: pass while True: try: ip = struct.unpack( "<I", filebuf[c2_list_offset:c2_list_offset + 4])[0] except Exception: return if ip == 0: return c2_address = socket.inet_ntoa(struct.pack("!L", ip)) port = str( struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset + 6])[0]) if not c2_address or not port: return conf_dict.setdefault("address", []).append(f"{c2_address}:{port}") c2_list_offset += 8 elif yara_matches.get("$snippet4"): c2list_va_offset = int(yara_matches["$snippet4"]) c2_list_va = struct.unpack( "I", filebuf[c2list_va_offset + 8:c2list_va_offset + 12])[0] c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x20000 else c2_list_va - image_base try: c2_list_offset = pe.get_offset_from_rva(c2_list_rva) except pefile.PEFormatError: pass while True: try: ip = struct.unpack( "<I", filebuf[c2_list_offset:c2_list_offset + 4])[0] except Exception: return if ip == 0: return c2_address = socket.inet_ntoa(struct.pack("!L", ip)) port = str( struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset + 6])[0]) if not c2_address or not port: return conf_dict.setdefault("address", []).append(f"{c2_address}:{port}") c2_list_offset += 8 elif any( yara_matches.get(name, False) for name in ("$snippet5", "$snippet8", "$snippet9", "$snippetB", "$snippetC", "$comboA1", "$comboA2")): delta = 5 if yara_matches.get("$snippet5"): refc2list = yara_matches.get("$snippet5") elif yara_matches.get("$snippet8"): refc2list = yara_matches.get("$snippet8") elif yara_matches.get("$snippet9"): refc2list = yara_matches.get("$snippet8") c2list_va_offset = int(yara_matches["$snippet9"]) tb = struct.unpack( "b", filebuf[c2list_va_offset + 5:c2list_va_offset + 6])[0] if tb == 0x48: delta += 1 elif yara_matches.get("$snippetB"): delta = 9 refc2list = yara_matches.get("$snippetB") elif yara_matches.get("$snippetC"): delta = 8 refc2list = yara_matches.get("$snippetC") elif yara_matches.get("$comboA1"): refc2list = yara_matches.get("$comboA1") elif yara_matches.get("$comboA2"): delta = 6 refc2list = yara_matches.get("$comboA2") if refc2list: c2list_va_offset = int(refc2list) c2_list_va = struct.unpack( "I", filebuf[c2list_va_offset + delta:c2list_va_offset + delta + 4])[0] c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x40000 else c2_list_va - image_base try: c2_list_offset = pe.get_offset_from_rva(c2_list_rva) except pefile.PEFormatError as err: log.error(err) return while True: preip = filebuf[c2_list_offset:c2_list_offset + 4] if not preip: return try: ip = struct.unpack("<I", preip)[0] except Exception as e: log.error(e) break if ip == 0: break c2_address = socket.inet_ntoa(struct.pack("!L", ip)) port = str( struct.unpack( "H", filebuf[c2_list_offset + 4:c2_list_offset + 6])[0]) if not c2_address or not port: break conf_dict.setdefault("address", []).append(f"{c2_address}:{port}") c2found = True c2_list_offset += 8 elif yara_matches.get("$snippet6"): c2list_va_offset = int(yara_matches["$snippet6"]) c2_list_va = struct.unpack( "I", filebuf[c2list_va_offset + 15:c2list_va_offset + 19])[0] c2_list_rva = c2_list_va - image_base try: c2_list_offset = pe.get_offset_from_rva(c2_list_rva) except pefile.PEFormatError: pass while True: preip = filebuf[c2_list_offset:c2_list_offset + 4] if not preip: break try: ip = struct.unpack("<I", preip)[0] except Exception as e: log.error(e) break if ip == 0: break c2_address = socket.inet_ntoa(struct.pack("!L", ip)) port = str( struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset + 6])[0]) if not c2_address or not port: break conf_dict.setdefault("address", []).append(f"{c2_address}:{port}") c2found = True c2_list_offset += 8 elif yara_matches.get("$snippet7"): c2list_va_offset = int(yara_matches["$snippet7"]) delta = 26 hb = struct.unpack( "b", filebuf[c2list_va_offset + 29:c2list_va_offset + 30])[0] if hb: delta += 1 c2_list_va = struct.unpack( "I", filebuf[c2list_va_offset + delta:c2list_va_offset + delta + 4])[0] c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x20000 else c2_list_va - image_base try: c2_list_offset = pe.get_offset_from_rva(c2_list_rva) except pefile.PEFormatError: pass while True: try: ip = struct.unpack( "<I", filebuf[c2_list_offset:c2_list_offset + 4])[0] except Exception: break if ip == 0: break c2_address = socket.inet_ntoa(struct.pack("!L", ip)) port = str( struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset + 6])[0]) if not c2_address or not port: break conf_dict.setdefault("address", []).append(f"{c2_address}:{port}") c2found = True c2_list_offset += 8 elif yara_matches.get("$snippetA"): c2list_va_offset = int(yara_matches["$snippetA"]) c2_list_va = struct.unpack( "I", filebuf[c2list_va_offset + 24:c2list_va_offset + 28])[0] c2_list_rva = c2_list_va & 0xFFFF if c2_list_va - image_base > 0x20000 else c2_list_va - image_base try: c2_list_offset = pe.get_offset_from_rva(c2_list_rva) except pefile.PEFormatError: pass while True: try: ip = struct.unpack( "<I", filebuf[c2_list_offset:c2_list_offset + 4])[0] except Exception: break if ip == 0: break c2_address = socket.inet_ntoa(struct.pack("!L", ip)) port = str( struct.unpack("H", filebuf[c2_list_offset + 4:c2_list_offset + 6])[0]) if not c2_address or not port: break conf_dict.setdefault("address", []).append(f"{c2_address}:{port}") c2found = True c2_list_offset += 8 elif yara_matches.get("$snippetD"): delta = 6 c2list_va_offset = int(yara_matches["$snippetD"]) elif yara_matches.get("$snippetE"): delta = 13 c2list_va_offset = int(yara_matches["$snippetE"]) elif yara_matches.get("$snippetF"): delta = 9 c2list_va_offset = int(yara_matches["$snippetF"]) elif yara_matches.get("$snippetG"): delta = -4 c2list_va_offset = int(yara_matches["$snippetG"]) elif yara_matches.get("$snippetH"): delta = 12 c2list_va_offset = int(yara_matches["$snippetH"]) elif yara_matches.get("$snippetI"): delta = -4 c2list_va_offset = int(yara_matches["$snippetI"]) elif yara_matches.get("$snippetJ"): delta = 14 c2list_va_offset = int(yara_matches["$snippetJ"]) elif yara_matches.get("$snippetK"): delta = -5 c2list_va_offset = int(yara_matches["$snippetK"]) elif yara_matches.get("$snippetL"): delta = -4 c2list_va_offset = int(yara_matches["$snippetL"]) elif yara_matches.get("$snippetM"): delta = 12 c2list_va_offset = int(yara_matches["$snippetM"]) elif yara_matches.get("$snippetN"): delta = 9 c2list_va_offset = int(yara_matches["$snippetN"]) elif yara_matches.get("$snippetO"): delta = 5 c2list_va_offset = int(yara_matches["$snippetO"]) elif yara_matches.get("$snippetP"): delta = 17 c2list_va_offset = int(yara_matches["$snippetP"]) elif yara_matches.get("$snippetQ"): delta = 5 c2list_va_offset = int(yara_matches["$snippetQ"]) elif yara_matches.get("$snippetR"): delta = 18 c2list_va_offset = int(yara_matches["$snippetR"]) elif yara_matches.get("$snippetS"): delta = -4 c2list_va_offset = int(yara_matches["$snippetS"]) elif yara_matches.get("$snippetT"): delta = 13 c2list_va_offset = int(yara_matches["$snippetT"]) elif yara_matches.get("$snippetU"): delta = 13 c2list_va_offset = int(yara_matches["$snippetU"]) elif yara_matches.get("$snippetV"): delta = 14 c2list_va_offset = int(yara_matches["$snippetV"]) elif yara_matches.get("$snippetW"): delta = 10 c2_delta_offset = int(yara_matches["$snippetW"]) elif yara_matches.get("$snippetX"): delta = 3 c2_delta_offset = int(yara_matches["$snippetX"]) if delta: if c2list_va_offset: c2_list_va = struct.unpack( "I", filebuf[c2list_va_offset + delta:c2list_va_offset + delta + 4])[0] c2_list_rva = c2_list_va - image_base try: c2_list_offset = pe.get_offset_from_rva(c2_list_rva) except pefile.PEFormatError as err: log.error(err) return elif c2_delta_offset: c2_delta = struct.unpack( "i", filebuf[c2_delta_offset + delta:c2_delta_offset + delta + 4])[0] c2_list_rva = pe.get_rva_from_offset( c2_delta_offset) + c2_delta + delta + 4 c2_list_offset = pe.get_offset_from_rva(c2_list_rva) key = filebuf[c2_list_offset:c2_list_offset + 4] presize = filebuf[c2_list_offset + 4:c2_list_offset + 8] if not presize: return size = struct.unpack("I", presize)[0] ^ struct.unpack("I", key)[0] if size > 1000: log.info("Anomalous C2 list size 0x%x", size) return c2_list_offset += 8 c2_list = xor_data(filebuf[c2_list_offset:], key) offset = 0 while offset < size: try: ip = struct.unpack(">I", c2_list[offset:offset + 4])[0] except Exception: break if ip == struct.unpack(">I", key)[0]: break c2_address = socket.inet_ntoa(struct.pack("!L", ip)) port = str(struct.unpack(">H", c2_list[offset + 4:offset + 6])[0]) if not c2_address or not port: break conf_dict.setdefault("address", []).append(f"{c2_address}:{port}") c2found = True offset += 8 if not c2found: return pem_key = False try: pem_key = extract_emotet_rsakey(pe) except ValueError as e: log.error(e) if pem_key: # self.reporter.add_metadata("other", {"RSA public key": pem_key.exportKey().decode()}) conf_dict.setdefault("RSA public key", pem_key.exportKey().decode()) else: if yara_matches.get("$ref_rsa"): ref_rsa_offset = int(yara_matches["$ref_rsa"]) ref_rsa_va = 0 zb = struct.unpack( "b", filebuf[ref_rsa_offset + 31:ref_rsa_offset + 32])[0] if not zb: ref_rsa_va = struct.unpack( "I", filebuf[ref_rsa_offset + 28:ref_rsa_offset + 32])[0] else: zb = struct.unpack( "b", filebuf[ref_rsa_offset + 29:ref_rsa_offset + 30])[0] if not zb: ref_rsa_va = struct.unpack( "I", filebuf[ref_rsa_offset + 26:ref_rsa_offset + 30])[0] else: zb = struct.unpack( "b", filebuf[ref_rsa_offset + 28:ref_rsa_offset + 29])[0] if not zb: ref_rsa_va = struct.unpack( "I", filebuf[ref_rsa_offset + 25:ref_rsa_offset + 29])[0] else: zb = struct.unpack( "b", filebuf[ref_rsa_offset + 38:ref_rsa_offset + 39])[0] if not zb: ref_rsa_va = struct.unpack( "I", filebuf[ref_rsa_offset + 35:ref_rsa_offset + 39])[0] if not ref_rsa_va: return ref_rsa_rva = ref_rsa_va - image_base try: ref_rsa_offset = pe.get_offset_from_rva(ref_rsa_rva) except Exception: return key = struct.unpack("<I", filebuf[ref_rsa_offset:ref_rsa_offset + 4])[0] xorsize = key ^ struct.unpack( "<I", filebuf[ref_rsa_offset + 4:ref_rsa_offset + 8])[0] rsa_key = xor_data( filebuf[ref_rsa_offset + 8:ref_rsa_offset + 8 + xorsize], struct.pack("<I", key)) seq = asn1.DerSequence() seq.decode(rsa_key) # self.reporter.add_metadata("other", {"RSA public key": RSA.construct((seq[0], seq[1])).exportKey()}) conf_dict.setdefault("RSA public key", RSA.construct((seq[0], seq[1])).exportKey()) else: ref_ecc_offset = 0 delta1 = 0 delta2 = 0 if yara_matches.get("$ref_ecc1"): ref_ecc_offset = int(yara_matches["$ref_ecc1"]) delta1 = 9 delta2 = 62 elif yara_matches.get("$ref_ecc2"): ref_ecc_offset = int(yara_matches["$ref_ecc2"]) delta1 = 22 delta2 = 71 elif yara_matches.get("$ref_ecc3"): ref_ecc_offset = int(yara_matches["$ref_ecc3"]) delta1 = 8 delta2 = 47 elif yara_matches.get("$ref_ecc4"): ref_ecc_offset = int(yara_matches["$ref_ecc4"]) delta1 = -4 delta2 = 49 elif yara_matches.get("$ref_ecc5"): ref_ecc_offset = int(yara_matches["$ref_ecc5"]) delta1 = 15 delta2 = 65 elif yara_matches.get("$ref_ecc6"): ref_ecc_offset = int(yara_matches["$ref_ecc6"]) delta1 = -4 delta2 = 48 elif yara_matches.get("$ref_ecc7"): ref_ecc_offset = int(yara_matches["$ref_ecc7"]) delta1 = 23 delta2 = 47 elif yara_matches.get("$ref_ecc8"): ref_ecc_offset = int(yara_matches["$ref_ecc8"]) delta1 = -5 delta2 = 44 elif yara_matches.get("$ref_ecc9"): ref_ecc_offset = int(yara_matches["$ref_ecc9"]) delta1 = -4 delta2 = 24 elif yara_matches.get("$ref_eccA"): ref_ecc_offset = int(yara_matches["$ref_eccA"]) delta1 = 12 delta2 = 55 elif yara_matches.get("$ref_eccB"): ref_ecc_offset = int(yara_matches["$ref_eccB"]) delta1 = 15 delta2 = 58 elif yara_matches.get("$ref_eccC"): ref_ecc_offset = int(yara_matches["$ref_eccC"]) delta1 = 8 delta2 = 37 elif yara_matches.get("$ref_eccD"): ref_ecc_offset = int(yara_matches["$ref_eccD"]) delta1 = 26 delta2 = 72 elif yara_matches.get("$ref_eccE"): ref_ecc_offset = int(yara_matches["$ref_eccE"]) delta1 = 8 delta2 = 36 elif yara_matches.get("$ref_eccF"): ref_ecc_offset = int(yara_matches["$ref_eccF"]) delta1 = -4 delta2 = 48 elif yara_matches.get("$ref_eccG"): ref_ecc_offset = int(yara_matches["$ref_eccG"]) delta1 = 30 delta2 = 76 if yara_matches.get("$ref_eccH"): ref_ecc_offset = int(yara_matches["$ref_eccH"]) delta1 = 9 delta2 = 59 if yara_matches.get("$ref_eccI"): ref_ecc_offset = int(yara_matches["$ref_eccI"]) delta1 = 22 delta2 = 58 if yara_matches.get("$ref_eccJ"): ref_ecc_offset = int(yara_matches["$ref_eccJ"]) delta1 = 10 delta2 = 245 if yara_matches.get("$ref_eccK"): ref_ecc_offset = int(yara_matches["$ref_eccK"]) delta1 = 14 delta2 = 166 if yara_matches.get("$ref_eccK"): ref_ecc_offset = int(yara_matches["$ref_eccK"]) delta1 = 14 delta2 = 166 if yara_matches.get("$ref_eccL"): ecc_delta_offset = int(yara_matches["$ref_eccL"]) delta1 = 8 delta2 = 97 if yara_matches.get("$ref_eccM"): ecc_delta_offset = int(yara_matches["$ref_eccM"]) delta1 = 3 delta2 = 234 if yara_matches.get("$ref_eccN"): ecc_delta_offset = int(yara_matches["$ref_eccN"]) delta1 = 3 delta2 = 107 if yara_matches.get("$ref_eccO"): ecc_delta_offset = int(yara_matches["$ref_eccO"]) delta1 = 3 delta2 = 206 if delta1 or delta2: if ref_ecc_offset: ref_eck_rva = struct.unpack( "I", filebuf[ref_ecc_offset + delta1:ref_ecc_offset + delta1 + 4])[0] - image_base ref_ecs_rva = struct.unpack( "I", filebuf[ref_ecc_offset + delta2:ref_ecc_offset + delta2 + 4])[0] - image_base try: eck_offset = pe.get_offset_from_rva(ref_eck_rva) ecs_offset = pe.get_offset_from_rva(ref_ecs_rva) except Exception as e: log.error(e) return elif ecc_delta_offset: eck_delta = struct.unpack( "i", filebuf[ecc_delta_offset + delta1:ecc_delta_offset + delta1 + 4])[0] ecs_delta = struct.unpack( "i", filebuf[ecc_delta_offset + delta2:ecc_delta_offset + delta2 + 4])[0] ref_eck_rva = pe.get_rva_from_offset( ecc_delta_offset) + eck_delta + delta1 + 4 ref_ecs_rva = pe.get_rva_from_offset( ecc_delta_offset) + ecs_delta + delta2 + 4 eck_offset = pe.get_offset_from_rva(ref_eck_rva) ecs_offset = pe.get_offset_from_rva(ref_ecs_rva) key = filebuf[eck_offset:eck_offset + 4] size = struct.unpack("I", filebuf[eck_offset + 4:eck_offset + 8])[0] ^ struct.unpack( "I", key)[0] eck_offset += 8 eck_key = xor_data(filebuf[eck_offset:eck_offset + size], key) key_len = struct.unpack("<I", eck_key[4:8])[0] conf_dict.setdefault( "ECC ECK1", ECC.construct( curve="p256", point_x=int.from_bytes(eck_key[8:8 + key_len], "big"), point_y=int.from_bytes(eck_key[8 + key_len:], "big"), ).export_key(format="PEM"), ) key = filebuf[ecs_offset:ecs_offset + 4] size = struct.unpack("I", filebuf[ecs_offset + 4:ecs_offset + 8])[0] ^ struct.unpack( "I", key)[0] ecs_offset += 8 ecs_key = xor_data(filebuf[ecs_offset:ecs_offset + size], key) key_len = struct.unpack("<I", ecs_key[4:8])[0] conf_dict.setdefault( "ECC ECS1", ECC.construct( curve="p256", point_x=int.from_bytes(ecs_key[8:8 + key_len], "big"), point_y=int.from_bytes(ecs_key[8 + key_len:], "big"), ).export_key(format="PEM"), ) return conf_dict
def protocol_capture(eth_protocol, content): if eth_protocol == 8: ip_data = content[14:34] ip_unpack = unpack('!BBHHHBBH4s4s', ip_data) source_ip = socket.inet_ntoa(ip_unpack[8]) destination_ip = socket.inet_ntoa(ip_unpack[9]) ip_version = ip_unpack[0] ip_version_data = ip_version >> 4 if ip_version_data == 4: ip_length = 20 else: ip_length = 40 ip_protocol = ip_unpack[6] print 'IP_DATA: ' + ' Source Ip : ' + str( source_ip ) + ' Destination Ip: ' + destination_ip + ' Ip_version: ' + str( ip_version_data) + ' Ip_protocol:' + str( ip_protocol) + ' Ip Header length ' + str(ip_version_data) #Based on the protocol we will separate TCP, UDP, ICMP packets Below the logic for the getting the detilsin TCP packet. #This is when the ip_protocol is 6 if ip_protocol == 6: tcp_length = ip_length + 14 tcp_data = content[tcp_length:tcp_length + 20] tcp_unpack = unpack('!HHLLBBHHH', tcp_data) tcp_sourceport = tcp_unpack[0] tcp_destport = tcp_unpack[1] tcp_sequence = tcp_unpack[2] tcp_ack = tcp_unpack[3] doff_reserved = tcp_unpack[4] tcp_head_length = doff_reserved >> 4 print 'TCP_DATA:' + ' Source Port :' + str( tcp_sourceport) + ' Destination Port:' + str( tcp_destport) + ' Sequence:' + str( tcp_sequence) + ' Acknowledgement:' + str(tcp_ack) #Now when the ip_protocol value equals 1 it is a ICMP packet elif ip_protocol == 1: icmp_length = ip_length + 14 icmp_data = content[icmp_length:icmp_length + 4] icmp_unpack = unpack('!BBH', icmp_data) icmp_type = icmp_unpack[0] icmp_code = icmp_unpack[1] icmp_checksum = icmp_unpack[2] message = icmp_messages(icmp_type) print 'ICMP_DATA:' + ' Icmp_type ' + str( icmp_type) + ' Icmp_code ' + str( icmp_code) + ' Icmp_checksum ' + str( icmp_checksum) + ' Icmp Message: ' + str(message) #When the ip_protocol value equal 17 it is a UDP packet and below are UDP details elif ip_protocol == 17: udp_length = ip_length + 14 udp_data = content[udp_length:udp_length + 8] udp_unpack = unpack('!HHHH', udp_data) udp_source = udp_unpack[0] udp_destination = udp_unpack[1] udp_checksum = udp_unpack[3] print 'UDP DATA:' + ' Source port: ' + str( udp_source) + ' Destination port: ' + str( udp_destination) + ' Check Sum ' + str(udp_checksum) # if the ip_protocl is 2 then it is a IGMP packet elif ip_protocol == 2: igmp_length = ip_length + 14 igmp_data = content[igmp_length:igmp_length + 4] igmp_unpack = unpack('!BBHHHBBH4s4sI', igmp_data) igmp_type = igmp_unpack[0] igmp_code = igmp_unpack[1] igmp_checksum = igmp_unpack[3] message = igmp_meessages(igmp_type) print 'IGMP_DATA:' + 'Igmp Type:' + str( igmp_type ) + ' Igmp_code' + str( igmp_code ) + ' igmp checksum' + igmp_checksum + ' Igmp message: ' + message return True
def get_ip_src(self): return socket.inet_ntoa(self.getb('src'))
def numToDottedQuad(n): "convert long int to dotted quad string" return socket.inet_ntoa(struct.pack('!L', n))
def scan_for_default_gw(fields): if fields[DEST_COLUMN] == '00000000': s = fields[GW_COLUMN] return socket.inet_ntoa(binascii.unhexlify(s)[::-1])
def get_ip_dst(self): return socket.inet_ntoa(self.getb('dst'))
def handle_packet(self, pkt_dir, pkt): # TODO: Your main firewall code will be here. try: packet = pkt IP_header = unpack('!BBHHHBBH4s4s', packet[0:20]) ver_IHL = IP_header[0] ver = ver_IHL >> 4 IHL = ver_IHL & 0xF IP_header_length = IHL * 4 protocol = IP_header[6] sender_addr = socket.inet_ntoa(IP_header[8]) destination_addr = socket.inet_ntoa(IP_header[9]) protocol_type = None transaction_complete = False drop_packet = False http_object = {} # TCP if protocol == 6: TCP_header = unpack( '!HHLLBBHHH', packet[IP_header_length:IP_header_length + 20]) source_port = TCP_header[0] dest_port = TCP_header[1] seq_no = TCP_header[2] protocol_type = 'tcp' payload = len(packet[IP_header_length + 20:]) if dest_port == 80 or source_port == 80: # protocol_type = 'http' HTTP_header = packet[IP_header_length + 20:] if pkt_dir == PKT_DIR_OUTGOING: info = (sender_addr, destination_addr, source_port, dest_port) if info in self.http_state.keys(): old_packet = self.http_state[info] if old_packet['next_seq_no'] == seq_no: old_packet['seq_no'] = seq_no old_packet['next_seq_no'] = seq_no + payload end_index_packet = HTTP_header.find('\r\n\r\n') if not old_packet['locked']: if end_index_packet != -1: old_packet[ 'req'] += HTTP_header[: end_index_packet + 4] old_packet['locked'] = True else: old_packet['req'] += HTTP_header # print old_packet end_index_so_far = old_packet['req'].find( '\r\n\r\n') if end_index_so_far != -1: old_packet['locked'] = True else: if seq_no > old_packet['next_seq_no']: drop_packet = True else: new_pckt = { 'addr+port': (sender_addr, destination_addr, source_port, dest_port), 'seq_no': seq_no, 'next_seq_no': seq_no + payload, 'locked': False, 'req': '', 'resp': '', 'completed': False, 'persistant': False } end_index_packet = HTTP_header.find('\r\n\r\n') if end_index_packet != -1: new_pckt[ 'req'] += HTTP_header[:end_index_packet + 4] new_pckt['locked'] = True else: new_pckt['req'] += HTTP_header self.http_state[(sender_addr, destination_addr, source_port, dest_port)] = new_pckt else: info = (destination_addr, sender_addr, dest_port, source_port) if info in self.http_state.keys(): old_packet = self.http_state[info] if (old_packet['req'].find('\r\n\r\n') != -1): if old_packet['resp'] == '' or old_packet[ 'next_seq_no'] == seq_no: old_packet['locked'] = False old_packet['seq_no'] = seq_no old_packet[ 'next_seq_no'] = seq_no + payload end_index_packet = packet.find('\r\n\r\n') if not old_packet['locked']: if end_index_packet != -1: old_packet[ 'resp'] += HTTP_header[: end_index_packet + 4] old_packet['completed'] = True old_packet['locked'] = True transaction_complete = True else: old_packet['resp'] += HTTP_header end_index_so_far = old_packet[ 'resp'].find('\r\n\r\n') if end_index_so_far != -1: old_packet['locked'] = True old_packet['completed'] = True transaction_complete = True else: if seq_no > old_packet['seq_no']: drop_packet = True # UDP if protocol == 17: UDP_header = unpack( '!HHHH', packet[IP_header_length:IP_header_length + 8]) source_port = UDP_header[0] dest_port = UDP_header[1] UDP_length = UDP_header[2] UDP_checksum = UDP_header[3] protocol_type = 'udp' # DNS if dest_port == 53: DNS_header = unpack( '!HHHHHH', packet[IP_header_length + 8:IP_header_length + 20]) DNS_ID = DNS_header[0] # (1 << 15) + (OPCODE << 10) + (1 << 9) DNS_OPCODE = DNS_header[1] >> 10 QDCOUNT = DNS_header[2] protocol_type = 'dns' if QDCOUNT == 1: QNAME = [] x = IP_header_length + 20 length_byte = unpack('!B', packet[x])[0] while length_byte != 0: fmt = '!' + str(length_byte) + 's' QNAME.append( unpack(fmt, packet[x + 1:x + length_byte + 1])[0]) x += 1 + length_byte length_byte = unpack('!B', packet[x])[0] namelength = x - IP_header_length - 20 + 1 DNS_NAME = unpack('!' + str(namelength) + 's', packet[IP_header_length + 20:x + 1]) DNS_QTYPE = unpack('!H', packet[x + 1:x + 3])[0] DNS_QCLASS = unpack('!H', packet[x + 3:x + 5])[0] DNS_QUESTION = packet[IP_header_length + 20:x + 5] QNAME = string.join(QNAME, ".") # ICMP if protocol == 1: ICMP_header = unpack( '!BBHL', packet[IP_header_length:IP_header_length + 8]) ICMP_type = ICMP_header[0] protocol_type = 'icmp' dest_port = ICMP_type source_port = ICMP_type match = None ip_addr = None port = None if pkt_dir == PKT_DIR_INCOMING: port = source_port ip_addr = sender_addr else: port = dest_port ip_addr = destination_addr if not self.loss_mode or not self.loss_simulation(self.loss_rate): for rule in self.rules: if protocol_type == rule.storage[ 'protocol'] or rule.storage['protocol'] == 'http': if rule.storage['protocol'] == 'dns': if rule.match(QNAME): match = rule else: # PASS if not match: match = "PASS" else: if rule.storage[ 'protocol'] == 'http' and transaction_complete: # print "HTTP" key = (destination_addr, sender_addr, dest_port, source_port) transaction = self.http_state[key] http_object = http_parse(transaction) print http_object if rule.match(http_object['host']): f = open('http.log', 'a') wri = http_object['host'] + ' ' + http_object['method'] + ' ' + http_object['path'] + ' ' \ + http_object['version'] + ' ' + http_object['status_code'] + ' ' + http_object['object_size'] + '\n' # print wri f.write(wri) f.flush() # raise Exception if not self.http_state[key]['persistant']: del self.http_state[key] else: transaction['resp'] = '' transaction['req'] = '' transaction['completed'] = False transaction['locked'] = False transaction_complete = True if rule.storage['protocol'] == 'tcp': if rule.match(ip_addr) and rule.portMatch( port): match = rule else: if not match: match = "PASS" # print match if not match or match == "PASS" or match.storage[ 'verdict'] == 'pass' or not drop_packet: if pkt_dir == PKT_DIR_INCOMING: self.iface_int.send_ip_packet(pkt) elif pkt_dir == PKT_DIR_OUTGOING: self.iface_ext.send_ip_packet(pkt) elif match.storage['verdict'] == 'deny': resp_pkt = None if match.storage['protocol'] == 'tcp': # DROP PACKET AND RESPOND WITH RST resp_pkt = create_tcp_deny(sender_addr, destination_addr, source_port, dest_port) elif match.storage['protocol'] == 'dns': if pkt_dir == PKT_DIR_OUTGOING: # Drop packet and respond with placeholder redirect # DNS_ID, OPCODE, NAME, namelength, dest_addr, src_addr if DNS_QTYPE != 'AAAA': resp_pkt = create_dns_deny(DNS_ID, DNS_OPCODE, DNS_NAME[0], namelength, destination_addr, sender_addr, source_port, DNS_QUESTION) else: resp_pkt = packet # print resp_pkt if pkt_dir == PKT_DIR_INCOMING: self.iface_ext.send_ip_packet(resp_pkt) elif pkt_dir == PKT_DIR_OUTGOING: self.iface_int.send_ip_packet(resp_pkt) # END Try except Exception as e: raise e if pkt_dir == PKT_DIR_INCOMING: self.iface_int.send_ip_packet(pkt) elif pkt_dir == PKT_DIR_OUTGOING: self.iface_ext.send_ip_packet(pkt)
def handle_proxy_conn(self, reader, writer): """ Handle incoming client connection. Perform SOCKSv5 request exchange, open a proxied connection and start relaying. @param reader: Read side of the socket @type reader: asyncio.StreamReader @param writer: Write side of the socket @type writer: asyncio.StreamWriter """ try: # SOCKS hello data = yield from reader.readexactly(2) vers, method_no = struct.unpack('!BB', data) if vers != 0x05: # disconnect on invalid packet -- we have no clue how # to reply in alien :) writer.close() return # ...and auth method list data = yield from reader.readexactly(method_no) for method in data: if method == 0x00: break else: # no supported method method = 0xFF # auth reply repl = struct.pack('!BB', 0x05, method) writer.write(repl) yield from writer.drain() if method == 0xFF: writer.close() return # request data = yield from reader.readexactly(4) vers, cmd, rsv, atyp = struct.unpack('!BBBB', data) if vers != 0x05 or rsv != 0x00: # disconnect on malformed packet self.close() return # figure out if we can handle it rpl = 0x00 if cmd != 0x01: # CONNECT rpl = 0x07 # command not supported elif atyp == 0x01: # IPv4 data = yield from reader.readexactly(4) addr = socket.inet_ntoa(data) elif atyp == 0x03: # domain name data = yield from reader.readexactly(1) addr_len, = struct.unpack('!B', data) addr = yield from reader.readexactly(addr_len) try: addr = addr.decode('idna') except UnicodeDecodeError: rpl = 0x04 # host unreachable elif atyp == 0x04: # IPv6 data = yield from reader.readexactly(16) addr = socket.inet_ntop(socket.AF_INET6, data) else: rpl = 0x08 # address type not supported # try to connect if we can handle it if rpl == 0x00: data = yield from reader.readexactly(2) port, = struct.unpack('!H', data) try: # open a proxied connection proxied_reader, proxied_writer = yield from asyncio.open_connection( addr, port) except (socket.gaierror, socket.herror): # DNS failure rpl = 0x04 # host unreachable except OSError as e: # connection failure if e.errno in (errno.ENETUNREACH, errno.ENETDOWN): rpl = 0x03 # network unreachable elif e.errno in (errno.EHOSTUNREACH, errno.EHOSTDOWN): rpl = 0x04 # host unreachable elif e.errno in (errno.ECONNREFUSED, errno.ETIMEDOUT): rpl = 0x05 # connection refused else: raise else: # get socket details that we can send back to the client # local address (sockname) in particular -- but we need # to ask for the whole socket since Python's sockaddr # does not list the family... sock = proxied_writer.get_extra_info('socket') addr = sock.getsockname() if sock.family == socket.AF_INET: host, port = addr bin_host = socket.inet_aton(host) repl_addr = struct.pack('!B4sH', 0x01, bin_host, port) elif sock.family == socket.AF_INET6: # discard flowinfo, scope_id host, port = addr[:2] bin_host = socket.inet_pton(sock.family, host) repl_addr = struct.pack('!B16sH', 0x04, bin_host, port) if rpl != 0x00: # fallback to 0.0.0.0:0 repl_addr = struct.pack('!BLH', 0x01, 0x00000000, 0x0000) # reply to the request repl = struct.pack('!BBB', 0x05, rpl, 0x00) writer.write(repl + repl_addr) yield from writer.drain() # close if an error occured if rpl != 0x00: writer.close() return # otherwise, start two loops: # remote -> local... t = asyncio_ensure_future( self.handle_proxied_conn(proxied_reader, writer, current_task())) # and local -> remote... try: try: while True: data = yield from reader.read(4096) if data == b'': # client disconnected, stop relaying from # remote host t.cancel() break proxied_writer.write(data) yield from proxied_writer.drain() except OSError: # read or write failure t.cancel() except: t.cancel() raise finally: # always disconnect in the end :) proxied_writer.close() writer.close() except (OSError, asyncio.IncompleteReadError, asyncio.CancelledError): writer.close() return except: writer.close() raise
def numToIp(num): """ Convert a numeric value into the IP string form. """ num = long(num) return socket.inet_ntoa(struct.pack('!L', num))
def Unpack(self, data): try: return socket.inet_ntoa(data) except socket.error as e: raise ArgsValidationError("Can't unpack data: %s" % e)
def convertIP(ip): return socket.inet_ntoa(struct.pack('!L',ip));
def int2ip(int_ip): return socket.inet_ntoa(struct.pack("!I", int_ip))
class pcap_miner(): def __init__(self,pcap_file): #declaration self._pcap_file = pcap_file self._http_request_data = [] self._source_ips = [] self._destination_ips = [] self._source_ip_details = [] self._destination_ip_details = [] self._dns_request_data = [] self._flows = [] self._packet_count = 0 self._http_count = 0 self._dns_count = 0 #processing self._handle = self._get_dpkt_handle() self._extract_data() def _get_dpkt_handle(self): f = open(self._pcap_file) pcap = dpkt.pcap.Reader(f) return pcap def unpack_ip(self,packed_ip): ip = socket.inet_ntoa(packed_ip) return ip def quick_unique(self,seq): seen = set() return [ x for x in seq if x not in seen and not seen.add(x)] def _extract_data(self): pcap = self._handle eth = None ip = None protocol = None for ts, buf in pcap: try: eth = dpkt.ethernet.Ethernet(buf) ip = eth.data protocol = ip.data except dpkt.dpkt.NeedData: continue self._packet_count += 1 try: source_ip = self.unpack_ip(ip.src) destination_ip = self.unpack_ip(ip.dst) self._source_ips.append(source_ip) self._destination_ips.append(destination_ip) except Exception, e: continue try: if protocol.dport == 80 or protocol.dport == 443: self._http_count += 1 try: http = dpkt.http.Request(protocol.data) tmp = http.headers tmp["source_ip"] = source_ip tmp['destination_ip'] = destination_ip tmp['method'] = http.method tmp['version'] = http.version tmp['uri'] = http.uri self._http_request_data.append(tmp) except Exception, e: continue except Exception, e: continue try: if protocol.dport == 53 or protocol.sport == 53: self._dns_count += 1 try: dns = dns = dpkt.dns.DNS(protocol.data) if dns.qr != dpkt.dns.DNS_R: continue if dns.opcode != dpkt.dns.DNS_QUERY: continue if dns.rcode != dpkt.dns.DNS_RCODE_NOERR: continue if len(dns.an) < 1: continue for answer in dns.an: if answer.type == 5: tmp = { "type": "CNAME", "request":answer.name, "response":answer.cname } self._dns_request_data.append(tmp) elif answer.type == 1: tmp = { "type": "A", "request":answer.name, "response":socket.inet_ntoa(answer.rdata) } self._dns_request_data.append(tmp) elif answer.type == 12: tmp = { "type": "PTR", "request":answer.name, "response":answer.ptrname } self._dns_request_data.append(tmp) except Exception, e: continue except Exception, e: continue
import socket import struct s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) #s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3)) # Capture Ether #s.bind(('', 0)) while True: pacote = s.recvfrom(65565) traduzido = struct.unpack('!BBHHHBBH4s4s', pacote[0][0:20]) print 'From:', pacote[1][0] print 'Pacote:', traduzido print 'IP Version:', traduzido[0] >> 4 print 'TTL:', traduzido[5] print 'Protocol:', traduzido[6] print 'Source IP:', socket.inet_ntoa(traduzido[8]) print 'Target IP:', socket.inet_ntoa(traduzido[9]) print pacote[0]
def parse_packet(packet) : #parse ethernet header eth_length = 14 eth_header = packet[:eth_length] eth = unpack('!6s6sH' , eth_header) eth_protocol = socket.ntohs(eth[2]) print 'Destination MAC : ' + eth_addr(packet[0:6]) + ' Source MAC : ' + eth_addr(packet[6:12]) + ' Protocol : ' + str(eth_protocol) #Parse IP packets, IP Protocol number = 8 if eth_protocol == 8 : #Parse IP header #take first 20 characters for the ip header ip_header = packet[eth_length:20+eth_length] #now unpack them :) iph = unpack('!BBHHHBBH4s4s' , ip_header) version_ihl = iph[0] version = version_ihl >> 4 ihl = version_ihl & 0xF iph_length = ihl * 4 ttl = iph[5] protocol = iph[6] s_addr = socket.inet_ntoa(iph[8]); d_addr = socket.inet_ntoa(iph[9]); print 'Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + ' TTL : ' + str(ttl) + ' Protocol : ' + str(protocol) + ' Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr) #TCP protocol if protocol == 6 : t = iph_length + eth_length tcp_header = packet[t:t+20] #now unpack them :) tcph = unpack('!HHLLBBHHH' , tcp_header) source_port = tcph[0] dest_port = tcph[1] sequence = tcph[2] acknowledgement = tcph[3] doff_reserved = tcph[4] tcph_length = doff_reserved >> 4 print 'Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Sequence Number : ' + str(sequence) + ' Acknowledgement : ' + str(acknowledgement) + ' TCP header length : ' + str(tcph_length) h_size = eth_length + iph_length + tcph_length * 4 data_size = len(packet) - h_size #get data from the packet data = packet[h_size:] print 'Data : ' + data #ICMP Packets elif protocol == 1 : u = iph_length + eth_length icmph_length = 4 icmp_header = packet[u:u+4] #now unpack them :) icmph = unpack('!BBH' , icmp_header) icmp_type = icmph[0] code = icmph[1] checksum = icmph[2] print 'Type : ' + str(icmp_type) + ' Code : ' + str(code) + ' Checksum : ' + str(checksum) h_size = eth_length + iph_length + icmph_length data_size = len(packet) - h_size #get data from the packet data = packet[h_size:] print 'Data : ' + data #UDP packets elif protocol == 17 : u = iph_length + eth_length udph_length = 8 udp_header = packet[u:u+8] #now unpack them :) udph = unpack('!HHHH' , udp_header) source_port = udph[0] dest_port = udph[1] length = udph[2] checksum = udph[3] print 'Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Length : ' + str(length) + ' Checksum : ' + str(checksum) h_size = eth_length + iph_length + udph_length data_size = len(packet) - h_size #get data from the packet data = packet[h_size:] print 'Data : ' + data #some other IP packet like IGMP else : print 'Protocol other than TCP/UDP/ICMP' print
def unpack_ip(self,packed_ip): ip = socket.inet_ntoa(packed_ip) return ip