예제 #1
0
 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)
예제 #2
0
    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)
예제 #3
0
 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")
예제 #4
0
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)
예제 #6
0
    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)
예제 #8
0
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()
예제 #9
0
    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]
예제 #11
0
    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())