def Parse(self, stat, unused_knowledge_base): """Parse the key currentcontrolset output.""" value = stat.registry_data.GetValue() if not str(value).isdigit() or int(value) > 999 or int(value) < 0: raise parsers.ParseError( "Invalid value for CurrentControlSet key %s" % value) yield rdfvalue.RDFString("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet%03d" % int(value))
def testCorrectlyExportsTwoValuesOfTheSameType(self): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString("foo"), source=self.client_id)) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString("bar"), source=self.client_id)) chunks = self.ProcessPlugin() self.assertListEqual(chunks, [ "Start: aff4:/foo/bar", "Values of type: RDFString", "First pass: foo (source=%s)" % self.client_id, "First pass: bar (source=%s)" % self.client_id, "Second pass: foo (source=%s)" % self.client_id, "Second pass: bar (source=%s)" % self.client_id, "Finish: aff4:/foo/bar" ]) # pyformat: disable
def testValuesOfMultipleTypesCanBeIteratedTogether(self): with self.pool: original_values = set() for i in range(100): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i)), mutation_pool=self.pool) original_values.add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i))) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i)), mutation_pool=self.pool) original_values.add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i))) self.assertEqual(sorted([v.payload for v in original_values]), sorted([v.payload for v in self.collection]))
def Parse(self, stat, knowledge_base): """Expand any variables in the value.""" value = stat.registry_data.GetValue() if not value: raise parsers.ParseError("Invalid value for key %s" % stat.pathspec.path) value = artifact_utils.ExpandWindowsEnvironmentVariables( value, knowledge_base) if value: yield rdfvalue.RDFString(value)
def testDeletingCollectionDeletesAllSubcollections(self): self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(0))) self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFString("foo"))) self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFURN( "aff4:/foo/bar"))) aff4.FACTORY.Delete(self.collection.urn, token=self.token) for urn in data_store.DB.subjects.keys(): self.assertFalse(utils.SmartStr(self.collection.urn) in urn)
def testExtractsTypesFromGrrMessage(self): self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(0))) self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFString("foo"))) self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFURN( "aff4:/foo/bar"))) self.assertEqual( set([rdfvalue.RDFInteger.__name__, rdfvalue.RDFString.__name__, rdfvalue.RDFURN.__name__]), set(self.collection.ListStoredTypes()))
def ReceiveHello(self, responses): if responses.First() != "Hello": raise RuntimeError("Did not receive hello.") DelayedCallStateFlow.flow_ran = 1 # Call the child flow. self.CallState([rdfvalue.RDFString("Hello")], next_state="DelayedHello", start_time=rdfvalue.RDFDatetime.Now() + 100)
def Parse(self, stat, knowledge_base): """Convert the timezone to Olson format.""" _ = knowledge_base value = stat.registry_data.GetValue() result = ZONE_LIST.get(value.strip()) if not result: raise parsers.ParseError( "Unknown value for TimeZoneKeyName key %s" % value) yield rdfvalue.RDFString(result)
def Parse(self, stat, knowledge_base): """Parse the key currentcontrolset output.""" value = stat.registry_data.GetValue() if not value: raise parsers.ParseError("Invalid value for key %s" % stat.pathspec.path) value = artifact_lib.ExpandWindowsEnvironmentVariables( value, knowledge_base) if value: yield rdfvalue.RDFString(value)
def testAddGet(self): with aff4.FACTORY.Create("aff4:/sequential_collection/test5", "GeneralIndexedCollection", token=self.token) as collection: collection.Add(rdfvalue.RDFInteger(42)) collection.Add(rdfvalue.RDFString("the meaning of life")) self.assertEqual(collection[0].__class__, rdfvalue.RDFInteger) self.assertEqual(collection[0], 42) self.assertEqual(collection[1].__class__, rdfvalue.RDFString) self.assertEqual(collection[1], "the meaning of life")
def testAddGet(self): collection = sequential_collection.GeneralIndexedCollection( rdfvalue.RDFURN("aff4:/sequential_collection/testAddGetIndexed"), token=self.token) collection.Add(rdfvalue.RDFInteger(42)) collection.Add(rdfvalue.RDFString("the meaning of life")) self.assertEqual(collection[0].__class__, rdfvalue.RDFInteger) self.assertEqual(collection[0], 42) self.assertEqual(collection[1].__class__, rdfvalue.RDFString) self.assertEqual(collection[1], "the meaning of life")
def testIPInfo(self): for ip, result in [ ("", utils.IPInfo.UNKNOWN), ("192.168.0.1", utils.IPInfo.INTERNAL), ("10.0.0.7", utils.IPInfo.INTERNAL), ("69.50.225.155", utils.IPInfo.EXTERNAL), ]: rdf_ip = rdfvalue.RDFString(ip) info, _ = utils.RetrieveIPInfo(rdf_ip) self.assertEqual(info, result)
def testLengthOfCollectionIsCorrectWhenMultipleTypesAreUsed(self): with self.pool: for i in range(100): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i)), mutation_pool=self.pool) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i)), mutation_pool=self.pool) self.assertEqual(200, len(self.collection))
def testLengthIsReportedCorrectlyForEveryType(self): for i in range(99): self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i))) for i in range(101): self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i))) self.assertEqual(99, self.collection.LengthByType(rdfvalue.RDFInteger.__name__)) self.assertEqual(101, self.collection.LengthByType(rdfvalue.RDFString.__name__))
def testAddGet(self): collection = sequential_collection.GeneralIndexedCollection( rdfvalue.RDFURN("aff4:/sequential_collection/testAddGetIndexed")) with data_store.DB.GetMutationPool() as pool: collection.Add(rdfvalue.RDFInteger(42), mutation_pool=pool) collection.Add(rdfvalue.RDFString("the meaning of life"), mutation_pool=pool) self.assertEqual(collection[0].__class__, rdfvalue.RDFInteger) self.assertEqual(collection[0], 42) self.assertEqual(collection[1].__class__, rdfvalue.RDFString) self.assertEqual(collection[1], "the meaning of life")
def testDeletingCollectionDeletesAllSubcollections(self): if not isinstance(data_store.DB, fake_data_store.FakeDataStore): self.skipTest("Only supported on FakeDataStore.") self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(0))) self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFString("foo"))) self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFURN("aff4:/foo/bar"))) self.collection.Delete() for urn in data_store.DB.subjects.keys(): self.assertFalse(utils.SmartStr(self.collection.collection_id) in urn)
def Parse(self, stat, _): """Parse the key currentcontrolset output.""" value = stat.registry_data.GetValue() if not value: raise parsers.ParseError("Invalid value for key %s" % stat.pathspec.path) systemdrive = value[0:2] if re.match(r"^[A-Za-z]:$", systemdrive): yield rdfvalue.RDFString(systemdrive) else: raise parsers.ParseError( "Bad drive letter for key %s" % stat.pathspec.path)
def testValuesOfMultipleTypesCanBeIteratedPerType(self): for i in range(100): self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFInteger(i))) self.collection.Add(rdf_flows.GrrMessage(payload=rdfvalue.RDFString(i))) for index, (_, v) in enumerate( self.collection.ScanByType(rdfvalue.RDFInteger.__name__)): self.assertEqual(index, v.payload) for index, (_, v) in enumerate( self.collection.ScanByType(rdfvalue.RDFString.__name__)): self.assertEqual(str(index), v.payload)
def Run(self): hunt_urn = rdfvalue.RDFURN("aff4:/hunts/H:123456") results_urn = hunt_urn.Add("Results") with aff4.FACTORY.Create(results_urn, aff4_type=hunt_results.HuntResultCollection, token=self.token) as results: result = rdf_flows.GrrMessage( payload=rdfvalue.RDFString("blah1"), age=rdfvalue.RDFDatetime().FromSecondsFromEpoch(1)) results.Add(result, timestamp=result.age + rdfvalue.Duration("1s")) result = rdf_flows.GrrMessage( payload=rdfvalue.RDFString("blah2-foo"), age=rdfvalue.RDFDatetime().FromSecondsFromEpoch(42)) results.Add(result, timestamp=result.age + rdfvalue.Duration("1s")) self.Check("GET", "/api/hunts/H:123456/results") self.Check("GET", "/api/hunts/H:123456/results?count=1") self.Check("GET", "/api/hunts/H:123456/results?offset=1&count=1") self.Check("GET", "/api/hunts/H:123456/results?filter=foo")
def testDynamicAnyValueTypeWithPrimitiveValues(self): test_pb = DynamicAnyValueTypeTest(type="RDFString") # We can not assign arbitrary values to the dynamic field. self.assertRaises(ValueError, setattr, test_pb, "dynamic", 42) # Can assign a nested field. test_pb.dynamic = rdfvalue.RDFString("Hello") self.assertTrue(isinstance(test_pb.dynamic, rdfvalue.RDFString)) # Test serialization/deserialization. serialized = test_pb.SerializeToString() unserialized = DynamicAnyValueTypeTest.FromSerializedString(serialized) self.assertEqual(unserialized, test_pb) self.assertEqual(unserialized.dynamic, "Hello")
def testCorrectlyExportsSingleValue(self): with self.pool: self.collection.Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo"), source=self.client_id), mutation_pool=self.pool) chunks = self.ProcessPlugin() self.assertListEqual(chunks, [ "Start: aff4:/foo/bar", "Values of type: RDFString", "First pass: foo (source=%s)" % self.client_id, "Second pass: foo (source=%s)" % self.client_id, "Finish: aff4:/foo/bar" ]) # pyformat: disable
def testUsesDefaultClientURNIfGrrMessageHasNoSource(self): self.collection.Add( rdf_flows.GrrMessage(payload=rdfvalue.RDFString("foo"), source=None)) chunks = self.ProcessPlugin( source_urn=rdf_client.ClientURN("C.1111222233334444")) self.assertListEqual(chunks, [ "Start: aff4:/foo/bar", "Values of type: RDFString", "First pass: foo (source=aff4:/C.1111222233334444)", "Second pass: foo (source=aff4:/C.1111222233334444)", "Finish: aff4:/foo/bar" ]) # pyformat: disable
def _FillInStubResults(self): results = implementation.GRRHunt.ResultCollectionForHID( self.hunt.urn, token=self.token) result = results[0] for i in range(self.handler.MAX_RECORDS_TO_CHECK): wrong_result = rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo/bar"), age=(result.age - (self.handler.MAX_RECORDS_TO_CHECK - i + 1) * rdfvalue.Duration("1s")), source=self.client_id) results.Add(wrong_result, timestamp=wrong_result.age) return result
def ParseMultiple(self, stats, knowledge_base): """Parse each returned registry variable.""" prof_directory = r"%SystemDrive%\Documents and Settings" all_users = "All Users" # Default value. for stat in stats: value = stat.registry_data.GetValue() if stat.pathspec.Basename() == "ProfilesDirectory" and value: prof_directory = value elif stat.pathspec.Basename() == "AllUsersProfile" and value: all_users = value all_users_dir = r"%s\%s" % (prof_directory, all_users) all_users_dir = artifact_utils.ExpandWindowsEnvironmentVariables( all_users_dir, knowledge_base) yield rdfvalue.RDFString(all_users_dir)
def Parse(self, stat, _): """Parses a SystemDrive environment variable.""" if isinstance(stat, rdf_client.StatEntry): value = stat.registry_data.GetValue() elif isinstance(stat, rdfvalue.RDFString): value = stat if not value: raise parsers.ParseError("Invalid value for key %s" % stat.pathspec.path) systemdrive = value[0:2] if re.match(r"^[A-Za-z]:$", systemdrive): yield rdfvalue.RDFString(systemdrive) else: raise parsers.ParseError( "Bad drive letter for key %s" % stat.pathspec.path)
def testClientSummaryModalIsShownWhenClientInfoButtonClicked(self): client_id = self.SetupClients(1)[0] h = self.CreateSampleHunt() with data_store.DB.GetMutationPool() as pool: h.ResultCollection().Add(rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo-result"), source=client_id), mutation_pool=pool) self.Open("/#/hunts/%s/results" % h.urn.Basename()) self.Click("css=td:contains('%s') button:has(.glyphicon-info-sign)" % client_id.Basename()) self.WaitUntil( self.IsElementPresent, "css=.modal-dialog:contains('Client %s')" % client_id.Basename())
def _FillInStubResults(self): original_results = aff4.FACTORY.Open(self.results_urn, token=self.token) original_result = original_results[0] with aff4.FACTORY.Create( self.results_urn, aff4_type=hunt_results.HuntResultCollection, mode="rw", token=self.token) as new_results: for i in range(self.handler.MAX_RECORDS_TO_CHECK): wrong_result = rdf_flows.GrrMessage( payload=rdfvalue.RDFString("foo/bar"), age=(original_result.age - (self.handler.MAX_RECORDS_TO_CHECK - i + 1) * rdfvalue.Duration("1s"))) new_results.Add(wrong_result, timestamp=wrong_result.age) return original_result
def Parse(self, stat, _): """Parse the key currentcontrolset output.""" # SystemDriveEnvironmentVariable produces a statentry, # WindowsEnvironmentVariableSystemDrive produces a string if isinstance(stat, rdf_client.StatEntry): value = stat.registry_data.GetValue() elif isinstance(stat, rdfvalue.RDFString): value = stat if not value: raise parsers.ParseError("Invalid value for key %s" % stat.pathspec.path) systemdrive = value[0:2] if re.match(r"^[A-Za-z]:$", systemdrive): yield rdfvalue.RDFString(systemdrive) else: raise parsers.ParseError("Bad drive letter for key %s" % stat.pathspec.path)
def ParseFiles(self, responses): """Take each file we retrieved and get the history from it.""" if responses: for response in responses: fd = aff4.FACTORY.Open( response.stat_entry.AFF4Path(self.client_id), token=self.token) hist = firefox3_history.Firefox3History(fd) count = 0 for epoch64, dtype, url, dat1, in hist.Parse(): count += 1 str_entry = "%s %s %s %s" % ( datetime.datetime.utcfromtimestamp(epoch64 / 1e6), url, dat1, dtype) self.SendReply(rdfvalue.RDFString(utils.SmartStr(str_entry))) self.Log("Wrote %d Firefox History entries for user %s from %s", count, self.args.username, response.stat_entry.pathspec.Basename()) self.state.hist_count += count
def ParseFiles(self, responses): """Take each file we retrieved and get the history from it.""" # Note that some of these Find requests will fail because some paths don't # exist, e.g. Chromium on most machines, so we don't check for success. if responses: for response in responses: fd = aff4.FACTORY.Open( response.stat_entry.AFF4Path(self.client_id), token=self.token) hist = chrome_history.ChromeParser(fd) count = 0 for epoch64, dtype, url, dat1, dat2, dat3 in hist.Parse(): count += 1 str_entry = "%s %s %s %s %s %s" % ( datetime.datetime.utcfromtimestamp(epoch64 / 1e6), url, dat1, dat2, dat3, dtype) self.SendReply(rdfvalue.RDFString(utils.SmartStr(str_entry))) self.Log("Wrote %d Chrome History entries for user %s from %s", count, self.args.username, response.stat_entry.pathspec.Basename()) self.state.hist_count += count