def test_decoding(self): '''Test IP6 Packet decoding.''' d = ImpactDecoder.IP6Decoder() parsed_packet = d.decode(self.binary_packet) protocol_version = parsed_packet.get_protocol_version() traffic_class = parsed_packet.get_traffic_class() flow_label = parsed_packet.get_flow_label() payload_length = parsed_packet.get_payload_length() next_header = parsed_packet.get_next_header() hop_limit = parsed_packet.get_hop_limit() source_address = parsed_packet.get_source_address() destination_address = parsed_packet.get_destination_address() self.assertEquals(protocol_version, 6, "IP6 parsing - Incorrect protocol version") self.assertEquals(traffic_class, 72, "IP6 parsing - Incorrect traffic class") self.assertEquals(flow_label, 148997, "IP6 parsing - Incorrect flow label") self.assertEquals(payload_length, 1500, "IP6 parsing - Incorrect payload length") self.assertEquals(next_header, 17, "IP6 parsing - Incorrect next header") self.assertEquals(hop_limit, 1, "IP6 parsing - Incorrect hop limit") self.assertEquals(source_address.as_string(), "FE80::78F8:89D1:30FF:256B", "IP6 parsing - Incorrect source address") self.assertEquals(destination_address.as_string(), "FF02::1:3", "IP6 parsing - Incorrect destination address")
def test_decoding_chained_basic_options_inside_ipv6_packet(self): ipv6_binary_packet = [ 0x64, 0x82, 0x46, 0x05, 0x05, 0xdc, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf8, 0x89, 0xd1, 0x30, 0xff, 0x25, 0x6b, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03] hop_by_hop_binary_packet = [ 0x2b, 0x01, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] routing_options_binary_packet = [ 0x3c, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00] dest_opts_binary_packet = [ 0x3a, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00] binary_packet = ipv6_binary_packet + hop_by_hop_binary_packet + routing_options_binary_packet + dest_opts_binary_packet d = ImpactDecoder.IP6Decoder() parsed_ipv6_packet = d.decode(binary_packet) # IPv6 Parsing ipv6_protocol_version = parsed_ipv6_packet.get_ip_v() ipv6_traffic_class = parsed_ipv6_packet.get_traffic_class() ipv6_flow_label = parsed_ipv6_packet.get_flow_label() ipv6_payload_length = parsed_ipv6_packet.get_payload_length() ipv6_next_header = parsed_ipv6_packet.get_next_header() ipv6_hop_limit = parsed_ipv6_packet.get_hop_limit() ipv6_source_address = parsed_ipv6_packet.get_ip_src() ipv6_destination_address = parsed_ipv6_packet.get_ip_dst() # Hop By Hop Parsing hop_by_hop_parsed_packet = parsed_ipv6_packet.child() hop_by_hop_next_header = hop_by_hop_parsed_packet.get_next_header() hop_by_hop_header_extension_length = hop_by_hop_parsed_packet.get_header_extension_length() hop_by_hop_options = hop_by_hop_parsed_packet.get_options() self.assertEqual(1, len(hop_by_hop_options), "Hop By Hop Parsing - Wrong Quantity of Options") hop_by_hop_padn_option = hop_by_hop_options[0] hop_by_hop_padn_option_type = hop_by_hop_padn_option.get_option_type() hop_by_hop_padn_option_length = hop_by_hop_padn_option.get_option_length() # Routing Options Tests routing_options_parsed_packet = hop_by_hop_parsed_packet.child() routing_options_next_header = routing_options_parsed_packet.get_next_header() routing_options_header_extension_length = routing_options_parsed_packet.get_header_extension_length() routing_options_routing_type = routing_options_parsed_packet.get_routing_type() routing_options_segments_left = routing_options_parsed_packet.get_segments_left() routing_options_options = routing_options_parsed_packet.get_options() # Destination Options Parsing destination_options_parsed_packet = routing_options_parsed_packet.child() destination_options_next_header = destination_options_parsed_packet.get_next_header() destination_options_header_extension_length = destination_options_parsed_packet.get_header_extension_length() destination_options_options = destination_options_parsed_packet.get_options() self.assertEqual(2, len(destination_options_options), "Destination Options Parsing - Wrong Quantity of Options") destination_options_pad1_option = destination_options_options[0] destination_options_pad1_option_type = destination_options_pad1_option.get_option_type() destination_options_padn_option = destination_options_options[1] destination_options_padn_option_type = destination_options_padn_option.get_option_type() destination_options_padn_option_length = destination_options_padn_option.get_option_length() self.assertEqual(ipv6_protocol_version, 6, "IP6 parsing - Incorrect protocol version") self.assertEqual(ipv6_traffic_class, 72, "IP6 parsing - Incorrect traffic class") self.assertEqual(ipv6_flow_label, 148997, "IP6 parsing - Incorrect flow label") self.assertEqual(ipv6_payload_length, 1500, "IP6 parsing - Incorrect payload length") self.assertEqual(ipv6_next_header, 0, "IP6 parsing - Incorrect next header") self.assertEqual(ipv6_hop_limit, 1, "IP6 parsing - Incorrect hop limit") self.assertEqual(ipv6_source_address.as_string(), "FE80::78F8:89D1:30FF:256B", "IP6 parsing - Incorrect source address") self.assertEqual(ipv6_destination_address.as_string(), "FF02::1:3", "IP6 parsing - Incorrect destination address") self.assertEqual(hop_by_hop_parsed_packet.get_header_type(), 0, "Hop By Hop Parsing - Incorrect packet") self.assertEqual(hop_by_hop_next_header, 43, "Hop By Hop Parsing - Incorrect next header value") self.assertEqual(hop_by_hop_header_extension_length, 1, "Hop By Hop Parsing - Incorrect size") self.assertEqual(hop_by_hop_padn_option_type, 1, "Hop By Hop Parsing - Incorrect option type") self.assertEqual(hop_by_hop_padn_option_length, 12, "Hop By Hop Parsing - Incorrect option size") self.assertEqual(routing_options_parsed_packet.get_header_type(), 43, "Routing Options Parsing - Incorrect packet") self.assertEqual(routing_options_next_header, 60, "Routing Options Parsing - Incorrect next header value") self.assertEqual(routing_options_header_extension_length, 0, "Routing Options Parsing - Incorrect size") self.assertEqual(routing_options_routing_type, 0, "Routing Options Parsing - Incorrect routing type") self.assertEqual(routing_options_segments_left, 10, "Routing Options Parsing - Incorrect quantity of segments left size") self.assertEqual(0, len(routing_options_options), "Routing Options Parsing - Wrong Quantity of Options") self.assertEqual(destination_options_parsed_packet.get_header_type(), 60, "Destination Options Parsing - Incorrect packet") self.assertEqual(destination_options_next_header, 58, "Destination Options Parsing - Incorrect next header value") self.assertEqual(destination_options_header_extension_length, 0, "Destination Options Parsing - Incorrect size") self.assertEqual(destination_options_pad1_option_type, 0, "Destination Options Parsing - Incorrect option type") self.assertEqual(destination_options_padn_option_type, 1, "Destination Options Parsing - Incorrect option type") self.assertEqual(destination_options_padn_option_length, 3, "Destination Options Parsing - Incorrect option size")
def collector(self, packet): packetdata = None try: eth = ImpactDecoder.EthDecoder().decode(packet) off = eth.get_header_size() if eth.get_ether_type() == ImpactPacket.IP.ethertype: ip_decoder = ImpactDecoder.IPDecoder() ip = ip_decoder.decode(packet[off:]) dst = ip.get_ip_dst() src = ip.get_ip_src() if ip.get_ip_p() == ImpactPacket.UDP.protocol: udp = ip.child() payload = udp.child().get_bytes().tostring() try: import hexdump try: msg = message.from_wire(payload) except Exception as e: # Not an acceptable DNS packet return None if len(msg.answer) > 0: # Packet should not have an answer section return None if len(msg.question) > 0: for q in msg.question: #if hasattr(q, 'name'): if q.rdtype == rdatatype.A: if self.PROPERTIES['subdomain']['Value']: prefix = '.%s.%s.' % ( self.PROPERTIES['subdomain'] ['Value'], self.PROPERTIES['domain']['Value']) else: prefix = '.%s.' % ( self.PROPERTIES['domain']['Value']) if prefix == q.name.to_text( )[-len(prefix):]: # Send a reply to the DNS packet try: r = message.make_response(msg) a = A(rdataclass.IN, rdatatype.A, '79.70.84.71' ) # OFTG in dotted-decimal rrs = rrset.from_rdata( q.name.to_text(), 30, a) r.answer.append(rrs) data = ImpactPacket.Data( r.to_wire()) rudp = ImpactPacket.UDP() rudp.set_uh_sport(53) rudp.set_uh_dport(12345) rudp.contains(data) rip = ImpactPacket.IP() rip.set_ip_dst(src) rip.set_ip_src(self.getlocaladdr()) rip.contains(rudp) s = socket.socket( socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP) s.setsockopt( socket.IPPROTO_IP, socket.IP_HDRINCL, 1) s.sendto(rip.get_packet(), (src, 12345)) except Exception as e: self.logger.error( 'Failed to send reply packet with %s: %s' % (self.__class__.__name__, e)) dnsdata = q.name.to_text( )[:-len(prefix)] dnsdata = self.dnsb64unescape(dnsdata) payload = self.decoder(dnsdata) result = payload # TODO: Fix results result['Source Host'] = src result['Protocol Subtype'] = 'Port' result[ 'Subtype'] = 53 #str(ip.child().get_uh_sport()) return result except DNSException: pass except Exception as e: if e: print 'Error %s' % e.message raise elif eth.get_ether_type() == IP6.IP6.ethertype: ip6_decoder = ImpactDecoder.IP6Decoder() ip6 = ip6_decoder.decode(packet[off:]) src = ip6.get_source_address() packetdata = ip6.get_data_as_string() self.logger.debug( 'Skipping IPv6 packet (not supported for this plugin)') if not packetdata: return None return None except Exception as e: raise return None