pattern guide

stix2.0
mbastian1135 2018-08-24 10:40:37 -04:00
parent 68aac583c9
commit a9de13107f
1 changed files with 244 additions and 5 deletions

View File

@ -18,6 +18,11 @@ class _Constant(object):
class StringConstant(_Constant): class StringConstant(_Constant):
"""Pattern string constant
Args:
value (str): string value
"""
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
@ -26,6 +31,11 @@ class StringConstant(_Constant):
class TimestampConstant(_Constant): class TimestampConstant(_Constant):
"""Pattern timestamp constant
Args:
value (datetime.datetime OR str): if string, must be a timestamp string
"""
def __init__(self, value): def __init__(self, value):
try: try:
self.value = parse_into_datetime(value) self.value = parse_into_datetime(value)
@ -37,6 +47,12 @@ class TimestampConstant(_Constant):
class IntegerConstant(_Constant): class IntegerConstant(_Constant):
"""Pattern interger constant
Args:
value (int): integer value
"""
def __init__(self, value): def __init__(self, value):
try: try:
self.value = int(value) self.value = int(value)
@ -59,6 +75,13 @@ class FloatConstant(_Constant):
class BooleanConstant(_Constant): class BooleanConstant(_Constant):
"""Pattern boolean constant
Args:
value (str OR int):
(str) 'true', 't' for True; 'false', 'f' for False
(int) 1 for True; 0 for False
"""
def __init__(self, value): def __init__(self, value):
if isinstance(value, bool): if isinstance(value, bool):
self.value = value self.value = value
@ -106,6 +129,15 @@ _HASH_REGEX = {
class HashConstant(StringConstant): class HashConstant(StringConstant):
"""Pattern hash constant
Args:
value (str): hash value
type (str): hash algorithm name
supported hash algorithms: "MD5", "MD6", RIPEMD160", "SHA1",
"SHA224", "SHA256", "SHA384", "SHA512", "SHA3224", "SHA3256",
"SHA3384", "SHA3512", "SSDEEP", "WHIRLPOOL"
"""
def __init__(self, value, type): def __init__(self, value, type):
key = type.upper().replace('-', '') key = type.upper().replace('-', '')
if key in _HASH_REGEX: if key in _HASH_REGEX:
@ -116,7 +148,11 @@ class HashConstant(StringConstant):
class BinaryConstant(_Constant): class BinaryConstant(_Constant):
"""Pattern binary constant
Args:
value (str): base64 encoded string value
"""
def __init__(self, value): def __init__(self, value):
try: try:
base64.b64decode(value) base64.b64decode(value)
@ -129,6 +165,11 @@ class BinaryConstant(_Constant):
class HexConstant(_Constant): class HexConstant(_Constant):
"""Pattern hexadecimal constant
Args:
value (str): hexadecimal value
"""
def __init__(self, value): def __init__(self, value):
if not re.match('^([a-fA-F0-9]{2})+$', value): if not re.match('^([a-fA-F0-9]{2})+$', value):
raise ValueError("must contain an even number of hexadecimal characters") raise ValueError("must contain an even number of hexadecimal characters")
@ -139,6 +180,11 @@ class HexConstant(_Constant):
class ListConstant(_Constant): class ListConstant(_Constant):
"""Pattern list constant
Args:
value (list): list of values
"""
def __init__(self, values): def __init__(self, values):
self.value = values self.value = values
@ -147,6 +193,12 @@ class ListConstant(_Constant):
def make_constant(value): def make_constant(value):
"""Convert value to Pattern constant, best effort attempt
at determining root value type and corresponding conversion
Args:
value (): value to convert to Pattern constant
"""
if isinstance(value, _Constant): if isinstance(value, _Constant):
return value return value
@ -182,6 +234,16 @@ class _ObjectPathComponent(object):
class BasicObjectPathComponent(_ObjectPathComponent): class BasicObjectPathComponent(_ObjectPathComponent):
"""Basic object path component (for a observation or expression)
By "Basic", implies that the object path component is not a
list, object reference or futher referenced property, i.e. terminal
component
Args:
property_name (str): object property name
is_key (): is dictionary key, default: False
"""
def __init__(self, property_name, is_key=False): def __init__(self, property_name, is_key=False):
self.property_name = property_name self.property_name = property_name
# TODO: set is_key to True if this component is a dictionary key # TODO: set is_key to True if this component is a dictionary key
@ -192,6 +254,13 @@ class BasicObjectPathComponent(_ObjectPathComponent):
class ListObjectPathComponent(_ObjectPathComponent): class ListObjectPathComponent(_ObjectPathComponent):
"""List object path component (for an observation or expression)
Args:
property_name (): list object property name
index (): index of the list property's value that is specified
"""
def __init__(self, property_name, index): def __init__(self, property_name, index):
self.property_name = property_name self.property_name = property_name
self.index = index self.index = index
@ -201,6 +270,11 @@ class ListObjectPathComponent(_ObjectPathComponent):
class ReferenceObjectPathComponent(_ObjectPathComponent): class ReferenceObjectPathComponent(_ObjectPathComponent):
"""Reference object path component (for an observation or expression)
Args:
reference_property_name (str): reference object property name
"""
def __init__(self, reference_property_name): def __init__(self, reference_property_name):
self.property_name = reference_property_name self.property_name = reference_property_name
@ -209,6 +283,12 @@ class ReferenceObjectPathComponent(_ObjectPathComponent):
class ObjectPath(object): class ObjectPath(object):
"""Pattern operand object (property) path
Args:
object_type_name (str): name of object type for corresponding object path component
property_path (_ObjectPathComponent OR str): Object path
"""
def __init__(self, object_type_name, property_path): def __init__(self, object_type_name, property_path):
self.object_type_name = object_type_name self.object_type_name = object_type_name
self.property_path = [x if isinstance(x, _ObjectPathComponent) else self.property_path = [x if isinstance(x, _ObjectPathComponent) else
@ -219,11 +299,17 @@ class ObjectPath(object):
return "%s:%s" % (self.object_type_name, ".".join(["%s" % x for x in self.property_path])) return "%s:%s" % (self.object_type_name, ".".join(["%s" % x for x in self.property_path]))
def merge(self, other): def merge(self, other):
"""Extend the object property with that of the supplied object property path"""
self.property_path.extend(other.property_path) self.property_path.extend(other.property_path)
return self return self
@staticmethod @staticmethod
def make_object_path(lhs): def make_object_path(lhs):
"""Create ObjectPath from string encoded object path
Args:
lhs (str): object path of left-hand-side component of expression
"""
path_as_parts = lhs.split(":") path_as_parts = lhs.split(":")
return ObjectPath(path_as_parts[0], path_as_parts[1].split(".")) return ObjectPath(path_as_parts[0], path_as_parts[1].split("."))
@ -233,6 +319,14 @@ class _PatternExpression(object):
class _ComparisonExpression(_PatternExpression): class _ComparisonExpression(_PatternExpression):
"""Pattern Comparison Expression
Args:
operator (str): operator of comparison expression
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, operator, lhs, rhs, negated=False): def __init__(self, operator, lhs, rhs, negated=False):
if operator == "=" and isinstance(rhs, (ListConstant, list)): if operator == "=" and isinstance(rhs, (ListConstant, list)):
self.operator = "IN" self.operator = "IN"
@ -257,58 +351,139 @@ class _ComparisonExpression(_PatternExpression):
class EqualityComparisonExpression(_ComparisonExpression): class EqualityComparisonExpression(_ComparisonExpression):
"""Pattern Equality Comparison Expression
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False): def __init__(self, lhs, rhs, negated=False):
super(EqualityComparisonExpression, self).__init__("=", lhs, rhs, negated) super(EqualityComparisonExpression, self).__init__("=", lhs, rhs, negated)
class GreaterThanComparisonExpression(_ComparisonExpression): class GreaterThanComparisonExpression(_ComparisonExpression):
"""Pattern Greater-than Comparison Expression
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False): def __init__(self, lhs, rhs, negated=False):
super(GreaterThanComparisonExpression, self).__init__(">", lhs, rhs, negated) super(GreaterThanComparisonExpression, self).__init__(">", lhs, rhs, negated)
class LessThanComparisonExpression(_ComparisonExpression): class LessThanComparisonExpression(_ComparisonExpression):
"""Pattern Less-than Comparison Expression
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False): def __init__(self, lhs, rhs, negated=False):
super(LessThanComparisonExpression, self).__init__("<", lhs, rhs, negated) super(LessThanComparisonExpression, self).__init__("<", lhs, rhs, negated)
class GreaterThanEqualComparisonExpression(_ComparisonExpression): class GreaterThanEqualComparisonExpression(_ComparisonExpression):
"""Pattern Greater-Than-or-Equal-to Comparison Expression
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False): def __init__(self, lhs, rhs, negated=False):
super(GreaterThanEqualComparisonExpression, self).__init__(">=", lhs, rhs, negated) super(GreaterThanEqualComparisonExpression, self).__init__(">=", lhs, rhs, negated)
class LessThanEqualComparisonExpression(_ComparisonExpression): class LessThanEqualComparisonExpression(_ComparisonExpression):
"""Pattern Less-Than-or-Equal-to Comparison Expression
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False): def __init__(self, lhs, rhs, negated=False):
super(LessThanEqualComparisonExpression, self).__init__("<=", lhs, rhs, negated) super(LessThanEqualComparisonExpression, self).__init__("<=", lhs, rhs, negated)
class InComparisonExpression(_ComparisonExpression): class InComparisonExpression(_ComparisonExpression):
"""'in' Comparison Expression
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False): def __init__(self, lhs, rhs, negated=False):
super(InComparisonExpression, self).__init__("IN", lhs, rhs, negated) super(InComparisonExpression, self).__init__("IN", lhs, rhs, negated)
class LikeComparisonExpression(_ComparisonExpression): class LikeComparisonExpression(_ComparisonExpression):
"""'in' Comparison Expression
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False): def __init__(self, lhs, rhs, negated=False):
super(LikeComparisonExpression, self).__init__("LIKE", lhs, rhs, negated) super(LikeComparisonExpression, self).__init__("LIKE", lhs, rhs, negated)
class MatchesComparisonExpression(_ComparisonExpression): class MatchesComparisonExpression(_ComparisonExpression):
"""Matches Comparison Expression
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False): def __init__(self, lhs, rhs, negated=False):
super(MatchesComparisonExpression, self).__init__("MATCHES", lhs, rhs, negated) super(MatchesComparisonExpression, self).__init__("MATCHES", lhs, rhs, negated)
class IsSubsetComparisonExpression(_ComparisonExpression): class IsSubsetComparisonExpression(_ComparisonExpression):
def __init__(self, lhs, rhs, negated=False): """ 'is subset' Comparison Expression
super(IsSubsetComparisonExpression, self).__init__("ISSUBSET", lhs, rhs, negated)
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False):
super(IsSubsetComparisonExpression, self).__init__("ISSUBSET", lhs, rhs, negated)
class IsSupersetComparisonExpression(_ComparisonExpression): class IsSupersetComparisonExpression(_ComparisonExpression):
def __init__(self, lhs, rhs, negated=False): """ 'is super set' Comparison Expression
super(IsSupersetComparisonExpression, self).__init__("ISSUPERSET", lhs, rhs, negated)
Args:
lhs (ObjectPath OR str): object path of left-hand-side component of expression
rhs (ObjectPath OR str): object path of right-hand-side component of expression
negated (bool): comparison expression negated. Default: False
"""
def __init__(self, lhs, rhs, negated=False):
super(IsSupersetComparisonExpression, self).__init__("ISSUPERSET", lhs, rhs, negated)
class _BooleanExpression(_PatternExpression): class _BooleanExpression(_PatternExpression):
"""Pattern Boolean Expression
Args:
operator (str): boolean operator
operands (list): boolean operands
"""
def __init__(self, operator, operands): def __init__(self, operator, operands):
self.operator = operator self.operator = operator
self.operands = [] self.operands = []
for arg in operands: for arg in operands:
if not hasattr(self, "root_type"): if not hasattr(self, "root_type"):
@ -327,16 +502,31 @@ class _BooleanExpression(_PatternExpression):
class AndBooleanExpression(_BooleanExpression): class AndBooleanExpression(_BooleanExpression):
"""Pattern 'AND' Boolean Expression
Args:
operands (list): AND operands
"""
def __init__(self, operands): def __init__(self, operands):
super(AndBooleanExpression, self).__init__("AND", operands) super(AndBooleanExpression, self).__init__("AND", operands)
class OrBooleanExpression(_BooleanExpression): class OrBooleanExpression(_BooleanExpression):
"""Pattern 'OR' Boolean Expression
Args:
operands (list): OR operands
"""
def __init__(self, operands): def __init__(self, operands):
super(OrBooleanExpression, self).__init__("OR", operands) super(OrBooleanExpression, self).__init__("OR", operands)
class ObservationExpression(_PatternExpression): class ObservationExpression(_PatternExpression):
"""Observation Expression
Args:
operand (str): observation expression operand
"""
def __init__(self, operand): def __init__(self, operand):
self.operand = operand self.operand = operand
@ -345,6 +535,12 @@ class ObservationExpression(_PatternExpression):
class _CompoundObservationExpression(_PatternExpression): class _CompoundObservationExpression(_PatternExpression):
"""Compound Observation Expression
Args:
operator (str): compound observation operator
operands (str): compound observation operands
"""
def __init__(self, operator, operands): def __init__(self, operator, operands):
self.operator = operator self.operator = operator
self.operands = operands self.operands = operands
@ -357,21 +553,42 @@ class _CompoundObservationExpression(_PatternExpression):
class AndObservationExpression(_CompoundObservationExpression): class AndObservationExpression(_CompoundObservationExpression):
"""Pattern 'AND' Compound Observation Expression
Args:
operands (str): compound observation operands
"""
def __init__(self, operands): def __init__(self, operands):
super(AndObservationExpression, self).__init__("AND", operands) super(AndObservationExpression, self).__init__("AND", operands)
class OrObservationExpression(_CompoundObservationExpression): class OrObservationExpression(_CompoundObservationExpression):
"""Pattern 'OR' Compound Observation Expression
Args:
operands (str): compound observation operands
"""
def __init__(self, operands): def __init__(self, operands):
super(OrObservationExpression, self).__init__("OR", operands) super(OrObservationExpression, self).__init__("OR", operands)
class FollowedByObservationExpression(_CompoundObservationExpression): class FollowedByObservationExpression(_CompoundObservationExpression):
"""Pattern 'Followed by' Compound Observation Expression
Args:
operands (str): compound observation operands
"""
def __init__(self, operands): def __init__(self, operands):
super(FollowedByObservationExpression, self).__init__("FOLLOWEDBY", operands) super(FollowedByObservationExpression, self).__init__("FOLLOWEDBY", operands)
class ParentheticalExpression(_PatternExpression): class ParentheticalExpression(_PatternExpression):
"""Pattern Parenthetical Observation Expression
Args:
exp (str): observation expression
"""
def __init__(self, exp): def __init__(self, exp):
self.expression = exp self.expression = exp
if hasattr(exp, "root_type"): if hasattr(exp, "root_type"):
@ -386,6 +603,11 @@ class _ExpressionQualifier(_PatternExpression):
class RepeatQualifier(_ExpressionQualifier): class RepeatQualifier(_ExpressionQualifier):
"""Pattern Repeat Qualifier
Args:
times_to_repeat (int): times the qualifiers is repeated
"""
def __init__(self, times_to_repeat): def __init__(self, times_to_repeat):
if isinstance(times_to_repeat, IntegerConstant): if isinstance(times_to_repeat, IntegerConstant):
self.times_to_repeat = times_to_repeat self.times_to_repeat = times_to_repeat
@ -399,6 +621,11 @@ class RepeatQualifier(_ExpressionQualifier):
class WithinQualifier(_ExpressionQualifier): class WithinQualifier(_ExpressionQualifier):
"""Pattern 'Within' Qualifier
Args:
number_of_seconds (int): seconds value for 'within' qualifier
"""
def __init__(self, number_of_seconds): def __init__(self, number_of_seconds):
if isinstance(number_of_seconds, IntegerConstant): if isinstance(number_of_seconds, IntegerConstant):
self.number_of_seconds = number_of_seconds self.number_of_seconds = number_of_seconds
@ -412,6 +639,12 @@ class WithinQualifier(_ExpressionQualifier):
class StartStopQualifier(_ExpressionQualifier): class StartStopQualifier(_ExpressionQualifier):
"""Pattern Start/Stop Qualifier
Args:
start_time (TimestampConstant OR datetime.date): start timestamp for qualifier
stop_time (TimestampConstant OR datetime.date): stop timestamp for qualifier
"""
def __init__(self, start_time, stop_time): def __init__(self, start_time, stop_time):
if isinstance(start_time, TimestampConstant): if isinstance(start_time, TimestampConstant):
self.start_time = start_time self.start_time = start_time
@ -431,6 +664,12 @@ class StartStopQualifier(_ExpressionQualifier):
class QualifiedObservationExpression(_PatternExpression): class QualifiedObservationExpression(_PatternExpression):
"""Pattern Qualified Observation Expression
Args:
observation_expression (PatternExpression OR _CompoundObservationExpression OR ): pattern expression
qualifier (_ExpressionQualifier): pattern expression qualifier
"""
def __init__(self, observation_expression, qualifier): def __init__(self, observation_expression, qualifier):
self.observation_expression = observation_expression self.observation_expression = observation_expression
self.qualifier = qualifier self.qualifier = qualifier