def setUp(self): super(CheckRegistryTests, self).setUp() if self.sw_chk is None: self.sw_chk = self._LoadCheck("sw.yaml", "SW-CHECK") checks.CheckRegistry.RegisterCheck(check=self.sw_chk, source="dpkg.out", overwrite_if_exists=True) if self.sshd_chk is None: self.sshd_chk = self._LoadCheck("sshd.yaml", "SSHD-CHECK") checks.CheckRegistry.RegisterCheck(check=self.sshd_chk, source="sshd_config", overwrite_if_exists=True) if self.sshd_perms is None: self.sshd_perms = self._LoadCheck("sshd.yaml", "SSHD-PERMS") checks.CheckRegistry.RegisterCheck(check=self.sshd_perms, source="sshd_config", overwrite_if_exists=True) self.kb = rdf_client.KnowledgeBase() self.kb.fqdn = "test.example.com" self.host_data = { "KnowledgeBase": self.kb, "WMIInstalledSoftware": GetWMIData(), "DebianPackagesStatus": GetDPKGData(), "SshdConfigFile": GetSSHDConfig() }
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(client_id, [ "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 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 testKnowledgeBaseRootAttributesGetMappedCorrectly(self): kb = rdf_client.KnowledgeBase( environ_path="the_path", environ_temp="the_temp", environ_systemroot="the_systemroot", environ_windir="the_windir", environ_programfiles="the_programfiles", environ_programfilesx86="the_programfilesx86", environ_systemdrive="the_systemdrive", environ_allusersprofile="the_allusersprofile", environ_allusersappdata="the_allusersappdata") mapping = artifact_utils.GetWindowsEnvironmentVariablesMap(kb) self.assertEqual( mapping, { "allusersappdata": "the_allusersappdata", "allusersprofile": "the_allusersprofile", "path": "the_path", "programdata": "the_allusersprofile", "programfiles": "the_programfiles", "programfiles(x86)": "the_programfilesx86", "programw6432": "the_programfiles", "systemdrive": "the_systemdrive", "systemroot": "the_systemroot", "temp": "the_temp", "windir": "the_windir" })
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 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 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 = rdf_artifacts.ArtifactSource( type=rdf_artifacts.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 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 ValidateSyntax(rdf_artifact): """Validates artifact syntax. This method can be used to validate individual artifacts as they are loaded, without needing all artifacts to be loaded first, as for Validate(). Args: rdf_artifact: RDF object artifact. Raises: ArtifactSyntaxError: If artifact syntax is invalid. """ if not rdf_artifact.doc: raise rdf_artifacts.ArtifactSyntaxError(rdf_artifact, "missing doc") for supp_os in rdf_artifact.supported_os: valid_os = rdf_artifact.SUPPORTED_OS_LIST if supp_os not in valid_os: detail = "invalid `supported_os` ('%s' not in %s)" % (supp_os, valid_os) raise rdf_artifacts.ArtifactSyntaxError(rdf_artifact, detail) for condition in rdf_artifact.conditions: # FIXME(hanuszczak): It does not look like the code below can throw # `ConditionException`. Do we really need it then? try: of = objectfilter.Parser(condition).Parse() of.Compile(objectfilter.BaseFilterImplementation) except rdf_artifacts.ConditionError as e: detail = "invalid condition '%s'" % condition raise rdf_artifacts.ArtifactSyntaxError(rdf_artifact, detail, e) for label in rdf_artifact.labels: if label not in rdf_artifact.ARTIFACT_LABELS: raise rdf_artifacts.ArtifactSyntaxError( rdf_artifact, "invalid label '%s'" % label) # Anything listed in provides must be defined in the KnowledgeBase valid_provides = rdf_client.KnowledgeBase().GetKbFieldNames() for kb_var in rdf_artifact.provides: if kb_var not in valid_provides: detail = "broken `provides` ('%s' not in %s)" % (kb_var, valid_provides) raise rdf_artifacts.ArtifactSyntaxError(rdf_artifact, detail) # Any %%blah%% path dependencies must be defined in the KnowledgeBase for dep in GetArtifactPathDependencies(rdf_artifact): if dep not in valid_provides: detail = "broken path dependencies ('%s' not in %s)" % ( dep, valid_provides) raise rdf_artifacts.ArtifactSyntaxError(rdf_artifact, detail) for source in rdf_artifact.sources: try: source.Validate() except rdf_artifacts.ArtifactSourceSyntaxError as e: raise rdf_artifacts.ArtifactSyntaxError(rdf_artifact, "bad source", e)
def SetKnowledgeBase(fqdn="test.example.com", host_os="Linux", host_data=None): """Generates a KnowledgeBase entry in the host_data used by checks.""" if not host_data: host_data = {} host_data["KnowledgeBase"] = rdf_client.KnowledgeBase(fqdn=fqdn, os=host_os) return host_data
def InitializeKnowledgeBase(self): """Get the existing KB or create a new one if none exists.""" self.client = aff4.FACTORY.Open(self.client_id, token=self.token) # Always create a new KB to override any old values. self.state.knowledge_base = rdf_client.KnowledgeBase() SetCoreGRRKnowledgeBaseValues(self.state.knowledge_base, self.client) if not self.state.knowledge_base.os: # If we don't know what OS this is, there is no way to proceed. raise flow.FlowError("Client OS not set for: %s, cannot initialize" " KnowledgeBase" % self.client_id)
def testClientSummary(self): d = self.db client_id_1 = self.InitializeClient() client_id_2 = self.InitializeClient() client_id_3 = self.InitializeClient() d.WriteClientSnapshot( rdf_objects.ClientSnapshot(client_id=client_id_1, knowledge_base=rdf_client.KnowledgeBase( fqdn="test1234.examples.com"), kernel="12.3")) d.WriteClientSnapshot( rdf_objects.ClientSnapshot(client_id=client_id_1, knowledge_base=rdf_client.KnowledgeBase( fqdn="test1234.examples.com"), kernel="12.4")) d.WriteClientSnapshot( rdf_objects.ClientSnapshot(client_id=client_id_2, knowledge_base=rdf_client.KnowledgeBase( fqdn="test1235.examples.com"), kernel="12.4")) hist = d.ReadClientSnapshotHistory(client_id_1) self.assertEqual(len(hist), 2) # client_3 should be excluded - no snapshot yet res = d.MultiReadClientSnapshot( [client_id_1, client_id_2, client_id_3]) self.assertEqual(len(res), 3) self.assertIsInstance(res[client_id_1], rdf_objects.ClientSnapshot) self.assertIsInstance(res[client_id_2], rdf_objects.ClientSnapshot) self.assertIsInstance(res[client_id_1].timestamp, rdfvalue.RDFDatetime) self.assertIsNotNone(res[client_id_2].timestamp) self.assertEqual(res[client_id_1].knowledge_base.fqdn, "test1234.examples.com") self.assertEqual(res[client_id_1].kernel, "12.4") self.assertEqual(res[client_id_2].knowledge_base.fqdn, "test1235.examples.com") self.assertFalse(res[client_id_3])
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 testKnowledgeBase(self): """Test that the knowledge base is passed in the bundle.""" artifact_collector = collectors.ClientArtifactCollector(None) artifact_collector.args = artifact_utils.ArtifactCollectorFlowArgs() kb = rdf_client.KnowledgeBase() kb.os = "Windows" artifact_collector.args.knowledge_base = kb artifact_bundle = artifact_collector._GetArtifactCollectorArgs([]) self.assertEqual(artifact_bundle.knowledge_base.os, "Windows")
def testBasicParsing(self): ps_list_file = os.path.join(config.CONFIG["Test.data_dir"], "rekall_vad_result.dat.gz") result = rdf_rekall_types.RekallResponse( json_messages=gzip.open(ps_list_file, "rb").read(), plugin="pslist") knowledge_base = rdf_client.KnowledgeBase() knowledge_base.environ_systemdrive = "C:" parser = rekall_artifact_parser.RekallVADParser() parsed_pathspecs = list(parser.Parse(result, knowledge_base)) paths = [p.path for p in parsed_pathspecs] self.assertIn(u"C:\\Windows\\System32\\spoolsv.exe", paths)
def _SetupFullInfoClients(self): for i in range(10): client_id = self.InitializeClient("C.000000005000000%d" % i) cl = rdf_objects.ClientSnapshot( client_id=client_id, knowledge_base=rdf_client.KnowledgeBase( fqdn="test%d.examples.com" % i), kernel="12.3.%d" % i) self.db.WriteClientSnapshot(cl) self.db.WriteClientMetadata(client_id, certificate=CERT) si = rdf_client.StartupInfo(boot_time=i) self.db.WriteClientStartupInfo(client_id, si) self.db.AddClientLabels( client_id, "test_owner", ["test_label-a-%d" % i, "test_label-b-%d" % i])
def testParse(self): parser = windows_persistence.WindowsPersistenceMechanismsParser() path = (r"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion" r"\Run\test") pathspec = rdf_paths.PathSpec( path=path, pathtype=rdf_paths.PathSpec.PathType.REGISTRY) reg_data = "C:\\blah\\some.exe /v" reg_type = rdf_client.StatEntry.RegistryType.REG_SZ stat = rdf_client.StatEntry( pathspec=pathspec, registry_type=reg_type, registry_data=rdf_protodict.DataBlob(string=reg_data)) persistence = [stat] image_paths = [ "system32\\drivers\\ACPI.sys", "%systemroot%\\system32\\svchost.exe -k netsvcs", "\\SystemRoot\\system32\\drivers\\acpipmi.sys" ] reg_key = "HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/services/AcpiPmi" for path in image_paths: serv_info = rdf_client.WindowsServiceInformation( name="blah", display_name="GRRservice", image_path=path, registry_key=reg_key) persistence.append(serv_info) knowledge_base = rdf_client.KnowledgeBase() knowledge_base.environ_systemroot = "C:\\Windows" expected = [ "C:\\blah\\some.exe", "C:\\Windows\\system32\\drivers\\ACPI.sys", "C:\\Windows\\system32\\svchost.exe", "C:\\Windows\\system32\\drivers\\acpipmi.sys" ] for index, item in enumerate(persistence): results = list( parser.Parse(item, knowledge_base, rdf_paths.PathSpec.PathType.OS)) self.assertEqual(results[0].pathspec.path, expected[index]) self.assertEqual(len(results), 1)
def testGetKBDependencies(self): """Test that KB dependencies are calculated correctly.""" artifact_registry.REGISTRY.ClearSources() try: test_artifacts_file = os.path.join(config.CONFIG["Test.data_dir"], "artifacts", "test_artifacts.json") artifact_registry.REGISTRY.AddFileSource(test_artifacts_file) with test_lib.ConfigOverrider({ "Artifacts.knowledge_base": [ "DepsParent", "DepsDesktop", "DepsHomedir", "DepsWindir", "DepsWindirRegex", "DepsControlSet", "FakeArtifact" ], "Artifacts.knowledge_base_additions": ["DepsHomedir2"], "Artifacts.knowledge_base_skip": ["DepsWindir"], "Artifacts.knowledge_base_heavyweight": ["FakeArtifact"] }): args = artifact.KnowledgeBaseInitializationArgs( lightweight=True) kb_init = artifact.KnowledgeBaseInitializationFlow( None, token=self.token) kb_init.args = args kb_init.state["all_deps"] = set() kb_init.state["awaiting_deps_artifacts"] = [] kb_init.state["knowledge_base"] = rdf_client.KnowledgeBase( os="Windows") no_deps = kb_init.GetFirstFlowsForCollection() self.assertItemsEqual(no_deps, ["DepsControlSet", "DepsHomedir2"]) self.assertItemsEqual(kb_init.state.all_deps, [ "users.homedir", "users.desktop", "users.username", "environ_windir", "current_control_set" ]) self.assertItemsEqual(kb_init.state.awaiting_deps_artifacts, [ "DepsParent", "DepsDesktop", "DepsHomedir", "DepsWindirRegex" ]) finally: artifact.ArtifactLoader().RunOnce()
def testAnalyzeClient(self): index = client_index.CreateClientIndex(token=self.token) client = aff4.FACTORY.Create("aff4:/" + CLIENT_ID, aff4_type=aff4_grr.VFSGRRClient, mode="rw", token=self.token) client.Set(client.Schema.SYSTEM("Windows")) client.Set( client.Schema.CLIENT_INFO(client_name="grr monitor", labels=["client-label-23"])) 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)
def testKnowlegeBaseUsersAttributesExpandIntoLists(self): kb = rdf_client.KnowledgeBase() kb.users.append( rdf_client.User(appdata="the_appdata_1", localappdata="the_localappdata_1", userdomain="the_userdomain_1", userprofile="the_userprofile_1")) kb.users.append( rdf_client.User(appdata="the_appdata_2", localappdata="the_localappdata_2", userdomain="the_userdomain_2", userprofile="the_userprofile_2")) mapping = artifact_utils.GetWindowsEnvironmentVariablesMap(kb) self.assertEqual( mapping, { "appdata": ["the_appdata_1", "the_appdata_2"], "localappdata": ["the_localappdata_1", "the_localappdata_2"], "userdomain": ["the_userdomain_1", "the_userdomain_2"], "userprofile": ["the_userprofile_1", "the_userprofile_2"] })
def testSourceMeetsConditions(self): """Test we can get a GRR client artifact with conditions.""" artifact_collector = collectors.ClientArtifactCollector(None) artifact_collector.args = artifact_utils.ArtifactCollectorFlowArgs() kb = rdf_client.KnowledgeBase() kb.os = "Windows" artifact_collector.args.knowledge_base = kb # Run with false condition. source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}, conditions=["os == 'Linux'"]) self.assertFalse(artifact_collector._MeetsConditions(source)) # Run with matching or condition. source = rdf_artifacts.ArtifactSource( type=rdf_artifacts.ArtifactSource.SourceType.GRR_CLIENT_ACTION, attributes={"client_action": standard.ListProcesses.__name__}, conditions=["os == 'Linux' or os == 'Windows'"]) self.assertTrue(artifact_collector._MeetsConditions(source))
def testReadClientFullInfoReturnsCorrectResult(self): d = self.db client_id = self.InitializeClient() cl = rdf_objects.ClientSnapshot( client_id=client_id, knowledge_base=rdf_client.KnowledgeBase( fqdn="test1234.examples.com"), kernel="12.3") d.WriteClientSnapshot(cl) d.WriteClientMetadata(client_id, certificate=CERT) si = rdf_client.StartupInfo(boot_time=1) d.WriteClientStartupInfo(client_id, si) d.AddClientLabels(client_id, "test_owner", ["test_label"]) full_info = d.ReadClientFullInfo(client_id) self.assertEqual(full_info.last_snapshot, cl) self.assertEqual(full_info.metadata.certificate, CERT) self.assertEqual(full_info.last_startup_info, si) self.assertEqual( full_info.labels, [rdf_objects.ClientLabel(owner="test_owner", name="test_label")])
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") google_cloud_instance = rdf_cloud.GoogleCloudInstance( instance_id="1771384456894610289", zone="projects/123456789733/zones/us-central1-a", project_id="myproject", unique_id="us-central1-a/myproject/1771384456894610289") cloud_instance = rdf_cloud.CloudInstance( cloud_type="GOOGLE", google=google_cloud_instance) serial_number = "DSD33679FZ" system_manufacturer = "Foobar Inc." system_uuid = "C31292AD-6Z4F-55D8-28AC-EC1100E42222" hwinfo = rdf_client.HardwareInfo( serial_number=serial_number, system_manufacturer=system_manufacturer, system_uuid=system_uuid) 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.AsSecondsSinceEpoch(), 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.HARDWARE_INFO(hwinfo)) fd.Set(fd.Schema.INTERFACES([interface])) fd.Set(fd.Schema.CLOUD_INSTANCE(cloud_instance)) with aff4.FACTORY.Open( "C.0000000000000000", aff4_grr.VFSGRRClient, mode="rw", token=self.token) as fd: summary = fd.GetSummary() 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.AsSecondsSinceEpoch(), 101) self.assertEqual(summary.cloud_type, "GOOGLE") self.assertEqual(summary.cloud_instance_id, "us-central1-a/myproject/1771384456894610289") self.assertEqual(summary.serial_number, serial_number) self.assertEqual(summary.system_manufacturer, system_manufacturer) self.assertEqual(summary.system_uuid, system_uuid)
def CreateClientObject(self, vfs_fixture): """Make a new client object.""" # First remove the old fixture just in case its still there. aff4.FACTORY.Delete(self.client_id, token=self.token) # Create the fixture at a fixed time. with test_lib.FakeTime(self.age): for path, (aff4_type, attributes) in vfs_fixture: path %= self.args aff4_object = aff4.FACTORY.Create(self.client_id.Add(path), aff4_type, mode="rw", token=self.token) if data_store.RelationalDBWriteEnabled(): data_store.REL_DB.WriteClientMetadata( self.client_id.Basename(), fleetspeak_enabled=False) components = [ component for component in path.split("/") if component ] if components[0:2] == ["fs", "os"]: path_info = rdf_objects.PathInfo() path_info.path_type = rdf_objects.PathInfo.PathType.OS path_info.components = components[2:] if aff4_type in [ aff4_grr.VFSFile, aff4_grr.VFSMemoryFile ]: path_info.directory = False elif aff4_type == aff4_standard.VFSDirectory: path_info.directory = True else: raise ValueError("Incorrect AFF4 type: %s" % aff4_type) data_store.REL_DB.WritePathInfos( client_id=self.client_id.Basename(), path_infos=[path_info]) for attribute_name, value in attributes.items(): attribute = aff4.Attribute.PREDICATES[attribute_name] if isinstance(value, (str, unicode)): # Interpolate the value value %= self.args # Is this supposed to be an RDFValue array? if aff4.issubclass(attribute.attribute_type, rdf_protodict.RDFValueArray): rdfvalue_object = attribute() for item in value: new_object = rdfvalue_object.rdf_type.FromTextFormat( utils.SmartStr(item)) rdfvalue_object.Append(new_object) # It is a text serialized protobuf. elif aff4.issubclass(attribute.attribute_type, rdf_structs.RDFProtoStruct): # Use the alternate constructor - we always write protobufs in # textual form: rdfvalue_object = attribute.attribute_type.FromTextFormat( utils.SmartStr(value)) elif aff4.issubclass(attribute.attribute_type, rdfvalue.RDFInteger): rdfvalue_object = attribute(int(value)) else: rdfvalue_object = attribute(value) # If we don't already have a pathspec, try and get one from the stat. if aff4_object.Get(aff4_object.Schema.PATHSPEC) is None: # If the attribute was a stat, it has a pathspec nested in it. # We should add that pathspec as an attribute. if attribute.attribute_type == rdf_client.StatEntry: stat_object = attribute.attribute_type.FromTextFormat( utils.SmartStr(value)) if stat_object.pathspec: pathspec_attribute = aff4.Attribute( "aff4:pathspec", rdf_paths.PathSpec, "The pathspec used to retrieve " "this object from the client.", "pathspec") aff4_object.AddAttribute( pathspec_attribute, stat_object.pathspec) if attribute in ["aff4:content", "aff4:content"]: # For AFF4MemoryStreams we need to call Write() instead of # directly setting the contents.. aff4_object.Write(rdfvalue_object) else: aff4_object.AddAttribute(attribute, rdfvalue_object) if (isinstance(rdfvalue_object, rdf_client.StatEntry) and rdfvalue_object.pathspec.pathtype != "UNSET"): if data_store.RelationalDBWriteEnabled(): client_id = self.client_id.Basename() path_info = rdf_objects.PathInfo.FromStatEntry( rdfvalue_object) data_store.REL_DB.WritePathInfos( client_id, [path_info]) # Populate the KB from the client attributes. if aff4_type == aff4_grr.VFSGRRClient: kb = rdf_client.KnowledgeBase() artifact.SetCoreGRRKnowledgeBaseValues(kb, aff4_object) aff4_object.Set(aff4_object.Schema.KNOWLEDGE_BASE, kb) # Make sure we do not actually close the object here - we only want to # sync back its attributes, not run any finalization code. aff4_object.Flush() if aff4_type == aff4_grr.VFSGRRClient: index = client_index.CreateClientIndex(token=self.token) index.AddClient(aff4_object)
def _SetupClientImpl(self, client_nr, index=None, arch="x86_64", install_time=None, last_boot_time=None, kernel="4.0.0", os_version="buster/sid", ping=None, system="Linux", memory_size=None, add_cert=True): 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: if add_cert: 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)) if memory_size: fd.Set(fd.Schema.MEMORY_SIZE(memory_size)) if last_boot_time: fd.Set(fd.Schema.LAST_BOOT_TIME(last_boot_time)) if install_time: fd.Set(fd.Schema.INSTALL_DATE(install_time)) 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 Handle(self, args, token=None): fields = rdf_client.KnowledgeBase().GetKbFieldNames() return ApiListKbFieldsResult(items=sorted(fields))