def testInset(self): obj = DummyObject("clone", 2) parser = objectfilter.Parser("clone inset [1, 2, 3]").Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), True) obj = DummyObject("troubleshooter", "red") parser = objectfilter.Parser("troubleshooter inset ['red', 'blue']").Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), True) obj = DummyObject("troubleshooter", "infrared") parser = objectfilter.Parser("troubleshooter inset ['red', 'blue']").Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False)
def testEscaping(self): parser = objectfilter.Parser(r"a is '\n'").Parse() self.assertEqual(parser.args[0], "\n") # Invalid escape sequence parser = objectfilter.Parser(r"a is '\z'") self.assertRaises(objectfilter.ParseError, parser.Parse) # Can escape the backslash parser = objectfilter.Parser(r"a is '\\'").Parse() self.assertEqual(parser.args[0], "\\") # HEX ESCAPING # This fails as it's not really a hex escaped string parser = objectfilter.Parser(r"a is '\xJZ'") self.assertRaises(objectfilter.ParseError, parser.Parse) # Instead, this is what one should write parser = objectfilter.Parser(r"a is '\\xJZ'").Parse() self.assertEqual(parser.args[0], r"\xJZ") # Standard hex-escape parser = objectfilter.Parser(r"a is '\x41\x41\x41'").Parse() self.assertEqual(parser.args[0], "AAA") # Hex-escape + a character parser = objectfilter.Parser(r"a is '\x414'").Parse() self.assertEqual(parser.args[0], r"A4") # How to include r'\x41' parser = objectfilter.Parser(r"a is '\\x41'").Parse() self.assertEqual(parser.args[0], r"\x41")
def _Compile(self, expression): try: of = objectfilter.Parser(expression).Parse() return of.Compile( objectfilter.LowercaseAttributeFilterImplementation) except objectfilter.Error as e: raise DefinitionError(e)
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 CheckCondition(condition, check_object): """Check if a condition matches an object. Args: condition: A string condition e.g. "os == 'Windows'" check_object: Object to validate, e.g. an rdf_client.KnowledgeBase() Returns: True or False depending on whether the condition matches. Raises: ConditionError: If condition is bad. """ try: of = objectfilter.Parser(condition).Parse() compiled_filter = of.Compile(objectfilter.BaseFilterImplementation) return compiled_filter.Matches(check_object) except objectfilter.Error as e: raise ConditionError(e)
def testCompile(self): obj = DummyObject("something", "Blue") parser = objectfilter.Parser("something == 'Blue'").Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), True) parser = objectfilter.Parser("something == 'Red'").Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False) parser = objectfilter.Parser("something == \"Red\"").Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False) obj = DummyObject("size", 4) parser = objectfilter.Parser("size < 3").Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False) parser = objectfilter.Parser("size == 4").Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), True) query = "something is 'Blue' and size notcontains 3" parser = objectfilter.Parser(query).Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False)
def testParse(self): # Arguments are either int, float or quoted string objectfilter.Parser("attribute == 1").Parse() objectfilter.Parser("attribute == 0x10").Parse() objectfilter.Parser("attribute == 0xa").Parse() objectfilter.Parser("attribute == 0xFF").Parse() parser = objectfilter.Parser("attribute == 1a") self.assertRaises(objectfilter.ParseError, parser.Parse) objectfilter.Parser("attribute == 1.2").Parse() objectfilter.Parser("attribute == 'bla'").Parse() objectfilter.Parser("attribute == \"bla\"").Parse() parser = objectfilter.Parser("something == red") self.assertRaises(objectfilter.ParseError, parser.Parse) # Can't start with AND parser = objectfilter.Parser("and something is 'Blue'") self.assertRaises(objectfilter.ParseError, parser.Parse) # Need to close braces objectfilter.Parser("(a is 3)").Parse() parser = objectfilter.Parser("(a is 3") self.assertRaises(objectfilter.ParseError, parser.Parse) # Need to open braces to close them parser = objectfilter.Parser("a is 3)") self.assertRaises(objectfilter.ParseError, parser.Parse) # Can parse lists objectfilter.Parser("attribute inset [1, 2, '3', 4.01, 0xa]").Parse() # Need to close square braces for lists. parser = objectfilter.Parser("attribute inset [1, 2, '3', 4.01, 0xA") self.assertRaises(objectfilter.ParseError, parser.Parse) # Need to opensquare braces to close lists. parser = objectfilter.Parser("attribute inset 1, 2, '3', 4.01]") self.assertRaises(objectfilter.ParseError, parser.Parse) # Context Operator alone is not accepted parser = objectfilter.Parser("@attributes") self.assertRaises(objectfilter.ParseError, parser.Parse) # Accepted only with braces objectfilter.Parser("@attributes( name is 'adrien')").Parse() # Not without them parser = objectfilter.Parser("@attributes name is 'adrien'") self.assertRaises(objectfilter.ParseError, parser.Parse) # Can nest context operators query = "@imported_dlls( @imported_function( name is 'OpenFileA'))" objectfilter.Parser(query).Parse() # Can nest context operators and mix braces without it messing up query = "@imported_dlls( @imported_function( name is 'OpenFileA'))" parser = objectfilter.Parser(query).Parse() query = """ @imported_dlls ( @imported_function ( name is 'OpenFileA' and ordinal == 12 ) ) """ parser = objectfilter.Parser(query).Parse() # Mix context and binary operators query = """ @imported_dlls ( @imported_function ( name is 'OpenFileA' ) AND num_functions == 2 ) """ parser = objectfilter.Parser(query).Parse() # Also on the right query = """
def testContext(self): self.assertRaises( objectfilter.InvalidNumberOfOperands, objectfilter.Context, arguments=["context"], value_expander=self.value_expander) self.assertRaises( objectfilter.InvalidNumberOfOperands, objectfilter.Context, arguments=[ "context", objectfilter.Equals( arguments=["path", "value"], value_expander=self.value_expander), objectfilter.Equals( arguments=["another_path", "value"], value_expander=self.value_expander) ], value_expander=self.value_expander) # "One imported_dll imports 2 functions AND one imported_dll imports # function RegQueryValueEx" arguments = [ objectfilter.Equals( ["imported_dlls.num_imported_functions", 1], value_expander=self.value_expander), objectfilter.Contains( ["imported_dlls.imported_functions", "RegQueryValueEx"], value_expander=self.value_expander) ] condition = objectfilter.AndFilter(arguments=arguments) # Without context, it matches because both filters match separately self.assertEqual(True, condition.Matches(self.file)) arguments = [ objectfilter.Equals( ["num_imported_functions", 2], value_expander=self.value_expander), objectfilter.Contains( ["imported_functions", "RegQueryValueEx"], value_expander=self.value_expander) ] condition = objectfilter.AndFilter(arguments=arguments) # "The same DLL imports 2 functions AND one of these is RegQueryValueEx" context = objectfilter.Context( arguments=["imported_dlls", condition], value_expander=self.value_expander) # With context, it doesn't match because both don't match in the same dll self.assertEqual(False, context.Matches(self.file)) # "One imported_dll imports only 1 function AND one imported_dll imports # function RegQueryValueEx" condition = objectfilter.AndFilter(arguments=[ objectfilter.Equals( arguments=["num_imported_functions", 1], value_expander=self.value_expander), objectfilter.Contains( ["imported_functions", "RegQueryValueEx"], value_expander=self.value_expander) ]) # "The same DLL imports 1 function AND it"s RegQueryValueEx" context = objectfilter.Context( ["imported_dlls", condition], value_expander=self.value_expander) self.assertEqual(True, context.Matches(self.file)) # Now test the context with a straight query query = """ @imported_dlls ( imported_functions contains "RegQueryValueEx" AND num_imported_functions == 1 ) """ filter_ = objectfilter.Parser(query).Parse() filter_ = filter_.Compile(self.filter_imp) self.assertEqual(True, filter_.Matches(self.file))