def testGrep(self): class MockCallFlow(object): def CallFlow(self, *args, **kwargs): self.args = args self.kwargs = kwargs mock_call_flow = MockCallFlow() with utils.Stubber(collectors.ArtifactCollectorFlow, "CallFlow", mock_call_flow.CallFlow): collect_flow = collectors.ArtifactCollectorFlow(None, token=self.token) collect_flow.args = mock.Mock() collect_flow.args.ignore_interpolation_errors = False kb = rdf_client.KnowledgeBase() kb.MergeOrAddUser(rdf_client.User(username="******")) kb.MergeOrAddUser(rdf_client.User(username="******")) collect_flow.state["knowledge_base"] = kb collect_flow.current_artifact_name = "blah" collector = artifact_registry.ArtifactSource( type=artifact_registry.ArtifactSource.SourceType.GREP, attributes={ "paths": ["/etc/passwd"], "content_regex_list": [r"^a%%users.username%%b$"] }) collect_flow.Grep(collector, rdf_paths.PathSpec.PathType.TSK) conditions = mock_call_flow.kwargs["conditions"] self.assertEqual(len(conditions), 1) regexes = conditions[0].contents_regex_match.regex.SerializeToString() self.assertItemsEqual(regexes.split("|"), ["(^atest1b$)", "(^atest2b$)"]) self.assertEqual(mock_call_flow.kwargs["paths"], ["/etc/passwd"])
def testGlob(self): """Test that glob works properly.""" client_id = self.SetupClient(0) # Add some usernames we can interpolate later. client = aff4.FACTORY.Open(client_id, mode="rw", token=self.token) kb = client.Get(client.Schema.KNOWLEDGE_BASE) kb.MergeOrAddUser(rdf_client.User(username="******")) kb.MergeOrAddUser(rdf_client.User(username="******")) client.Set(kb) client.Close() client_mock = action_mocks.GlobClientMock() # This glob selects all files which start with the username on this system. paths = [ os.path.join(self.base_path, "%%Users.username%%*"), os.path.join(self.base_path, "VFSFixture/var/*/wtmp") ] # Set iterator really low to force iteration. with utils.Stubber(filesystem.Glob, "FILE_MAX_PER_DIR", 2): flow_test_lib.TestFlowHelper( filesystem.Glob.__name__, client_mock, client_id=client_id, paths=paths, pathtype=rdf_paths.PathSpec.PathType.OS, token=self.token, sync=False, check_flow_errors=False) output_path = client_id.Add("fs/os").Add(self.base_path.replace("\\", "/")) children = [] fd = aff4.FACTORY.Open(output_path, token=self.token) for child in fd.ListChildren(): filename = child.Basename() if filename != "VFSFixture": children.append(filename) expected = [ filename for filename in os.listdir(self.base_path) if filename.startswith("test") or filename.startswith("syslog") ] self.assertTrue([x for x in expected if x.startswith("test")], "Need a file starting with 'test'" " in test_data for this test!") self.assertTrue([x for x in expected if x.startswith("syslog")], "Need a file starting with 'syslog'" " in test_data for this test!") self.assertItemsEqual(expected, children) children = [] fd = aff4.FACTORY.Open( output_path.Add("VFSFixture/var/log"), token=self.token) for child in fd.ListChildren(): children.append(child.Basename()) self.assertItemsEqual(children, ["wtmp"])
def _SetupClientImpl(self, client_nr, index=None, arch="x86_64", kernel="4.0.0", os_version="buster/sid", ping=None, system="Linux"): client_id_urn = rdf_client.ClientURN("C.1%015x" % client_nr) with aff4.FACTORY.Create(client_id_urn, aff4_grr.VFSGRRClient, mode="rw", token=self.token) as fd: cert = self.ClientCertFromPrivateKey( config.CONFIG["Client.private_key"]) fd.Set(fd.Schema.CERT, cert) fd.Set(fd.Schema.CLIENT_INFO, self._TestClientInfo()) fd.Set(fd.Schema.PING, ping or rdfvalue.RDFDatetime.Now()) fd.Set(fd.Schema.HOSTNAME("Host-%x" % client_nr)) fd.Set(fd.Schema.FQDN("Host-%x.example.com" % client_nr)) fd.Set( fd.Schema.MAC_ADDRESS("aabbccddee%02x\nbbccddeeff%02x" % (client_nr, client_nr))) fd.Set( fd.Schema.HOST_IPS("192.168.0.%d\n2001:abcd::%x" % (client_nr, client_nr))) if system: fd.Set(fd.Schema.SYSTEM(system)) if os_version: fd.Set(fd.Schema.OS_VERSION(os_version)) if arch: fd.Set(fd.Schema.ARCH(arch)) if kernel: fd.Set(fd.Schema.KERNEL(kernel)) kb = rdf_client.KnowledgeBase() kb.fqdn = "Host-%x.example.com" % client_nr kb.users = [ rdf_client.User(username="******"), rdf_client.User(username="******"), ] artifact.SetCoreGRRKnowledgeBaseValues(kb, fd) fd.Set(fd.Schema.KNOWLEDGE_BASE, kb) fd.Set(fd.Schema.INTERFACES(self._TestInterfaces(client_nr))) hardware_info = fd.Schema.HARDWARE_INFO() hardware_info.system_manufacturer = ("System-Manufacturer-%x" % client_nr) hardware_info.bios_version = ("Bios-Version-%x" % client_nr) fd.Set(fd.Schema.HARDWARE_INFO, hardware_info) fd.Flush() index.AddClient(fd) return client_id_urn
def _CreateClients(self): # To test all search keywords, we can rely on SetupClients # creating clients with attributes containing a numberic # value, e.g. hostname will be Host-0, Host-1, etc. self.client_ids = self.SetupClients(5) # SetupClients adds no labels or user names. with aff4.FACTORY.Open(self.client_ids[0], mode="rw", token=self.token) as client_obj: client_obj.AddLabel("common_test_label", owner=self.token.username) client_obj.AddLabel("unique_test_label", owner=self.token.username) # Add user in knowledge base. kb = client_obj.Get(client_obj.Schema.KNOWLEDGE_BASE) kb.users.Append(rdf_client.User(username="******")) kb.users.Append(rdf_client.User(username=self.token.username)) client_obj.Set(client_obj.Schema.KNOWLEDGE_BASE, kb) # Update index, since we added users and labels. self._UpdateClientIndex(client_obj) with aff4.FACTORY.Open(self.client_ids[1], mode="rw", token=self.token) as client_obj: client_obj.AddLabel("common_test_label", owner=self.token.username) self._UpdateClientIndex(client_obj)
def testUserMergeLinux(self): """Check Linux users are accurately merged.""" kb = rdf_client.KnowledgeBase() self.assertEqual(len(kb.users), 0) kb.MergeOrAddUser(rdf_client.User(username="******", last_logon=1111)) self.assertEqual(len(kb.users), 1) # This should merge since the username is the same. kb.MergeOrAddUser(rdf_client.User(uid="12", username="******")) self.assertEqual(len(kb.users), 1) # This should create a new record because the uid is different kb.MergeOrAddUser( rdf_client.User(username="******", uid="13", desktop="/home/blake/Desktop")) self.assertEqual(len(kb.users), 2) kb.MergeOrAddUser( rdf_client.User(username="******", uid="14", desktop="/home/blake/Desktop")) self.assertEqual(len(kb.users), 3) # Check merging where we don't specify uid works new_attrs, conflicts = kb.MergeOrAddUser( rdf_client.User(username="******", desktop="/home/blakey/Desktop")) self.assertEqual(len(kb.users), 3) self.assertItemsEqual(new_attrs, ["users.username", "users.desktop"]) self.assertItemsEqual( conflicts, [("desktop", u"/home/blake/Desktop", u"/home/blakey/Desktop")])
def SetupTestClientObject(self, client_nr, add_cert=True, arch="x86_64", last_boot_time=None, fqdn=None, kernel="4.0.0", memory_size=None, os_version="buster/sid", ping=None, system="Linux", labels=None): """Prepares a test client object.""" client_id = "C.1%015x" % client_nr client = objects.ClientSnapshot(client_id=client_id) client.startup_info.client_info = self._TestClientInfo() if last_boot_time is not None: client.startup_info.boot_time = last_boot_time client.knowledge_base.fqdn = fqdn or "Host-%x.example.com" % client_nr client.knowledge_base.os = system client.knowledge_base.users = [ rdf_client.User(username="******"), rdf_client.User(username="******"), ] client.os_version = os_version client.arch = arch client.kernel = kernel client.interfaces = self._TestInterfaces(client_nr) client.hardware_info = rdf_client.HardwareInfo( system_manufacturer="System-Manufacturer-%x" % client_nr, bios_version="Bios-Version-%x" % client_nr) if memory_size is not None: client.memory_size = memory_size ping = ping or rdfvalue.RDFDatetime.Now() if add_cert: cert = self.ClientCertFromPrivateKey( config.CONFIG["Client.private_key"]) else: cert = None data_store.REL_DB.WriteClientMetadata(client_id, last_ping=ping, certificate=cert, fleetspeak_enabled=False) data_store.REL_DB.WriteClientSnapshot(client) client_index.ClientIndex().AddClient(client) if labels: data_store.REL_DB.AddClientLabels(client_id, "GRR", labels) client_index.ClientIndex().AddClientLabels( client_id, data_store.REL_DB.ReadClientLabels(client_id)) return client
def testPathInterpolation(self): self.client_id = self.SetupClient(0) bar = rdf_client.User(username="******") baz = rdf_client.User(username="******") kb = rdf_client.KnowledgeBase(os="foo", domain="norf", users=[bar, baz]) client = aff4.FACTORY.Open(self.client_id, token=self.token, mode="rw") with client: client.Set(client.Schema.KNOWLEDGE_BASE, kb) with test_lib.AutoTempDirPath(remove_non_empty=True) as temp_dirpath: self._Touch(os.path.join(temp_dirpath, "foo", "bar")) self._Touch(os.path.join(temp_dirpath, "foo", "baz")) self._Touch(os.path.join(temp_dirpath, "foo", "quux")) self._Touch(os.path.join(temp_dirpath, "thud", "norf", "plugh")) self._Touch(os.path.join(temp_dirpath, "thud", "norf", "blargh")) paths = [ os.path.join(temp_dirpath, "%%os%%", "%%users.username%%"), os.path.join(temp_dirpath, "thud", "%%domain%%", "plugh"), ] action = rdf_file_finder.FileFinderAction.Action.STAT results = self._RunCFF(paths, action) paths = [result.stat_entry.pathspec.path for result in results] self.assertItemsEqual(paths, [ os.path.join(temp_dirpath, "foo", "bar"), os.path.join(temp_dirpath, "foo", "baz"), os.path.join(temp_dirpath, "thud", "norf", "plugh") ])
def testUserMergeWindows(self): """Check Windows users are accurately merged.""" kb = rdf_client.KnowledgeBase() self.assertEqual(len(kb.users), 0) kb.MergeOrAddUser(rdf_client.User(sid="1234")) self.assertEqual(len(kb.users), 1) kb.MergeOrAddUser(rdf_client.User(sid="5678", username="******")) self.assertEqual(len(kb.users), 2) _, conflicts = kb.MergeOrAddUser( rdf_client.User(sid="5678", username="******")) self.assertEqual(len(kb.users), 2) self.assertEqual(conflicts[0], ("username", "test1", "test2")) self.assertEqual(kb.GetUser(sid="5678").username, "test2") # This should merge on user name as we have no other data. kb.MergeOrAddUser(rdf_client.User(username="******", homedir="a")) self.assertEqual(len(kb.users), 2) # This should create a new user since the sid is different. new_attrs, conflicts = kb.MergeOrAddUser( rdf_client.User(username="******", sid="12345", temp="/blah")) self.assertEqual(len(kb.users), 3) self.assertItemsEqual(new_attrs, ["users.username", "users.temp", "users.sid"]) self.assertEqual(conflicts, [])
def testInterpolation(self): """Check we can interpolate values from the knowledge base.""" kb = rdf_client.KnowledgeBase() # No users yet, this should raise self.assertRaises( artifact_utils.KnowledgeBaseInterpolationError, list, artifact_utils.InterpolateKbAttributes( "test%%users.username%%test", kb)) # Now we have two users kb.users.Append(rdf_client.User(username="******", uid=1)) kb.users.Append(rdf_client.User(username="******", uid=2)) kb.Set("environ_allusersprofile", "c:\\programdata") paths = artifact_utils.InterpolateKbAttributes( "test%%users.username%%test", kb) paths = list(paths) self.assertEqual(len(paths), 2) self.assertItemsEqual(paths, ["testjoetest", "testjimtest"]) paths = artifact_utils.InterpolateKbAttributes( "%%environ_allusersprofile%%\\a", kb) self.assertEqual(list(paths), ["c:\\programdata\\a"]) # Check a bad attribute raises self.assertRaises( artifact_utils.KnowledgeBaseInterpolationError, list, artifact_utils.InterpolateKbAttributes("%%nonexistent%%\\a", kb)) # Empty values should also raise kb.Set("environ_allusersprofile", "") self.assertRaises( artifact_utils.KnowledgeBaseInterpolationError, list, artifact_utils.InterpolateKbAttributes( "%%environ_allusersprofile%%\\a", kb)) # No users have temp defined, so this should raise self.assertRaises( artifact_utils.KnowledgeBaseInterpolationError, list, artifact_utils.InterpolateKbAttributes("%%users.temp%%\\a", kb)) # One user has users.temp defined, the others do not. This is common on # windows where users have been created but have never logged in. We should # get just one value back. kb.users.Append( rdf_client.User(username="******", uid=1, temp="C:\\Users\\jason\\AppData\\Local\\Temp")) paths = artifact_utils.InterpolateKbAttributes(r"%%users.temp%%\abcd", kb) self.assertItemsEqual(paths, ["C:\\Users\\jason\\AppData\\Local\\Temp\\abcd"])
def testCompatibility(self): proto = knowledge_base_pb2.User(username="******") proto.desktop = "User Desktop 1" serialized = proto.SerializeToString() rdf_from_serialized = rdf_client.User(serialized) self.assertEqual(rdf_from_serialized.username, proto.username) self.assertEqual(rdf_from_serialized.desktop, proto.desktop) rdf_direct = rdf_client.User(username="******", desktop="User Desktop 1") self.assertRDFValuesEqual(rdf_from_serialized, rdf_direct)
def ParseMultiple(self, stats, knowledge_base): """Parse each returned registry value.""" user_dict = {} for stat in stats: sid_str = stat.pathspec.path.split("/", 3)[2] if SID_RE.match(sid_str): if sid_str not in user_dict: user_dict[sid_str] = rdf_client.User(sid=sid_str) if stat.registry_data.GetValue(): # Look up in the mapping if we can use this entry to populate a user # attribute, and if so, set it. reg_key_name = stat.pathspec.Dirname().Basename() if reg_key_name in self.key_var_mapping: map_dict = self.key_var_mapping[reg_key_name] reg_key = stat.pathspec.Basename() kb_attr = map_dict.get(reg_key) if kb_attr: value = artifact_utils.ExpandWindowsEnvironmentVariables( stat.registry_data.GetValue(), knowledge_base) value = artifact_utils.ExpandWindowsUserEnvironmentVariables( value, knowledge_base, sid=sid_str) user_dict[sid_str].Set(kb_attr, value) # Now yield each user we found. return user_dict.itervalues()
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")) kb = self.client.Get(self.client.Schema.KNOWLEDGE_BASE) kb.MergeOrAddUser( rdf_client.User(username="******", full_name="test user", homedir="/home/test/", last_logon=250)) self.client.Set(kb) self.client.Close() self.client_mock = action_mocks.FileFinderClientMock() # 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
def setUp(self): """Make sure things are initialized.""" super(ArtifactFlowLinuxTest, self).setUp() with aff4.FACTORY.Open( self.SetupClients(1, system="Linux", os_version="12.04")[0], mode="rw", token=self.token) as fd: # Add some users kb = fd.Get(fd.Schema.KNOWLEDGE_BASE) kb.MergeOrAddUser(rdf_client.User(username="******")) kb.MergeOrAddUser(rdf_client.User(username="******")) kb.MergeOrAddUser(rdf_client.User(username="******")) fd.Set(kb) self.LoadTestArtifacts()
def Parse(self, stat, knowledge_base): """Parse each returned registry value.""" _ = knowledge_base # Unused. sid_str = stat.pathspec.Dirname().Basename() if SID_RE.match(sid_str): kb_user = rdf_client.User() kb_user.sid = sid_str if stat.pathspec.Basename() == "ProfileImagePath": if stat.resident: # Support old clients. kb_user.homedir = utils.SmartUnicode(stat.resident) else: kb_user.homedir = stat.registry_data.GetValue() kb_user.userprofile = kb_user.homedir try: # Assume username is the last component of the path. This is not # robust, but other user artifacts will override it if there is a # better match. kb_user.username = kb_user.homedir.rsplit("\\", 1)[-1] except IndexError: pass yield kb_user
def Parse(self, stat, file_object, knowledge_base): """Parse the wtmp file.""" _, _ = stat, knowledge_base users = {} wtmp = file_object.read() while wtmp: try: record = UtmpStruct(wtmp) except utils.ParsingError: break wtmp = wtmp[record.size:] # Users only appear for USER_PROCESS events, others are system. if record.ut_type != 7: continue # Lose the null termination record.user = record.user.split("\x00", 1)[0] # Store the latest login time. # TODO(user): remove the 0 here once RDFDatetime can support times # pre-epoch properly. try: users[record.user] = max(users[record.user], record.sec, 0) except KeyError: users[record.user] = record.sec for user, last_login in users.iteritems(): yield rdf_client.User(username=utils.SmartUnicode(user), last_logon=last_login * 1000000)
def Run(self, unused_args): """Enumerates all the users on this system.""" users = self.ParseWtmp() for user, last_login in users.iteritems(): # Lose the null termination username = user.split("\x00", 1)[0] if username: try: pwdict = pwd.getpwnam(username) homedir = pwdict[5] # pw_dir full_name = pwdict[4] # pw_gecos except KeyError: homedir = "" full_name = "" # Somehow the last login time can be < 0. There is no documentation # what this means so we just set it to 0 (the rdfvalue field is # unsigned so we can't send negative values). if last_login < 0: last_login = 0 self.SendReply( rdf_client.User(username=utils.SmartUnicode(username), homedir=utils.SmartUnicode(homedir), full_name=utils.SmartUnicode(full_name), last_logon=last_login * 1000000))
def ParsePasswdEntry(self, line): """Process the passwd entry fields and primary group memberships.""" fields = ("uname", "passwd", "uid", "gid", "fullname", "homedir", "shell") if line: rslt = dict(zip(fields, line.split(":"))) user = self.entry.setdefault(rslt["uname"], rdf_client.User()) user.username = rslt["uname"] user.pw_entry.store = self.GetPwStore(rslt["passwd"]) if user.pw_entry.store == self.base_store: user.pw_entry.hash_type = self.GetHashType(rslt["passwd"]) # If the passwd file contains NIS entries they may not have uid/gid set. if rslt["uid"]: user.uid = int(rslt["uid"]) if rslt["gid"]: user.gid = int(rslt["gid"]) user.homedir = rslt["homedir"] user.shell = rslt["shell"] user.full_name = rslt["fullname"] # Map uid numbers to detect duplicates. uids = self.uids.setdefault(user.uid, set()) uids.add(user.username) # Map primary group memberships to populate memberships. gid = self.gids.setdefault(user.gid, set()) gid.add(user.username)
def testNoApplicableTests(self): """Try to run linux tests on windows.""" install_time = rdfvalue.RDFDatetime().Now() user = "******" userobj = rdf_client.User(username=user) interface = rdf_client.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 = endtoend.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 GetSummary(self): """Gets a client summary object. Returns: rdf_client.ClientSummary """ self.max_age = 0 summary = rdf_client.ClientSummary(client_id=self.urn) summary.system_info.node = self.Get(self.Schema.HOSTNAME) summary.system_info.system = self.Get(self.Schema.SYSTEM) summary.system_info.release = self.Get(self.Schema.OS_RELEASE) summary.system_info.version = str(self.Get(self.Schema.OS_VERSION, "")) summary.system_info.kernel = self.Get(self.Schema.KERNEL) summary.system_info.fqdn = self.Get(self.Schema.FQDN) summary.system_info.machine = self.Get(self.Schema.ARCH) summary.system_info.install_date = self.Get(self.Schema.INSTALL_DATE) # This should be summary.users = self.Get(self.Schema.USER) but older # clients may return serialized users here. users = self.Get(self.Schema.USER) if users: summary.users = [rdf_client.User(u) for u in users] summary.interfaces = self.Get(self.Schema.LAST_INTERFACES) summary.client_info = self.Get(self.Schema.CLIENT_INFO) summary.serial_number = self.Get( self.Schema.HARDWARE_INFO).serial_number summary.timestamp = self.age summary.system_manufacturer = self.Get( self.Schema.HARDWARE_INFO).system_manufacturer return summary
def testRegistryMRU(self): """Test that the MRU discovery flow. Flow is a work in Progress.""" # Mock out the Find client action. client_mock = action_mocks.ActionMock("Find") # Add some user accounts to this client. fd = aff4.FACTORY.Open(self.client_id, mode="rw", token=self.token) kb = fd.Get(fd.Schema.KNOWLEDGE_BASE) kb.users.Append(rdf_client.User( username="******", userdomain="testing-PC", homedir=r"C:\Users\testing", sid="S-1-5-21-2911950750-476812067-" "1487428992-1001")) fd.Set(kb) 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 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[ rdf_paths.PathSpec.PathType.OS] = test_lib.ClientVFSHandlerFixture vfs.VFS_HANDLERS[rdf_paths.PathSpec.PathType. REGISTRY] = test_lib.FakeRegistryVFSHandler # 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( rdf_client.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 Run(self, unused_args): """Enumerates all the users on this system.""" users = self.ParseWtmp() for user, last_login in users.iteritems(): # Lose the null termination username = user.split("\x00", 1)[0] if username: # Somehow the last login time can be < 0. There is no documentation # what this means so we just set it to 0 (the rdfvalue field is # unsigned so we can't send negative values). if last_login < 0: last_login = 0 result = rdf_client.User(username=utils.SmartUnicode(username), last_logon=last_login * 1000000) try: pwdict = pwd.getpwnam(username) result.homedir = utils.SmartUnicode(pwdict.pw_dir) result.full_name = utils.SmartUnicode(pwdict.pw_gecos) result.uid = pwdict.pw_uid result.gid = pwdict.pw_gid result.shell = utils.SmartUnicode(pwdict.pw_shell) except KeyError: pass self.SendReply(result)
def setUp(self): super(TestEndToEndTestFlow, self).setUp() self.SetupClients(1, system="Linux", os_version="14.04", arch="x86_64") install_time = rdfvalue.RDFDatetime.Now() user = "******" userobj = rdf_client.User(username=user) interface = rdf_client.Interface(ifname="eth0") self.client = aff4.FACTORY.Create(self.client_id, aff4_grr.VFSGRRClient, mode="rw", token=self.token, age=aff4.ALL_TIMES) kb = self.client.Get(self.client.Schema.KNOWLEDGE_BASE) kb.users.Append(userobj) self.client.Set(self.client.Schema.HOSTNAME("hostname")) self.client.Set(self.client.Schema.OS_RELEASE("debian")) 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.INSTALL_DATE(install_time)) self.client.Set(self.client.Schema.KNOWLEDGE_BASE(kb)) self.client.Set(self.client.Schema.USERNAMES([user])) self.client.Set(self.client.Schema.INTERFACES([interface])) self.client.Flush() self.client_mock = action_mocks.ListDirectoryClientMock()
def testFindsKeyWithInterpolatedGlobWithoutConditions(self): # Initialize client's knowledge base in order for the interpolation # to work. user = rdf_client.User(sid="S-1-5-20") kb = rdf_client.KnowledgeBase(users=[user]) client_id = self.SetupClient(0) with aff4.FACTORY.Open(client_id, mode="rw", token=self.token) as client: client.Set(client.Schema.KNOWLEDGE_BASE, kb) session_id = self.RunFlow([ "HKEY_USERS/%%users.sid%%/Software/Microsoft/Windows/" "CurrentVersion/*" ]) results = self.GetResults(session_id) self.assertEqual(len(results), 1) key = ("/HKEY_USERS/S-1-5-20/" "Software/Microsoft/Windows/CurrentVersion/Run") self.assertEqual(results[0].stat_entry.AFF4Path(client_id), "aff4:/C.1000000000000000/registry" + key) self.assertEqual(results[0].stat_entry.pathspec.path, key) self.assertEqual(results[0].stat_entry.pathspec.pathtype, rdf_paths.PathSpec.PathType.REGISTRY)
def setUp(self): super(ListVADBinariesTest, self).setUp() self.SetupClients(1, system="Windows", os_version="6.2", arch="AMD64") self.os_overrider = test_lib.VFSOverrider( rdf_paths.PathSpec.PathType.OS, test_lib.ClientVFSHandlerFixture) self.reg_overrider = test_lib.VFSOverrider( rdf_paths.PathSpec.PathType.REGISTRY, test_lib.FakeRegistryVFSHandler) self.os_overrider.Start() self.reg_overrider.Start() # Add some user accounts to this client. fd = aff4.FACTORY.Open(self.client_id, mode="rw", token=self.token) kb = fd.Get(fd.Schema.KNOWLEDGE_BASE) kb.environ_systemdrive = "C:" kb.MergeOrAddUser( rdf_client.User(username="******", userdomain="testing-PC", homedir=r"C:\Users\localservice", sid="S-1-5-20")) fd.Set(kb) 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")) kb = self.client.Get(self.client.Schema.KNOWLEDGE_BASE) kb.MergeOrAddUser(rdf_client.User(username="******", full_name="test user", homedir="/home/test/", last_logon=250)) self.client.Set(kb) 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 testInterpolateArgs(self): collect_flow = collectors.ArtifactCollectorFlow(None, token=self.token) kb = rdf_client.KnowledgeBase() kb.MergeOrAddUser(rdf_client.User(username="******")) kb.MergeOrAddUser(rdf_client.User(username="******")) collect_flow.state["knowledge_base"] = kb collect_flow.current_artifact_name = "blah" collect_flow.args = artifact_utils.ArtifactCollectorFlowArgs() test_rdf = rdf_client.KnowledgeBase() action_args = { "usernames": ["%%users.username%%", "%%users.username%%"], "nointerp": "asdfsdf", "notastring": test_rdf } kwargs = collect_flow.InterpolateDict(action_args) self.assertItemsEqual(kwargs["usernames"], ["test1", "test2", "test1", "test2"]) self.assertEqual(kwargs["nointerp"], "asdfsdf") self.assertEqual(kwargs["notastring"], test_rdf) # We should be using an array since users.username will expand to multiple # values. self.assertRaises(ValueError, collect_flow.InterpolateDict, {"bad": "%%users.username%%"}) list_args = collect_flow.InterpolateList( ["%%users.username%%", r"%%users.username%%\aa"]) self.assertItemsEqual(list_args, ["test1", "test2", r"test1\aa", r"test2\aa"]) list_args = collect_flow.InterpolateList(["one"]) self.assertEqual(list_args, ["one"]) # Ignore the failure in users.desktop, report the others. collect_flow.args.ignore_interpolation_errors = True list_args = collect_flow.InterpolateList( ["%%users.desktop%%", r"%%users.username%%\aa"]) self.assertItemsEqual(list_args, [r"test1\aa", r"test2\aa"]) # Both fail. list_args = collect_flow.InterpolateList( [r"%%users.desktop%%\aa", r"%%users.sid%%\aa"]) self.assertItemsEqual(list_args, [])
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 = rdf_client.User() user_record.special_folders.app_data = "test_data/index.dat" user_attribute.Append(user_record) user_record = rdf_client.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 = rdf_client.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 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 = rdf_client.User(username=user) interface = rdf_client.Interface(ifname="eth0") timestamp = 1 with utils.Stubber(time, "time", lambda: timestamp): with aff4.FACTORY.Create("C.0000000000000000", aff4_grr.VFSGRRClient, mode="rw", token=self.token) as fd: kb = rdf_client.KnowledgeBase() kb.users.Append(userobj) 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.KNOWLEDGE_BASE(kb)) fd.Set(fd.Schema.USERNAMES([user])) fd.Set(fd.Schema.INTERFACES([interface])) with aff4.FACTORY.Open("C.0000000000000000", aff4_grr.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 testAnalyzeClient(self): index = aff4.FACTORY.Create( "aff4:/client-index/", aff4_type=client_index.ClientIndex, mode="rw", token=self.token) test_lib.ClientFixture("aff4:/" + CLIENT_ID, token=self.token) client = aff4.FACTORY.Create( "aff4:/" + CLIENT_ID, aff4_type=aff4_grr.VFSGRRClient, mode="rw", token=self.token) kb = rdf_client.KnowledgeBase() kb.users.Append( rdf_client.User( username="******", full_name="Eric (Bertrand ) 'Russell' \"Logician\" Jacobson")) kb.users.Append( rdf_client.User( username="******", full_name="Steve O'Bryan")) client.Set(client.Schema.KNOWLEDGE_BASE(kb)) _, keywords = index.AnalyzeClient(client) # Should not contain an empty string. self.assertNotIn("", keywords) # OS of the client self.assertIn("windows", keywords) # Users of the client. self.assertIn("bert", keywords) self.assertIn("bertrand", keywords) self.assertNotIn(")", keywords) self.assertIn("russell", keywords) self.assertIn("logician", keywords) self.assertIn("ernie", keywords) self.assertIn("eric", keywords) self.assertIn("jacobson", keywords) self.assertIn("steve o'bryan", keywords) self.assertIn("o'bryan", keywords) # Client information. self.assertIn("grr monitor", keywords) self.assertIn("client-label-23", keywords)