def __init__(self,rule): #We need to flatten the rule here for pcre #r = RevRegex(rule) if rule.find("pcre") != -1: rule = RevRegex2.main(rule) #r.flatten() #rule = r.rule try: p = re.compile(r'^(?P<general>[^\(]+)\s*\((?P<rawoptions>.*)\)\s*$') m = p.search(rule) general = m.group("general") rawoptions = m.group("rawoptions") except: #Error parsing rule return if general != None and rawoptions != None: pg = re.compile(r'(?P<type>[^\s]+)\s+(?P<proto>[^\s]+)\s+(?P<rawsources>[^\s]+)\s+(?P<rawsrcports>[^\s]+)\s+(?P<direc>[^\s]+)\s+(?P<rawdestinations>[^\s]+)\s+(?P<rawdesports>[^\s]+)\s*') m = pg.search(general) self.type = m.group('type') self.proto = m.group('proto') self.rawsources = m.group('rawsources') self.rawsrcports = m.group('rawsrcports') self.direc = m.group('direc') self.rawdestinations = m.group('rawdestinations') self.rawdesports = m.group('rawdesports') self.rawoptions = rawoptions po = re.compile(r'\s*([^;]+[^\\])\s*;') optlist = po.findall(rawoptions) #there it is self.options = [] self.contents = [] self.uricontents = [] self.flow = None #set to none default self.flowbits = [] #set to none default self.isHTTP = False #here we check if we have any sort of "content" in the rule #if no content option is found - we simply put "None" if not [xcon for xcon in optlist if "content:" in xcon]: print "!!--no content found in the rule--!!" c = RuleContent("None") self.contents.append(c) for i in optlist: pi = re.compile(r'^(?P<key>[^:]+)(\s*:\s*(?P<value>.*))?\s*$') mi = pi.search(i) k = mi.group("key") v = mi.group("value") if v == None: v = True if k == "flow": self.flow=Flow(v) continue # Add as attributes the options that will not be "duplicated" # For options that can be duplicated/repeated do a list, like self.contents if k == "sid": self.sid = v if self.flowbits: RuleFlowbits(self.flowbits ,self.sid) continue if k == "msg": self.msg=v continue if k == "uricontent": self.isHTTP = True c = RuleUriContent(v) self.uricontents.append(c) continue if k == "content": c = RuleContent(v) self.contents.append(c) continue if k == "flowbits": self.flowbits.append(v) continue if k == "dsize": #it is a global variable, #not content modifier # - hence we get it here self.dsize = v #self.dsize_list = re.split(r'(\D)', self.dsize) self.dsize_list = re.findall(r'\d+|\D+', self.dsize) continue if k == "rawbytes": continue #To Do - "tag" has to be supported the proper way - #but not needed at the moment. if k == "tag": continue if k == "reference": continue if k == "classtype": continue if k == "rev": continue #this is to make rules with "threshold:...., count 1" ONLY #pass and be made. #since it is only 1 count of the alert/pcap needed. #count MORE than one (1) - would not be forged/made # TO DO - count >1 if k == "threshold": if "count 1" in v: print v continue # modifiers for contents #if len(self.contents) > 0: # for clast in self.contents: # pass clast = "" if len(self.contents) > 0: clast = self.contents[-1] else: continue if k == "nocase": clast.nocase = v continue if k == "rawbytes": clast.rawbytes = v continue if k == "depth": clast.depth = int(v) continue if k == "offset": clast.offset = int(v) continue if k == "distance": clast.distance = int(v) continue if k == "within": clast.within = int(v) continue if k == "http_client_body": clast.isHTTP = True clast.http_client_body = v continue if k == "http_cookie": clast.isHTTP = True clast.http_cookie = v continue if k == "http_header": clast.isHTTP = True clast.http_header = v continue if k == "http_method": clast.isHTTP = True clast.http_method = v continue if k == "http_uri": clast.isHTTP = True clast.http_uri = v #print [z.content for z in self.contents ][-1] #- returns the content that http_uri keyword modifies #as a string #print [z.content for z in self.contents ][-1:] #- returns the content that http_uri keyword modifies #as a list #basically content:"BLABLA"; http_uri; #[EQUALS] uricontent:"BLABLA" !! #so we need to make it uricontnet http_uri_content = [z.content for z in self.contents ][-1] c = RuleUriContent(http_uri_content) self.uricontents.append(c) #then we need to delete/destroy the "content"/"payload" #so that it is only the uricontent left #otherwise we end up with both "content" and "uricontent" for z in self.contents: if z.content == http_uri_content: z.content = '' z.payload = '' continue if k == "fast_pattern": clast.fast_pattern = v continue if k == "metadata": continue if k == "priority": continue if k == "threshold": continue else: print "\nUnsupported keyword! Error parsing rule contents\n" +str(rule) print str("KEYWORD ERR: " + k) return 1 #break self.options.append([k,v]) else: print "Error loading rule " +str(rule)
def __init__(self, rule): #We need to flatten the rule here for pcre #r = RevRegex(rule) if rule.find("pcre") != -1: rule = RevRegex2.main(rule) #r.flatten() #rule = r.rule try: p = re.compile( r'^(?P<general>[^\(]+)\s*\((?P<rawoptions>.*)\)\s*$') m = p.search(rule) general = m.group("general") rawoptions = m.group("rawoptions") except: #Error parsing rule return if general != None and rawoptions != None: pg = re.compile( r'(?P<type>[^\s]+)\s+(?P<proto>[^\s]+)\s+(?P<rawsources>[^\s]+)\s+(?P<rawsrcports>[^\s]+)\s+(?P<direc>[^\s]+)\s+(?P<rawdestinations>[^\s]+)\s+(?P<rawdesports>[^\s]+)\s*' ) m = pg.search(general) self.type = m.group('type') self.proto = m.group('proto') self.rawsources = m.group('rawsources') self.rawsrcports = m.group('rawsrcports') self.direc = m.group('direc') self.rawdestinations = m.group('rawdestinations') self.rawdesports = m.group('rawdesports') self.rawoptions = rawoptions po = re.compile(r'\s*([^;]+[^\\])\s*;') optlist = po.findall(rawoptions) self.options = [] self.contents = [] self.uricontents = [] self.flow = None self.isHTTP = False for i in optlist: pi = re.compile(r'^(?P<key>[^:]+)(\s*:\s*(?P<value>.*))?\s*$') mi = pi.search(i) k = mi.group("key") v = mi.group("value") if v == None: v = True if k == "flow": self.flow = Flow(v) continue # Add as attributes the options that will not be "duplicated" # For options that can be duplicated/repeated do a list, like self.contents if k == "sid": self.sid = v continue if k == "msg": self.msg = v continue if k == "uricontent": self.isHTTP = True c = RuleUriContent(v) self.uricontents.append(c) continue if k == "content": c = RuleContent(v) self.contents.append(c) continue # modifiers for contents #if len(self.contents) > 0: # for clast in self.contents: # pass clast = "" if len(self.contents) > 0: clast = self.contents[-1] else: continue if k == "nocase": clast.nocase = v continue if k == "rawbytes": clast.rawbytes = v continue if k == "depth": clast.depth = int(v) continue if k == "offset": clast.offset = int(v) continue if k == "distance": clast.distance = int(v) continue if k == "within": clast.within = int(v) continue if k == "http_client body": clast.isHTTP = True clast.http_client_body = v continue if k == "http_cookie": clast.isHTTP = True clast.http_cookie = v continue if k == "http_header": clast.isHTTP = True clast.http_header = v continue if k == "http_method": clast.isHTTP = True clast.http_method = v continue if k == "http_uri": clast.isHTTP = True clast.http_uri = v continue if k == "fast_pattern": clast.fast_pattern = v continue self.options.append([k, v]) else: print "Error loading rule " + str(rule)
def __init__(self,rule): #We need to flatten the rule here for pcre #r = RevRegex(rule) if rule.find("pcre") != -1: rule = RevRegex2.main(rule) #r.flatten() #rule = r.rule try: p = re.compile(r'^(?P<general>[^\(]+)\s*\((?P<rawoptions>.*)\)\s*$') m = p.search(rule) general = m.group("general") rawoptions = m.group("rawoptions") except: #Error parsing rule return if general != None and rawoptions != None: pg = re.compile(r'(?P<type>[^\s]+)\s+(?P<proto>[^\s]+)\s+(?P<rawsources>[^\s]+)\s+(?P<rawsrcports>[^\s]+)\s+(?P<direc>[^\s]+)\s+(?P<rawdestinations>[^\s]+)\s+(?P<rawdesports>[^\s]+)\s*') m = pg.search(general) self.type = m.group('type') self.proto = m.group('proto') self.rawsources = m.group('rawsources') self.rawsrcports = m.group('rawsrcports') self.direc = m.group('direc') self.rawdestinations = m.group('rawdestinations') self.rawdesports = m.group('rawdesports') self.rawoptions = rawoptions po = re.compile(r'\s*([^;]+[^\\])\s*;') optlist = po.findall(rawoptions) self.options = [] self.contents = [] self.uricontents = [] self.flow = None self.isHTTP = False for i in optlist: pi = re.compile(r'^(?P<key>[^:]+)(\s*:\s*(?P<value>.*))?\s*$') mi = pi.search(i) k = mi.group("key") v = mi.group("value") if v == None: v = True if k == "flow": self.flow=Flow(v) continue # Add as attributes the options that will not be "duplicated" # For options that can be duplicated/repeated do a list, like self.contents if k == "sid": self.sid = v continue if k == "msg": self.msg=v continue if k == "uricontent": self.isHTTP = True c = RuleUriContent(v) self.uricontents.append(c) continue if k == "content": c = RuleContent(v) self.contents.append(c) continue # modifiers for contents #if len(self.contents) > 0: # for clast in self.contents: # pass clast = "" if len(self.contents) > 0: clast = self.contents[-1] else: continue if k == "nocase": clast.nocase = v continue if k == "rawbytes": clast.rawbytes = v continue if k == "depth": clast.depth = int(v) continue if k == "offset": clast.offset = int(v) continue if k == "distance": clast.distance = int(v) continue if k == "within": clast.within = int(v) continue if k == "http_client body": clast.isHTTP = True clast.http_client_body = v continue if k == "http_cookie": clast.isHTTP = True clast.http_cookie = v continue if k == "http_header": clast.isHTTP = True clast.http_header = v continue if k == "http_method": clast.isHTTP = True clast.http_method = v continue if k == "http_uri": clast.isHTTP = True clast.http_uri = v continue if k == "fast_pattern": clast.fast_pattern = v continue self.options.append([k,v]) else: print "Error loading rule " +str(rule)
def __init__(self, rule): #We need to flatten the rule here for pcre #r = RevRegex(rule) if rule.find("pcre") != -1: rule = RevRegex2.main(rule) #r.flatten() #rule = r.rule try: p = re.compile( r'^(?P<general>[^\(]+)\s*\((?P<rawoptions>.*)\)\s*$') m = p.search(rule) general = m.group("general") rawoptions = m.group("rawoptions") except: #Error parsing rule return if general != None and rawoptions != None: pg = re.compile( r'(?P<type>[^\s]+)\s+(?P<proto>[^\s]+)\s+(?P<rawsources>[^\s]+)\s+(?P<rawsrcports>[^\s]+)\s+(?P<direc>[^\s]+)\s+(?P<rawdestinations>[^\s]+)\s+(?P<rawdesports>[^\s]+)\s*' ) m = pg.search(general) self.type = m.group('type') self.proto = m.group('proto') self.rawsources = m.group('rawsources') self.rawsrcports = m.group('rawsrcports') self.direc = m.group('direc') self.rawdestinations = m.group('rawdestinations') self.rawdesports = m.group('rawdesports') self.rawoptions = rawoptions po = re.compile(r'\s*([^;]+[^\\])\s*;') optlist = po.findall(rawoptions) #there it is self.options = [] self.contents = [] self.uricontents = [] self.flow = None #set to none default self.flowbits = [] #set to none default self.isHTTP = False #here we check if we have any sort of "content" in the rule #if no content option is found - we simply put "None" if not [xcon for xcon in optlist if "content:" in xcon]: print "!!--no content found in the rule--!!" c = RuleContent("None") self.contents.append(c) for i in optlist: pi = re.compile(r'^(?P<key>[^:]+)(\s*:\s*(?P<value>.*))?\s*$') mi = pi.search(i) k = mi.group("key") v = mi.group("value") if v == None: v = True if k == "flow": self.flow = Flow(v) continue # Add as attributes the options that will not be "duplicated" # For options that can be duplicated/repeated do a list, like self.contents if k == "sid": self.sid = v if self.flowbits: RuleFlowbits(self.flowbits, self.sid) continue if k == "msg": self.msg = v continue if k == "uricontent": self.isHTTP = True c = RuleUriContent(v) self.uricontents.append(c) continue if k == "content": c = RuleContent(v) self.contents.append(c) continue if k == "flowbits": self.flowbits.append(v) continue if k == "dsize": #it is a global variable, #not content modifier # - hence we get it here self.dsize = v #self.dsize_list = re.split(r'(\D)', self.dsize) self.dsize_list = re.findall(r'\d+|\D+', self.dsize) continue if k == "rawbytes": continue #To Do - "tag" has to be supported the proper way - #but not needed at the moment. if k == "tag": continue if k == "reference": continue if k == "classtype": continue if k == "rev": continue #this is to make rules with "threshold:...., count 1" ONLY #pass and be made. #since it is only 1 count of the alert/pcap needed. #count MORE than one (1) - would not be forged/made # TO DO - count >1 if k == "threshold": if "count 1" in v: print v continue # modifiers for contents #if len(self.contents) > 0: # for clast in self.contents: # pass clast = "" if len(self.contents) > 0: clast = self.contents[-1] else: continue if k == "nocase": clast.nocase = v continue if k == "rawbytes": clast.rawbytes = v continue if k == "depth": clast.depth = int(v) continue if k == "offset": clast.offset = int(v) continue if k == "distance": clast.distance = int(v) continue if k == "within": clast.within = int(v) continue if k == "http_client body": clast.isHTTP = True clast.http_client_body = v continue if k == "http_cookie": clast.isHTTP = True clast.http_cookie = v continue if k == "http_header": clast.isHTTP = True clast.http_header = v continue if k == "http_method": clast.isHTTP = True clast.http_method = v continue if k == "http_uri": clast.isHTTP = True clast.http_uri = v #print [z.content for z in self.contents ][-1] #- returns the content that http_uri keyword modifies #as a string #print [z.content for z in self.contents ][-1:] #- returns the content that http_uri keyword modifies #as a list #basically content:"BLABLA"; http_uri; #[EQUALS] uricontent:"BLABLA" !! #so we need to make it uricontnet http_uri_content = [z.content for z in self.contents][-1] c = RuleUriContent(http_uri_content) self.uricontents.append(c) #then we need to delete/destroy the "content"/"payload" #so that it is only the uricontent left #otherwise we end up with both "content" and "uricontent" for z in self.contents: if z.content == http_uri_content: z.content = '' z.payload = '' continue if k == "fast_pattern": clast.fast_pattern = v continue else: print "\nUnsupported keyword! Error parsing rule contents\n" + str( rule) return 1 #break self.options.append([k, v]) else: print "Error loading rule " + str(rule)