def setUp(self): super(ListVADBinariesTest, self).setUp() client = aff4.FACTORY.Open(self.client_id, token=self.token, mode="rw") client.Set(client.Schema.SYSTEM("Windows")) client.Set(client.Schema.OS_VERSION("6.2")) client.Flush() vfs.VFS_HANDLERS[ rdfvalue.PathSpec.PathType.OS] = test_lib.ClientVFSHandlerFixture vfs.VFS_HANDLERS[rdfvalue.PathSpec.PathType. REGISTRY] = test_lib.ClientRegistryVFSFixture # Add some user accounts to this client. fd = aff4.FACTORY.Open(self.client_id, mode="rw", token=self.token) users = fd.Schema.USER() users.Append( rdfvalue.User(username="******", domain="testing-PC", homedir=r"C:\Users\localservice", sid="S-1-5-20")) fd.Set(users) fd.Close() self.old_driver_flow = flow.GRRFlow.classes["LoadMemoryDriver"] flow.GRRFlow.classes["LoadMemoryDriver"] = DummyLoadMemoryDriverFlow
def setUp(self): super(TestWebHistory, self).setUp() # Set up client info self.client = aff4.FACTORY.Open(self.client_id, mode="rw", token=self.token) self.client.Set(self.client.Schema.SYSTEM("Linux")) user_list = self.client.Schema.USER() user_list.Append( rdfvalue.User(username="******", full_name="test user", homedir="/home/test/", last_logon=250)) self.client.AddAttribute(self.client.Schema.USER, user_list) self.client.Close() self.client_mock = action_mocks.ActionMock( "ReadBuffer", "FingerprintFile", "HashBuffer", "TransferBuffer", "StatFile", "Find", "ListDirectory", "Grep") # Mock the client to make it look like the root partition is mounted off the # test image. This will force all flow access to come off the image. def MockGetMountpoints(): return {"/": (os.path.join(self.base_path, "test_img.dd"), "ext2")} self.orig_linux_mp = client_utils_linux.GetMountpoints self.orig_osx_mp = client_utils_osx.GetMountpoints client_utils_linux.GetMountpoints = MockGetMountpoints client_utils_osx.GetMountpoints = MockGetMountpoints # We wiped the data_store so we have to retransmit all blobs. standard.HASH_CACHE = utils.FastStore(100)
def setUp(self): super(TestEndToEndTestFlow, self).setUp() install_time = rdfvalue.RDFDatetime().Now() user = "******" userobj = rdfvalue.User(username=user) interface = rdfvalue.Interface(ifname="eth0") self.client = aff4.FACTORY.Create(self.client_id, "VFSGRRClient", mode="rw", token=self.token, age=aff4.ALL_TIMES) self.client.Set(self.client.Schema.HOSTNAME("hostname")) self.client.Set(self.client.Schema.SYSTEM("Linux")) self.client.Set(self.client.Schema.OS_RELEASE("debian")) self.client.Set(self.client.Schema.OS_VERSION("14.04")) self.client.Set(self.client.Schema.KERNEL("3.15-rc2")) self.client.Set(self.client.Schema.FQDN("hostname.example.com")) self.client.Set(self.client.Schema.ARCH("x86_64")) self.client.Set(self.client.Schema.INSTALL_DATE(install_time)) self.client.Set(self.client.Schema.USER([userobj])) self.client.Set(self.client.Schema.USERNAMES([user])) self.client.Set(self.client.Schema.LAST_INTERFACES([interface])) self.client.Flush() self.client_mock = action_mocks.ActionMock("ListDirectory", "StatFile")
def testRegistryMRU(self): """Test that the MRU discovery flow. Flow is a work in Progress.""" # Install the mock vfs.VFS_HANDLERS[ rdfvalue.PathSpec.PathType.REGISTRY] = test_lib.ClientRegistryVFSFixture # Mock out the Find client action. client_mock = test_lib.ActionMock("Find") # Add some user accounts to this client. fd = aff4.FACTORY.Open(self.client_id, mode="rw", token=self.token) users = fd.Schema.USER() users.Append(rdfvalue.User( username="******", domain="testing-PC", homedir=r"C:\Users\testing", sid="S-1-5-21-2911950750-476812067-" "1487428992-1001")) fd.Set(users) fd.Close() # Run the flow in the emulated way. for _ in test_lib.TestFlowHelper("GetMRU", client_mock, client_id=self.client_id, token=self.token): pass # Check that the key was read. fd = aff4.FACTORY.Open(rdfvalue.RDFURN(self.client_id).Add( "registry/HKEY_USERS/S-1-5-21-2911950750-476812067-1487428992-1001/" "Software/Microsoft/Windows/CurrentVersion/Explorer/" "ComDlg32/OpenSavePidlMRU/dd/0"), token=self.token) self.assertEqual(fd.__class__.__name__, "VFSFile") s = fd.Get(fd.Schema.STAT) # TODO(user): Make this test better when the MRU flow is complete. self.assertTrue(s.registry_data)
def testGlobDirectory(self): """Test that glob expands directories.""" # Add some usernames we can interpolate later. client = aff4.FACTORY.Open(self.client_id, mode="rw", token=self.token) user_attribute = client.Schema.USER() user_record = rdfvalue.User() user_record.special_folders.app_data = "test_data/index.dat" user_attribute.Append(user_record) user_record = rdfvalue.User() user_record.special_folders.app_data = "test_data/History" user_attribute.Append(user_record) # This is a record which means something to the interpolation system. We # should not process this especially. user_record = rdfvalue.User() user_record.special_folders.app_data = "%%PATH%%" user_attribute.Append(user_record) client.Set(user_attribute) client.Close() client_mock = action_mocks.ActionMock("Find", "StatFile") # This glob selects all files which start with the username on this system. path = os.path.join(os.path.dirname(self.base_path), "%%Users.special_folders.app_data%%") # Run the flow. for _ in test_lib.TestFlowHelper("Glob", client_mock, client_id=self.client_id, paths=[path], token=self.token): pass path = self.client_id.Add("fs/os").Add(self.base_path).Add("index.dat") aff4.FACTORY.Open(path, aff4_type="VFSFile", token=self.token) path = self.client_id.Add("fs/os").Add(self.base_path).Add("index.dat") aff4.FACTORY.Open(path, aff4_type="VFSFile", token=self.token)
def ProcessKnowledgeBase(self, responses): """Update the SUMMARY from the knowledgebase data.""" if not responses.success: raise flow.FlowError("Error collecting artifacts: %s" % responses.status) knowledge_base = artifact.GetArtifactKnowledgeBase(self.client) for kbuser in knowledge_base.users: self.state.summary.users.Append( rdfvalue.User().FromKnowledgeBaseUser(kbuser))
def testGetClientSummary(self): hostname = "test" system = "Linux" os_release = "12.02" kernel = "3.15-rc2" fqdn = "test.test.com" arch = "amd64" install_time = rdfvalue.RDFDatetime().Now() user = "******" userobj = rdfvalue.User(username=user) interface = rdfvalue.Interface(ifname="eth0") timestamp = 1 with utils.Stubber(time, "time", lambda: timestamp): with aff4.FACTORY.Create("C.0000000000000000", "VFSGRRClient", mode="rw", token=self.token) as fd: empty_summary = fd.GetSummary() self.assertEqual(empty_summary.client_id, "C.0000000000000000") self.assertFalse(empty_summary.system_info.version) self.assertEqual(empty_summary.timestamp.AsSecondsFromEpoch(), 1) # This will cause TYPE to be written with current time = 101 when the # object is closed timestamp += 100 fd.Set(fd.Schema.HOSTNAME(hostname)) fd.Set(fd.Schema.SYSTEM(system)) fd.Set(fd.Schema.OS_RELEASE(os_release)) fd.Set(fd.Schema.KERNEL(kernel)) fd.Set(fd.Schema.FQDN(fqdn)) fd.Set(fd.Schema.ARCH(arch)) fd.Set(fd.Schema.INSTALL_DATE(install_time)) fd.Set(fd.Schema.USER([userobj])) fd.Set(fd.Schema.USERNAMES([user])) fd.Set(fd.Schema.LAST_INTERFACES([interface])) with aff4.FACTORY.Open("C.0000000000000000", "VFSGRRClient", mode="rw", token=self.token) as fd: summary = fd.GetSummary() self.assertEqual(summary.system_info.node, hostname) self.assertEqual(summary.system_info.system, system) self.assertEqual(summary.system_info.release, os_release) self.assertEqual(summary.system_info.kernel, kernel) self.assertEqual(summary.system_info.fqdn, fqdn) self.assertEqual(summary.system_info.machine, arch) self.assertEqual(summary.system_info.install_date, install_time) self.assertItemsEqual(summary.users, [userobj]) self.assertItemsEqual(summary.interfaces, [interface]) self.assertFalse(summary.client_info) self.assertEqual(summary.timestamp.AsSecondsFromEpoch(), 101)
def testConvertToKnowledgeBaseUser(self): folders = rdfvalue.FolderInformation(desktop="/usr/local/test/Desktop") user = rdfvalue.User(username="******", domain="test.com", homedir="/usr/local/test", special_folders=folders) kbuser = user.ToKnowledgeBaseUser() self.assertEqual(kbuser.username, "test") self.assertEqual(kbuser.userdomain, "test.com") self.assertEqual(kbuser.homedir, "/usr/local/test") self.assertEqual(kbuser.desktop, "/usr/local/test/Desktop")
def testConvertFromKnowledgeBaseUser(self): kbuser = rdfvalue.KnowledgeBaseUser(username="******", userdomain="test.com", homedir="/usr/local/test", desktop="/usr/local/test/Desktop", localappdata="/usr/local/test/AppData") user = rdfvalue.User().FromKnowledgeBaseUser(kbuser) self.assertEqual(user.username, "test") self.assertEqual(user.domain, "test.com") self.assertEqual(user.homedir, "/usr/local/test") self.assertEqual(user.special_folders.desktop, "/usr/local/test/Desktop") self.assertEqual(user.special_folders.local_app_data, "/usr/local/test/AppData")
def testTimeEncoding(self): fast_proto = rdfvalue.User(username="******") # Check that we can coerce an int to an RDFDatetime. fast_proto.last_logon = 1365177603180131 self.assertEqual(str(fast_proto.last_logon), "2013-04-05 16:00:03") self.assertEqual(type(fast_proto.last_logon), rdfvalue.RDFDatetime) # Check that this is backwards compatible with the old protobuf library. proto = jobs_pb2.User() proto.ParseFromString(fast_proto.SerializeToString()) # Old implementation should just see the last_logon field as an integer. self.assertEqual(proto.last_logon, 1365177603180131) self.assertEqual(type(proto.last_logon), long) # fast protobufs interoperate with old serialized formats. serialized_data = proto.SerializeToString() fast_proto = rdfvalue.User(serialized_data) self.assertEqual(fast_proto.last_logon, 1365177603180131) self.assertEqual(type(fast_proto.last_logon), rdfvalue.RDFDatetime)
def testCompatibility(self): proto = jobs_pb2.User(username="******") proto.special_folders.desktop = "User Desktop 1" serialized = proto.SerializeToString() fast_proto = rdfvalue.User(serialized) self.assertEqual(fast_proto.username, proto.username) self.assertEqual(fast_proto.special_folders.desktop, proto.special_folders.desktop) # Serialized RDFValue and protobuf have same fields. self.assertRDFValueEqualToProto(fast_proto, proto)
def testProtoDescriptorIsGeneratedForDynamicType(self): test_pb_descriptor = DynamicTypeTest.EmitProtoDescriptor("grr_export") factory = message_factory.MessageFactory() proto_class = factory.GetPrototype(test_pb_descriptor) # Now let's define an RDFProtoStruct for the dynamically generated # proto_class. new_dynamic_class = type("DynamicTypeTestReversed", (rdfvalue.RDFProtoStruct,), dict(protobuf=proto_class)) new_dynamic_instance = new_dynamic_class( type="foo", nested=rdfvalue.User(username="******")) self.assertEqual(new_dynamic_instance.type, "foo") self.assertEqual(new_dynamic_instance.nested.username, "bar")
def testCompatibility(self): proto = jobs_pb2.User(username="******") proto.special_folders.desktop = "User Desktop 1" serialized = proto.SerializeToString() fast_proto = rdfvalue.User(serialized) self.assertEqual(fast_proto.username, proto.username) self.assertEqual(fast_proto.special_folders.desktop, proto.special_folders.desktop) # Serialized form of both should be the same. self.assertProtoEqual(fast_proto, proto)
def CopyUsersFromKnowledgeBase(self, client): """Copy users from knowledgebase to USER. TODO(user): deprecate USER completely in favour of KNOWLEDGE_BASE.user Args: client: client object open for writing """ usernames = [] user_list = client.Schema.USER() for kbuser in self.state.knowledge_base.users: user_list.Append(rdfvalue.User().FromKnowledgeBaseUser(kbuser)) if kbuser.username: usernames.append(kbuser.username) # Store it now client.AddAttribute(client.Schema.USER, user_list) client.AddAttribute(client.Schema.USERNAMES(" ".join(usernames)))
def testProtoFileDescriptorIsGeneratedForDynamicType(self): test_pb_file_descriptor, deps = DynamicTypeTest.EmitProtoFileDescriptor( "grr_export") pool = descriptor_pool.DescriptorPool() for file_descriptor in [test_pb_file_descriptor] + deps: pool.Add(file_descriptor) proto_descriptor = pool.FindMessageTypeByName( "grr_export.DynamicTypeTest") factory = message_factory.MessageFactory() proto_class = factory.GetPrototype(proto_descriptor) # Now let's define an RDFProtoStruct for the dynamically generated # proto_class. new_dynamic_class = type("DynamicTypeTestReversed", (rdfvalue.RDFProtoStruct, ), dict(protobuf=proto_class)) new_dynamic_instance = new_dynamic_class( type="foo", nested=rdfvalue.User(username="******")) self.assertEqual(new_dynamic_instance.type, "foo") self.assertEqual(new_dynamic_instance.nested.username, "bar")
def testClientSubfieldGet(self): """Test we can get subfields of the client.""" fd = aff4.FACTORY.Create("C.0000000000000000", "VFSGRRClient", token=self.token, age=aff4.ALL_TIMES) users = fd.Schema.USER() for i in range(5): folder = "C:/Users/user%s" % i user = rdfvalue.User(username="******" % i) user.special_folders.app_data = folder users.Append(user) fd.AddAttribute(users) fd.Close() # Check the repeated Users array. for i, folder in enumerate( fd.GetValuesForAttribute("Users.special_folders.app_data")): self.assertEqual(folder, "C:/Users/user%s" % i)
def testNoApplicableTests(self): """Try to run linux tests on windows.""" install_time = rdfvalue.RDFDatetime().Now() user = "******" userobj = rdfvalue.User(username=user) interface = rdfvalue.Interface(ifname="eth0") self.client = aff4.FACTORY.Create(self.client_id, "VFSGRRClient", mode="rw", token=self.token, age=aff4.ALL_TIMES) self.client.Set(self.client.Schema.HOSTNAME("hostname")) self.client.Set(self.client.Schema.SYSTEM("Windows")) self.client.Set(self.client.Schema.OS_RELEASE("7")) self.client.Set(self.client.Schema.OS_VERSION("6.1.7601SP1")) self.client.Set(self.client.Schema.KERNEL("6.1.7601")) self.client.Set(self.client.Schema.FQDN("hostname.example.com")) self.client.Set(self.client.Schema.ARCH("AMD64")) self.client.Set(self.client.Schema.INSTALL_DATE(install_time)) self.client.Set(self.client.Schema.USER([userobj])) self.client.Set(self.client.Schema.USERNAMES([user])) self.client.Set(self.client.Schema.LAST_INTERFACES([interface])) self.client.Flush() args = rdfvalue.EndToEndTestFlowArgs(test_names=[ "TestListDirectoryOSLinuxDarwin", "MockEndToEndTest", "TestListDirectoryOSLinuxDarwin" ]) self.assertRaises( flow.FlowError, list, test_lib.TestFlowHelper("EndToEndTestFlow", self.client_mock, client_id=self.client_id, token=self.token, args=args))
def ProcessKnowledgeBase(self, responses): """Update the SUMMARY from the knowledgebase data.""" if not responses.success: raise flow.FlowError("Error collecting artifacts: %s" % responses.status) knowledge_base = artifact.GetArtifactKnowledgeBase(self.client) for kbuser in knowledge_base.users: self.state.summary.users.Append( rdfvalue.User().FromKnowledgeBaseUser(kbuser)) # If the knowledge base came back with values for these collected via # artifacts, we trust those more than the values returned via the # GetPlatformInfo client action so we override them here. if knowledge_base.os_release: os_release = knowledge_base.os_release self.client.Set(self.client.Schema.OS_RELEASE(os_release)) # Override OS version field too. # TODO(user): this actually results in incorrect versions for things # like Ubuntu (14.4 instead of 14.04). I don't think zero- # padding is always correct, however. os_version = "%d.%d" % (knowledge_base.os_major_version, knowledge_base.os_minor_version) self.client.Set(self.client.Schema.OS_VERSION(os_version)) # Update client summary accordingly. self.state.summary.system_info.release = os_release self.state.summary.system_info.version = os_version # Collect any non-knowledgebase artifacts that will be stored in aff4. artifact_list = self._GetExtraArtifactsForCollection() if artifact_list: self.CallFlow("ArtifactCollectorFlow", artifact_list=artifact_list, next_state="ProcessArtifactResponses", store_results_in_aff4=True)
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): result = rdfvalue.User(username="******" % number) result.special_folders.desktop = "User Desktop %s" % number return result
def testGetExtension(self): """Test that finding the Chrome plugin works.""" # Set up client info self.client = aff4.FACTORY.Open(self.client_id, mode="rw", token=self.token) self.client.Set(self.client.Schema.SYSTEM("Linux")) user_list = self.client.Schema.USER() for u in [ rdfvalue.User(username="******", full_name="FooFoo", last_logon=150), rdfvalue.User(username="******", full_name="test user", homedir="/home/test/", last_logon=250) ]: user_list.Append(u) self.client.AddAttribute(self.client.Schema.USER, user_list) self.client.Close() client_mock = action_mocks.ActionMock("ReadBuffer", "FingerprintFile", "TransferBuffer", "StatFile", "ListDirectory", "HashBuffer", "Find") # TODO(user): Find a way to do this on Windows. # Mock the client to make it look like the root partition is mounted off the # test image. This will force all flow access to come off the image. def MockGetMountpoints(): return {"/": (os.path.join(self.base_path, "test_img.dd"), "ext2")} orig_linux_mp = client_utils_linux.GetMountpoints orig_osx_mp = client_utils_osx.GetMountpoints client_utils_linux.GetMountpoints = MockGetMountpoints client_utils_osx.GetMountpoints = MockGetMountpoints try: # Run the flow in the simulated way for _ in test_lib.TestFlowHelper( "ChromePlugins", client_mock, client_id=self.client_id, username="******", download_files=True, output="analysis/plugins", token=self.token, pathtype=rdfvalue.PathSpec.PathType.TSK): pass # Now check that the right files were downloaded. fs_path = ("/home/test/.config/google-chrome/Default/Extensions/" "nlbjncdgjeocebhnmkbbbdekmmmcbfjd/2.1.3_0") # Check if the output VFile is created output_path = self.client_id.Add("fs/tsk").Add("/".join( [self.base_path.replace("\\", "/"), "test_img.dd"])).Add(fs_path) fd = aff4.FACTORY.Open(output_path, token=self.token) children = list(fd.OpenChildren()) self.assertEqual(len(children), 3) # Check for Analysis dir output_path = self.client_id.Add( "analysis/plugins/RSS Subscription Extension (by Google)/2.1.3" ) fd = aff4.FACTORY.Open(output_path, token=self.token) self.assertEqual(fd.Get(fd.Schema.NAME), "RSS Subscription Extension (by Google)") self.assertEqual(fd.Get(fd.Schema.VERSION), "2.1.3") self.assertEqual(fd.Get(fd.Schema.CHROMEID), "nlbjncdgjeocebhnmkbbbdekmmmcbfjd") self.assertEqual(fd.Get(fd.Schema.EXTENSIONDIR), fs_path) # check for file downloads urns = [ str(c.urn) for c in children if str(c.urn).endswith("testfile.txt") ] self.assertEqual(len(urns), 1) fd = aff4.FACTORY.Open(urns[0], token=self.token) expect = "This should be downloaded automatically." self.assertTrue(fd.Read(10000).startswith(expect)) self.assertEqual(fd.size, 41) finally: client_utils_linux.GetMountpoints = orig_linux_mp client_utils_osx.GetMountpoints = orig_osx_mp
def RDFStructDecode(): new_s = rdfvalue.User() new_s.ParseFromString(data) self.assertEqual(new_s.username, "user") self.assertEqual(new_s.username.__class__, unicode)
def RDFStructCreateAndSerialize(): s = rdfvalue.User(**self.USER_ACCOUNT) s.SerializeToString()
def RDFStructCreateAndSerializeFromProto(): s = rdfvalue.User(test_proto) s.SerializeToString()
def RDFStructCreateAndSerializeSetValue(): s = rdfvalue.User() for k, v in self.USER_ACCOUNT.iteritems(): setattr(s, k, v) s.SerializeToString()