def check_batch_yara(self, yara_check_meta_key_hash, sample_file_path, pass_yara_name): try: pass_yara_ = [] for rules in self.open_file(yara_check_meta_key_hash): if not isinstance(rules, list): continue try: yr = yaratool.YaraRule(rules[1]) for k in ["hash", "hash1"]: if k not in yr.metas.keys(): continue try: check_rule = yara.compile(filepath=rules[0]) for rootpath, dirpath, filenames in os.walk(sample_file_path): for filename in filenames: if filename == yr.metas[k]: filepath = os.path.join(rootpath, filename) with open(filepath, 'rb')as f: try: matches = check_rule.match(data=f.read()) if matches[0].strings != -1: pass_yara_.append(yr.name) # with open(pass_yara_name, "a+")as ft: # ft.write(yr.name + "\n") except Exception as e: print(e) except Exception as e: print(e) except Exception as e: print(e) with open(pass_yara_name, "w")as ft: for i in pass_yara_: ft.write(i + "\n") except Exception as e: print(e)
def testRuleNormalizationWithoutStrings(self): ruletext = """rule encryption_Camellia: encryption camellia summary { meta: description = "Camellia encryption algorithm" domain = "encryption" algorithm = "Camellia" reference = "RFC 3713, http://www.ietf.org/rfc/rfc3713.txt" rule_author = "Andreas Schuster" weight = 192 condition: ( encryption_Camellia_sigma_be or encryption_Camellia_sigma_le or encryption_Camellia_splitsigma_be or encryption_Camellia_splitsigma_le ) and ( encryption_Camellia_combinedsbox1 or (encryption_Camellia_sbox1 and encryption_Camellia_tables) ) }""" yn = yaratool.YaraRule(ruletext) self.failUnlessEqual("yn01:e9800998ecf8427e:e4ce92c847", yn.hash()) self.failUnlessEqual("encryption_Camellia", yn.name) self.failUnlessEqual(["encryption","camellia","summary"], yn.tags) self.failUnlessEqual("Camellia encryption algorithm", yn.metas['description']) self.failUnlessEqual(192, yn.metas['weight']) self.failUnlessEqual(["(","encryption_Camellia_sigma_be","or encryption_Camellia_sigma_le", "or encryption_Camellia_splitsigma_be", "or encryption_Camellia_splitsigma_le", ") and (", "encryption_Camellia_combinedsbox1", "or (encryption_Camellia_sbox1 and encryption_Camellia_tables)", ")"], yn.conditions)
def testMalformedRule(self): ruletext = "rule{}" try: yn = yaratool.YaraRule(ruletext) except Exception: pass else: self.fail("Parsing the malformed rule should have raised an exception")
def check_meta_key(file, file_new, threattype=''): for rootpath, dirpath, filenames in os.walk(file): for filename in filenames: filepath = os.path.join(rootpath, filename) with open(filepath, 'rb') as f: f.seek(0) rules = f.read() try: yr = yaratool.YaraRule(rules) except Exception as e: print('YaraRule cannot parse the rule!') else: try: if not yr.strings: print("not yara_strings") if not yr.conditions: print("not yara_condition") except Exception as e: print('Condition not satisfied analysis!') else: if "judge" not in yr.metas.keys(): yr.metas['judge'] = 'None' if "threatname" not in yr.metas.keys(): yr.metas['threatname'] = 'None' if "threattype" not in yr.metas.keys(): yr.metas['threattype'] = 'None' if "family" not in yr.metas.keys(): yr.metas['family'] = 'None' if "hacker" not in yr.metas.keys(): yr.metas['hacker'] = 'None' if "comment" not in yr.metas.keys(): yr.metas['comment'] = 'None' if "date" not in yr.metas.keys(): yr.metas['date'] = 'None' if "reference" not in yr.metas.keys(): yr.metas['reference'] = 'None' if "description" not in yr.metas.keys(): yr.metas['description'] = 'None' yr.metas['author'] = 'Spider' yr.metas['threattype'] = threattype for key in yr.metas.keys(): if key not in [ "judge", "threatname", "threattype", "family", "hacker", "comment", "date", "author", "reference", "description" ]: yr.metas.pop(key) new_rule = yr.normalize() tatol = re.search(r'rule.*', new_rule).group() tatol1 = tatol.split() rule_name = os.path.join(file_new, tatol1[1] + ".yar") yr.metas['threatname'] = tatol1[1].replace( "_", ".") new_rule1 = yr.normalize() with open(rule_name, 'w+') as tmp: tmp.write(new_rule1)
def yara_meta_key(self, yara_check_file, yara_check_meta_key): """yarameta格式效验""" try: for rules in self.yara_open_file(yara_check_file): if not isinstance(rules, list): continue try: yr = yaratool.YaraRule(rules[1]) except Exception as e: continue if "judge" not in yr.metas.keys(): yr.metas['judge'] = "black" if "threatname" not in yr.metas.keys(): yr.metas['threatname'] = "None" if "threattype" not in yr.metas.keys(): yr.metas['threattype'] = "None" if "family" not in yr.metas.keys(): yr.metas['family'] = "None" if "hacker" not in yr.metas.keys(): yr.metas['hacker'] = "None" if "comment" not in yr.metas.keys(): yr.metas['comment'] = "None" if "date" not in yr.metas.keys(): yr.metas['date'] = "None" if "reference" not in yr.metas.keys(): yr.metas['reference'] = "None" if "description" not in yr.metas.keys(): yr.metas['description'] = "None" yr.metas['author'] = "Spider" try: yara_new = yr.normalize() rule_name = os.path.join(yara_check_meta_key, rules[0]) res = "".join(yr.conditions) if not "pe." in res: with open(rule_name, 'w') as tmp: tmp.write(yara_new) else: with open(rule_name, 'w') as tmp1: tmp1.write("import \"pe\"\n\r" + yara_new) except Exception as e: pass except Exception as e: print(e)
def testRuleNormalization2(self): ruletext = """rule DataConversion__wide : IntegerParsing DataConversion { meta: weight = 1 strings: $ = "wtoi" nocase $ = "wtol" nocase $ = "wtof" nocase $ = "wtodb" nocase condition: any of them }""" yn = yaratool.YaraRule(ruletext) self.failUnlessEqual("yn01:a5fd8576f2da34e2:d936fceffe", yn.hash()) self.failUnlessEqual("1", yn.metas['weight']) self.failUnlessEqual("DataConversion__wide", yn.name) self.failUnlessEqual(["IntegerParsing", "DataConversion"], yn.tags) self.failUnlessEqual([ "$ = \"wtoi\" nocase", "$ = \"wtol\" nocase", "$ = \"wtof\" nocase", "$ = \"wtodb\" nocase" ], yn.strings) self.failUnlessEqual(["any of them"], yn.conditions)
def yara_meta_hash(self, yara_check_meta_key, yara_check_meta_key_hash): try: for rules in self.yara_open_file(yara_check_meta_key): if not isinstance(rules, list): continue try: yr = yaratool.YaraRule(rules[1]) except Exception as e: print(e) else: for k in ["hash", "hash1"]: if k in yr.metas.keys(): rule_name = os.path.join(yara_check_meta_key_hash, yr.name) try: with open(rule_name, 'w') as tmp: tmp.write(rules[1]) with open(hash_file, "a") as n: n.write(yr.metas[k] + "\n") except Exception as e: print(e) except Exception as e: print(e)
import yaratool if __name__ == "__main__": ruletext = """rule DebuggerCheck__API : AntiDebug DebuggerCheck { meta: author="Some dude or dudette" weight = 1 strings: $ ="IsDebuggerPresent" condition: any of them}""" yr = yaratool.YaraRule(ruletext) print yr.normalize() print "Name: %s, Tags: %s, Author: %s" % (yr.name, "&".join( yr.tags), yr.metas['author']) print "Strings: " for string in yr.strings: print " %s" % (string) print "Condition: " for condition in yr.conditions: print " %s" % (condition) print yr.hash()
def check_meta_key(self, filepath): try: f = open(filepath, 'rb') rule = f.read() try: yr = yaratool.YaraRule(rule) except BaseException, e: print e if not yr.strings: return [False, 1004, "yara_strings"] if not yr.conditions: return [False, 1004, "yara_condition"] print len(yr.metas.keys()), "5===" if len(yr.metas.keys()) == 10: for key in yr.metas.keys(): if key == "judge": if yr.metas[key][1:-1] == "unknown" or yr.metas[key][ 1:-1] == "white" or yr.metas[key][ 1:-1] == "black": continue else: return [False, 1003, key, filepath] if key == "threatname": ret = [] ret = self.check_threatname(yr.metas, key, filepath) if not ret[0]: return ret continue if key == "threattype": if not yr.metas[key][1:-1]: return [False, 1004, key, filepath] if "threatname" not in yr.metas.keys(): return [False, 1015, key, filepath] ret = self.check_threatname(yr.metas, "threatname", filepath) if not ret[0]: return [False, 1016, key, filepath] if '/' in yr.metas["threatname"]: if not yr.metas[key][1:-1].upper( ) in key_threattype: return [False, 1005, key, filepath] continue else: if not yr.metas[key][1:-1].upper( ) in behavior_threattype: return [False, 1018, key, filepath] continue if key == "family": if "threatname" not in yr.metas.keys(): return [False, 1015, key, filepath] ret = self.check_threatname(yr.metas, "threatname", filepath) if not ret[0]: return [False, 1016, key, filepath] if not yr.metas[key][1:-1]: return [False, 1004, key, filepath] if '.' not in yr.metas["threatname"]: return [False, 1012, key, filepath] if '/' in yr.metas["threatname"]: if yr.metas[key][1:-1] != yr.metas["threatname"][ 1:-1].split('/')[1].split('.')[1]: return [False, 1008, key, filepath] continue else: if yr.metas[key][1:-1] != "unknown": return [False, 1014, key, filepath] continue if key == "hacker": if not yr.metas[key][1:-1]: return [False, 1004, key, filepath] else: continue if key == "refer": if not yr.metas[key][1:-1]: return [False, 1004, key, filepath] if ',' in yr.metas[key][1:-1]: refer_md5 = yr.metas[key][1:-1].split(',') for md5 in refer_md5: if md5[:4] == "http": continue elif len(md5) != 32: return [False, 1010, key, filepath] continue else: if len(yr.metas[key][1:-1]) != 32: return [False, 1010, key, filepath] continue if key == "description": if not yr.metas[key][1:-1]: return [False, 1004, key, filepath] else: continue if key == "comment": if not yr.metas[key][1:-1]: return [False, 1004, key, filepath] else: continue if key == "author": if not yr.metas[key][1:-1]: return [False, 1004, key, filepath] else: continue if key == "date": if not yr.metas[key][1:-1]: return [False, 1004, key, filepath] else: continue else: return [False, 1011, filepath] return [True] else: return [False, 1017, filepath]
def check_meta_key(self, filepath, savetime): try: # rb f = open(filepath, 'r') rules = f.readline() if rules.find('-') != -1: return [False, 1024, filepath] f.seek(0) rule = f.read() try: yr = yaratool.YaraRule(rule) if not yr.strings: return [False, 1004, "yara_strings"] if not yr.conditions: return [False, 1004, "yara_condition"] if len(yr.metas.keys()) >= 10: for key in yr.metas.keys(): if key == "judge": if yr.metas[key] in judge_list: continue else: return [False, 1003, key, filepath] if key == "threatname": ret = [] ret = self.check_threatname( yr.metas, key, filepath) if not ret[0]: return ret continue if key == "threattype": if not yr.metas[key]: return [False, 1004, key, filepath] if "threatname" not in yr.metas.keys(): return [False, 1015, key, filepath] ret = self.check_threatname( yr.metas, "threatname", filepath) if not ret[0]: return [False, 1016, key, filepath] if '/' in yr.metas["threatname"]: if ',' in yr.metas[key]: list1 = (yr.metas[key]).split(',') for i in range(len(list1)): if not list1[i].upper( ) in key_threattype: return [False, 1005, key, filepath] else: if not yr.metas[key].upper( ) in key_threattype: return [False, 1005, key, filepath] continue else: if not yr.metas[key].upper( ) in behavior_threattype: return [False, 1018, key, filepath] continue if key == "family": if "threatname" not in yr.metas.keys(): return [False, 1015, key, filepath] ret = self.check_threatname( yr.metas, "threatname", filepath) if not ret[0]: return [False, 1016, key, filepath] if not yr.metas[key]: return [False, 1004, key, filepath] if '.' not in yr.metas["threatname"]: return [False, 1012, key, filepath] if '/' in yr.metas["threatname"]: if yr.metas[key] != yr.metas[ "threatname"].split('/')[1].split( '.')[1]: return [False, 1008, key, filepath] continue else: if yr.metas[key] != "unknown": return [False, 1014, key, filepath] continue if key == "hacker": if not yr.metas[key]: return [False, 1004, key, filepath] else: continue if key == "refer": if not yr.metas[key] or yr.metas[key] == "None": if self.cfg.upload.back_all: self.refpath = os.path.join( self.refdir, savetime) if not os.path.exists(self.refpath): os.makedirs(self.refpath) self.filename = filepath.split('/')[-1] path = os.path.join( self.refpath, self.filename) shutil.copy(filepath, path) return [False, 1004, key, filepath] if ',' in yr.metas[key]: refer_md5 = yr.metas[key].split(',') for md5 in refer_md5: if md5[:4] == "http": continue elif len(md5) != 32: return [False, 1010, key, filepath] continue else: if len(yr.metas[key]) != 32: return [False, 1010, key, filepath] continue if key == "description": if not yr.metas[key]: return [False, 1004, key, filepath] else: continue if key == "comment": if not yr.metas[key]: return [False, 1004, key, filepath] else: continue if key == "author": if not yr.metas[key]: return [False, 1004, key, filepath] else: continue if key == "date": if not yr.metas[key]: return [False, 1004, key, filepath] else: continue else: continue return [True] else: return [False, 1017, filepath] except BaseException as e: return [False, str(e), filepath] except Exception as e: return [False, str(e), filepath]
def testRuleNormalization(self): ruletext = r"""rule dbgdetect_procs : dbgdetect { meta: author = "AlienVault Labs" type = "info" severity = 1 description = "Debugger detection tricks" strings: $proc1 = "wireshark" nocase ascii wide $proc2 = "filemon" nocase ascii wide $proc3 = "procexp" nocase ascii wide $proc4 = "procmon" nocase ascii wide $proc5 = "regmon" nocase ascii wide $proc6 = "idag" nocase ascii wide $proc7 = "immunitydebugger" nocase ascii wide $proc8 = "ollydbg" nocase ascii wide $proc9 = "petools" nocase ascii wide $test1 = "A\x0aB\x0aC\x0aD" nocase condition: 2 of them }""" yn = yaratool.YaraRule(ruletext) self.failUnlessEqual("dbgdetect_procs", yn.name) self.failUnlessEqual("\"AlienVault Labs\"", yn.metas['author']) self.failUnlessEqual([ "$proc1 = \"wireshark\" nocase ascii wide", "$proc2 = \"filemon\" nocase ascii wide", "$proc3 = \"procexp\" nocase ascii wide", "$proc4 = \"procmon\" nocase ascii wide", "$proc5 = \"regmon\" nocase ascii wide", "$proc6 = \"idag\" nocase ascii wide", "$proc7 = \"immunitydebugger\" nocase ascii wide", "$proc8 = \"ollydbg\" nocase ascii wide", "$proc9 = \"petools\" nocase ascii wide", "$test1 = \"A\\x0aB\\x0aC\\x0aD\" nocase", ], yn.strings) self.failUnlessEqual(["2 of them"], yn.conditions) self.failUnlessEqual( r"""rule dbgdetect_procs : dbgdetect { meta: author = "AlienVault Labs" description = "Debugger detection tricks" severity = 1 type = "info" strings: $proc1 = "wireshark" nocase ascii wide $proc2 = "filemon" nocase ascii wide $proc3 = "procexp" nocase ascii wide $proc4 = "procmon" nocase ascii wide $proc5 = "regmon" nocase ascii wide $proc6 = "idag" nocase ascii wide $proc7 = "immunitydebugger" nocase ascii wide $proc8 = "ollydbg" nocase ascii wide $proc9 = "petools" nocase ascii wide $test1 = "A\x0aB\x0aC\x0aD" nocase condition: 2 of them }""", yn.normalize()) self.failUnlessEqual("yn01:fc93b999aa0d00b1:5cf26fa932", yn.hash()) yn.tags = ['tag1', 'tag2', 'tag3'] self.failUnlessEqual( r"""rule dbgdetect_procs : tag1 tag2 tag3 { meta: author = "AlienVault Labs" description = "Debugger detection tricks" severity = 1 type = "info" strings: $proc1 = "wireshark" nocase ascii wide $proc2 = "filemon" nocase ascii wide $proc3 = "procexp" nocase ascii wide $proc4 = "procmon" nocase ascii wide $proc5 = "regmon" nocase ascii wide $proc6 = "idag" nocase ascii wide $proc7 = "immunitydebugger" nocase ascii wide $proc8 = "ollydbg" nocase ascii wide $proc9 = "petools" nocase ascii wide $test1 = "A\x0aB\x0aC\x0aD" nocase condition: 2 of them }""", yn.normalize()) self.failUnlessEqual("yn01:fc93b999aa0d00b1:5cf26fa932", yn.hash())