def testClientSummaryToExportedNetworkInterfaceConverter(self): client_summary = rdfvalue.ClientSummary( interfaces=[rdfvalue.Interface( mac_address="123456", ifname="eth0", addresses=[ rdfvalue.NetworkAddress( address_type=rdfvalue.NetworkAddress.Family.INET, packed_bytes=socket.inet_aton("127.0.0.1"), ), rdfvalue.NetworkAddress( address_type=rdfvalue.NetworkAddress.Family.INET, packed_bytes=socket.inet_aton("10.0.0.1"), ), rdfvalue.NetworkAddress( address_type=rdfvalue.NetworkAddress.Family.INET6, packed_bytes=socket.inet_pton(socket.AF_INET6, "2001:720:1500:1::a100"), ) ] )] ) converter = export.ClientSummaryToExportedNetworkInterfaceConverter() results = list(converter.Convert(rdfvalue.ExportedMetadata(), client_summary, token=self.token)) self.assertEqual(len(results), 1) self.assertEqual(results[0].mac_address, "123456".encode("hex")) self.assertEqual(results[0].ifname, "eth0") self.assertEqual(results[0].ip4_addresses, "127.0.0.1 10.0.0.1") self.assertEqual(results[0].ip6_addresses, "2001:720:1500:1::a100")
def Run(self, unused_args): """Enumerate all MAC addresses.""" libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c")) ifa = Ifaddrs() p_ifa = ctypes.pointer(ifa) libc.getifaddrs(ctypes.pointer(p_ifa)) addresses = {} macs = {} ifs = set() m = p_ifa while m: ifname = ctypes.string_at(m.contents.ifa_name) ifs.add(ifname) try: iffamily = ord(m.contents.ifa_addr[1]) if iffamily == 0x2: # AF_INET data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrin)) ip4 = "".join(map(chr, data.contents.sin_addr)) address_type = rdfvalue.NetworkAddress.Family.INET address = rdfvalue.NetworkAddress( address_type=address_type, packed_bytes=ip4) addresses.setdefault(ifname, []).append(address) if iffamily == 0x12: # AF_LINK data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrdl)) iflen = data.contents.sdl_nlen addlen = data.contents.sdl_alen macs[ifname] = "".join( map(chr, data.contents.sdl_data[iflen:iflen + addlen])) if iffamily == 0x1E: # AF_INET6 data = ctypes.cast(m.contents.ifa_addr, ctypes.POINTER(Sockaddrin6)) ip6 = "".join(map(chr, data.contents.sin6_addr)) address_type = rdfvalue.NetworkAddress.Family.INET6 address = rdfvalue.NetworkAddress( address_type=address_type, packed_bytes=ip6) addresses.setdefault(ifname, []).append(address) except ValueError: # Some interfaces don't have a iffamily and will raise a null pointer # exception. We still want to send back the name. pass m = m.contents.ifa_next libc.freeifaddrs(p_ifa) for interface in ifs: mac = macs.setdefault(interface, "") address_list = addresses.setdefault(interface, "") args = {"ifname": interface} if mac: args["mac_address"] = mac if address_list: args["addresses"] = address_list self.SendReply(**args)
def _ConvertIPs(self, io_tuples, interface, output_dict): for inputkey, outputkey in io_tuples: addresses = [] if isinstance(interface[inputkey], list): for ip_address in interface[inputkey]: addresses.append( rdfvalue.NetworkAddress( human_readable_address=ip_address)) else: addresses.append( rdfvalue.NetworkAddress( human_readable_address=interface[inputkey])) output_dict[outputkey] = addresses return output_dict
def Run(self, unused_args): """Enumerate all MAC addresses.""" pythoncom.CoInitialize() for interface in wmi.WMI().Win32_NetworkAdapterConfiguration( IPEnabled=1): addresses = [] for ip_address in interface.IPAddress: if ":" in ip_address: # IPv6 address_type = rdfvalue.NetworkAddress.Family.INET6 else: # IPv4 address_type = rdfvalue.NetworkAddress.Family.INET addresses.append( rdfvalue.NetworkAddress(human_readable=ip_address, address_type=address_type)) args = {"ifname": interface.Description} args["mac_address"] = binascii.unhexlify( interface.MACAddress.replace(":", "")) if addresses: args["addresses"] = addresses self.SendReply(**args)
def testIPv4(self): sample = rdfvalue.NetworkAddress(human_readable_address="192.168.0.1") self.assertEqual(sample.address_type, rdfvalue.NetworkAddress.Family.INET) self.assertEqual(sample.packed_bytes, socket.inet_pton(socket.AF_INET, "192.168.0.1")) self.assertEqual(sample.human_readable_address, "192.168.0.1") self.CheckRDFValue(self.rdfvalue_class(sample), sample)
def testIPv6(self): ipv6_addresses = ["fe80::202:b3ff:fe1e:8329", "::1"] for address in ipv6_addresses: sample = rdfvalue.NetworkAddress(human_readable_address=address) self.assertEqual(sample.address_type, rdfvalue.NetworkAddress.Family.INET6) self.assertEqual(sample.packed_bytes, socket.inet_pton(socket.AF_INET6, address)) self.assertEqual(sample.human_readable_address, address) self.CheckRDFValue(self.rdfvalue_class(sample), sample)
def EnumerateInterfaces(self, _): return [ rdfvalue.Interface( mac_address="123456", addresses=[ rdfvalue.NetworkAddress( address_type=rdfvalue.NetworkAddress.Family.INET, human_readable="127.0.0.1", packed_bytes=socket.inet_aton("127.0.0.1"), ) ]) ]
def RunNetAdapterWMIQuery(self): pythoncom.CoInitialize() for interface in wmi.WMI().Win32_NetworkAdapterConfiguration(IPEnabled=1): addresses = [] for ip_address in interface.IPAddress: addresses.append(rdfvalue.NetworkAddress( human_readable_address=ip_address)) args = {"ifname": interface.Description} args["mac_address"] = binascii.unhexlify( interface.MACAddress.replace(":", "")) if addresses: args["addresses"] = addresses yield args
def testClientListReport(self): """Check that we can create and run a ClientList Report.""" # Create some clients. client_ids = self.SetupClients(10) with aff4.FACTORY.Open(client_ids[0], token=self.token, mode="rw") as client: with aff4.FACTORY.Open(client.urn.Add("network"), aff4_type="Network", token=self.token, mode="w") as net: interfaces = net.Schema.INTERFACES() interfaces.Append(addresses=[ rdfvalue.NetworkAddress(human_readable="1.1.1.1", address_type="INET") ], mac_address="11:11:11:11:11:11", ifname="eth0") net.Set(interfaces) client.Set(client.Schema.HOSTNAME("lawman")) # Also initialize a broken client with no hostname. with aff4.FACTORY.Open(client_ids[1], token=self.token, mode="rw") as client: client.Set(client.Schema.CLIENT_INFO("")) # Create a report for all clients. report = reports.ClientListReport(token=self.token) report.Run() self.assertEqual(len(report.results), 10) hostnames = [x.get("Host") for x in report.results] self.assertTrue("lawman" in hostnames) report.SortResults("Host") self.assertEqual(len(report.AsDict()), 10) self.assertEqual(len(report.AsCsv().getvalue().splitlines()), 11) self.assertEqual(len(report.AsText().getvalue().splitlines()), 10) self.assertEqual(report.results[-1]["Interfaces"], "1.1.1.1") self.assertEqual(len(report.broken_clients), 1)
def testRdfFormatter(self): """Hints format RDF values with arbitrary values and attributes.""" # Create a complex RDF value rdf = rdfvalue.ClientSummary() rdf.system_info.system = "Linux" rdf.system_info.node = "coreai.skynet.com" # Users (repeated) rdf.users = [rdfvalue.User(username=u) for u in ("root", "jconnor")] # Interface (nested, repeated) addresses = [ rdfvalue.NetworkAddress(human_readable=a) for a in ("1.1.1.1", "2.2.2.2", "3.3.3.3") ] eth0 = rdfvalue.Interface(ifname="eth0", addresses=addresses[:2]) ppp0 = rdfvalue.Interface(ifname="ppp0", addresses=addresses[2]) rdf.interfaces = [eth0, ppp0] template = ( "{system_info.system} {users.username} {interfaces.ifname} " "{interfaces.addresses.human_readable}") hinter = hints.Hinter(template=template) expected = "Linux root,jconnor eth0,ppp0 1.1.1.1,2.2.2.2,3.3.3.3" result = hinter.Render(rdf) self.assertEqual(expected, result)
def GenerateSample(self, number=0): return rdfvalue.NetworkAddress(human_readable_address="192.168.0.%s" % number)