mirror of
https://github.com/ditekshen/detection
synced 2026-06-08 13:49:35 +00:00
Add scripts, update README, minor addition to Yara/ClamAV rule
This commit is contained in:
@@ -4,4 +4,8 @@ A set of interrelated network and host detection rules with the aim of improving
|
||||
|
||||
## Supported Rules
|
||||
|
||||
Currently, Snort, Yara and ClamAV rules are supported. Additional singatures and formats are work in progress.
|
||||
Currently, Snort, Yara and ClamAV rules are supported. Additional singatures and formats are work in progress.
|
||||
|
||||
## Scripts
|
||||
|
||||
Currently, only scripts available are used to aid in auto-generation of hash-based and certificate-based Yara rules.
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ ditekSHen.INDICATOR.RTF.AncalogExploitBuilderDocument;Engine:51-255,Target:0;0&1
|
||||
ditekSHen.INDICATOR.RTF.EquationBITSAdminDownloader;Engine:81-255,Container:CL_TYPE_RTF,Target:2;0&1&(2|3);6269747361646d696e::i;6571756174696f6e::iaw;2f7472616e73666572;2f646f776e6c6f6164
|
||||
ditekSHen.INDICATOR.RTF.EquationPowerShellDownloader;Engine:81-255,Container:CL_TYPE_RTF,Target:2;0&1;706f7765727368656c6c::i;6571756174696f6e::iaw
|
||||
ditekSHen.INDICATOR.RTF.EquationCertUtilDownloader;Engine:81-255,Container:CL_TYPE_RTF,Target:2;0&1;636572747574696c::i;6571756174696f6e::iaw
|
||||
ditekSHen.INDICATOR.OOXML.Excel4MacrosEXEC;Engine:79-255,Container:CL_TYPE_OOXML_XL,Target:0;0&(1|2|3)>1;3c786d3a6d6163726f7368656574;3e464f524d554c412e46494c4c28;3e524547495354455228;3e4558454328
|
||||
ditekSHen.INDICATOR.OOXML.Excel4MacrosEXEC;Engine:79-255,Container:CL_TYPE_OOXML_XL,Target:0;0&(1|2|3|4)>1;3c786d3a6d6163726f7368656574;3e464f524d554c412e46494c4c28;3e524547495354455228;3e4558454328;3e52554e28
|
||||
ditekSHen.INDICATOR.Packed.NyanXCAT-CSharpLoader;Engine:51-255,Target:1;0;0050726f6772616d004c6f61646572004e79616e00
|
||||
ditekSHen.MALWARE.Win.Trojan.Firebird-HiveRAT;Engine:51-255,Target:1;(0|1|2|3)|(4&5&6&7&8&9&10&11&12)>5;46697265626972642052656d6f74652041646d696e697374726174696f6e20546f6f6c::w;57656c636f6d6520746f2046697265626972642120596f75722073797374656d2069732063757272656e746c79206265696e67206d6f6e69746f726564::w;486976652052656d6f74652041646d696e697374726174696f6e20546f6f6c::w;57656c636f6d6520746f20486976652120596f75722073797374656d2069732063757272656e746c79206265696e67206d6f6e69746f726564::w;5245504c41434554484553454b45595354524f4b4553::w;5f454e41424c455f50524f46494c494e47::w;4b65796c6f675375626a656374::w;77656263616d656e61626c6564;73637265656e6c6f6773;6d6f6e69746f726f6e;5443505f5441424c455f4f574e45525f5049445f414c4c;73637265656e47726162;656e63727970746564636f6e6e656374696f6e
|
||||
ditekSHen.MALWARE.Win.Trojan.AcridRain;Engine:51-255,Target:1;0&1&2&3&4&5&6&7&8&9;2f4c6962732e7a6970;2f55706c6f61642f;74656d706c6f67696d;74656d706c6f67696b;74656d70505368;74656d70505768;436f6f6b696573;53454c454354202a2046524f4d20;54656c656772616d2e657865;633a5c75736572735c69676f72315c::w
|
||||
@@ -114,4 +114,4 @@ ditekSHen.MALWARE.Linux.Trojan.HiddenWasp-ELF;Engine:51-255,Target:6;(0&1&2&3&4)
|
||||
ditekSHen.MALWARE.Linux.Trojan.WellMess_Golang;Engine:51-255,Target:6;0&1&2&3&4&5;3c3b686561643b3e3c3b7469746c653b3e;3c3b7469746c653b3e3c3b736572766963653b3e;5f2f686f6d652f7562756e74752f476f50726f6a6563742f7372632f626f742f626f746c6962;6e65742f687474702e282a70657273697374436f6e6e292e72656164526573706f6e7365;6e65742f687474702f636f6f6b69656a61722e282a4a6172292e536574436f6f6b696573;687474703a2f2f696e76616c69646c6f6f6b7570
|
||||
ditekSHen.MALWARE.Linux.Trojan.PLEAD;Engine:51-255,Target:6;0&1&2&3&4&5;4346696c655472616e73666572;4346696c654d616e61676572;43506f7274466f7277617264;43506f7274466f72776172644d616e61676572;4352656d6f74655368656c6c;43536f636b436c69656e74
|
||||
ditekSHen.MALWARE.Aix.Trojan.FastcachInjector;Engine:51-255,Target:0;0&1&2&3&4&5&6&7&8;0:01f7;73746f72655f636f6e666967;6c6f61645f636f6e666967;66696c655f64756d70;2f746d702f2e4943452d756e69782f636f6e6669675f2564;2f746d702f2e4943452d756e69782f44554d5025582e646174;496e6a6563742053746172740a;2e6f75745f6c6f67;2e6f75745f72656773
|
||||
ditekSHen.MALWARE.Aix.Trojan.FastcachDLL;Engine:51-255,Target:0;0&1&2&3&4&5&6&7&8;0:01f7;2f746d702f2e4943452d756e69782f746d7025645f25642e6c6f67;2f746d702f2e4943452d756e69782f746d70777425645f25642e6c6f67;2f746d702f2e4943452d756e69782f746d70726425645f25642e6c6f;6f75745f64756d705f6c6f67;4d53472044554d50;686f6f6b5f66756e635f6164647228257829;6f72675f66756e6328257029;636f70795f66756e6328257829
|
||||
ditekSHen.MALWARE.Aix.Trojan.FastcachDLL;Engine:51-255,Target:0;0&1&2&3&4&5&6&7&8;0:01f7;2f746d702f2e4943452d756e69782f746d7025645f25642e6c6f67;2f746d702f2e4943452d756e69782f746d70777425645f25642e6c6f67;2f746d702f2e4943452d756e69782f746d70726425645f25642e6c6f;6f75745f64756d705f6c6f67;4d53472044554d50;686f6f6b5f66756e635f6164647228257829;6f72675f66756e6328257029;636f70795f66756e6328257829
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import csv
|
||||
import codecs
|
||||
import requests
|
||||
import argparse
|
||||
|
||||
from contextlib import closing
|
||||
|
||||
__author__ = "ditekSHen"
|
||||
__copyright__ = "Copyright 2020, ditekShen"
|
||||
__version__ = "1.0"
|
||||
__reference__ = "https://github.com/ditekshen"
|
||||
|
||||
FILE_URL = "https://bazaar.abuse.ch/export/csv/cscb/"
|
||||
|
||||
def parse_csv(infile=None):
|
||||
cert_data = list()
|
||||
if infile:
|
||||
infile = os.path.join(os.path.dirname(__file__), infile)
|
||||
try:
|
||||
with open(infile, 'r', encoding='utf-8') as csvfile:
|
||||
reader = csv.reader(csvfile, delimiter=',', quotechar='"', skipinitialspace=True)
|
||||
try:
|
||||
for row in reader:
|
||||
if not row[0].startswith('#'):
|
||||
cert = dict()
|
||||
cert["serial_number"] = row[1]
|
||||
cert["thumbprint"] = row[2]
|
||||
cert["subject_cn"] = row[4]
|
||||
cert["reason"] = row[8]
|
||||
cert_data.append(cert)
|
||||
except IndexError as err:
|
||||
print("Input file is potentially not a CSV file")
|
||||
raise SystemExit(err)
|
||||
except IOError as err:
|
||||
raise SystemExit(err)
|
||||
|
||||
return cert_data
|
||||
else:
|
||||
try:
|
||||
with closing(requests.get(FILE_URL, stream=True)) as response:
|
||||
if response.status_code == 200:
|
||||
reader = csv.reader(codecs.iterdecode(response.iter_lines(),'utf-8'), delimiter=',', quotechar='"', skipinitialspace=True)
|
||||
try:
|
||||
for row in reader:
|
||||
if not row[0].startswith('#'):
|
||||
cert = dict()
|
||||
cert["serial_number"] = row[1]
|
||||
cert["thumbprint"] = row[2]
|
||||
cert["subject_cn"] = row[4]
|
||||
cert["reason"] = row[8]
|
||||
cert_data.append(cert)
|
||||
except IndexError as err:
|
||||
print("Response data is potentially not CSV formatted")
|
||||
raise SystemExit(err)
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise SystemExit(err)
|
||||
|
||||
return cert_data
|
||||
|
||||
def write_yara(iocs, outfile):
|
||||
rules = str()
|
||||
|
||||
try:
|
||||
fw = open(outfile, 'w')
|
||||
except IOError:
|
||||
print("Could not open file for writting output Yara rules file")
|
||||
|
||||
file_header = "/*\n"
|
||||
file_header += " Auto-generated certificate-based Yara rules from Abuse.ch MalwareBazar Code Signing Certificate Blocklist\n"
|
||||
file_header += " Author: Automatically generated by MBCSCBYar (ditekSHen)\n"
|
||||
file_header += " Reference: https://bazaar.abuse.ch/faq/#cscb\n"
|
||||
file_header += " Reference: https://github.com/ditekshen\n"
|
||||
file_header += "*/\n\n"
|
||||
fw.write(file_header)
|
||||
|
||||
fw.write('import "pe"\n\n')
|
||||
|
||||
for cert in iocs:
|
||||
rule_name = "rule INDICATOR_KB_CERT_%s {\n" % cert["serial_number"].lower()
|
||||
rule_meta = " meta:\n"
|
||||
rule_meta += " author = \"ditekSHen\"\n"
|
||||
rule_meta += " description = \"Detects executables signed with stolen, revoked or invalid certificates\"\n"
|
||||
rule_meta += " thumbprint = \"%s\"\n" % cert["thumbprint"].lower()
|
||||
rule_meta += " reason = \"%s\"\n" % cert["reason"]
|
||||
rule_meta += " reference = \"https://bazaar.abuse.ch/faq/#cscb\"\n"
|
||||
rule_condition = " condition:\n"
|
||||
rule_condition += " uint16(0) == 0x5a4d and\n"
|
||||
rule_condition += " for any i in (0..pe.number_of_signatures): (\n"
|
||||
rule_condition += " pe.signatures[i].subject contains \"%s\" and\n" % cert["subject_cn"]
|
||||
rule_condition += " pe.signatures[i].serial == \"%s\"\n" % ':'.join(cert["serial_number"][i:i + 2] for i in range(0, len(cert["serial_number"]), 2)).lower()
|
||||
rule_condition += " )\n"
|
||||
rule_end = "}\n\n"
|
||||
|
||||
rules += rule_name + rule_meta + rule_condition + rule_end
|
||||
|
||||
fw.write(rules)
|
||||
|
||||
try:
|
||||
fw.close()
|
||||
except IOError:
|
||||
print("Could not close output Yara rules file")
|
||||
|
||||
def main():
|
||||
usage_text = '''Example Usage:
|
||||
mbcscb_to_yara.py - Download CSCB CSV file from URL and write Yara rules file using default file name (defaults)
|
||||
mbcscb_to_yara.py -o name.yar - Download CSCB CSV file from URL and save generated Yara rules file using custom name
|
||||
mbcscb_to_yara.py -i cscb.csv - Read local CSCB CSV file and write Yara rules file using default file name
|
||||
mbcscb_to_yara.py -i cscb.csv -o name.yar - Read local CSCB CSV file and and save generated Yara rules file using custom name'''
|
||||
|
||||
parser = argparse.ArgumentParser(description='Generate Yara rules from Abuse.ch MalwareBazar Code Signing Certificate Blocklist (CSCB)',
|
||||
epilog=usage_text, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument('-i', '--input', type=str, metavar='INPUT', required=False, action='store', help='Input CSCB CSV local file',)
|
||||
parser.add_argument('-o', '--output', type=str, metavar='OUTPUT', required=False, default='certificates.yar', help='Output Yara rules file name')
|
||||
args = parser.parse_args()
|
||||
|
||||
cert_data = parse_csv(args.input)
|
||||
if len(cert_data) > 0:
|
||||
write_yara(cert_data, args.output)
|
||||
else:
|
||||
print("No certificate IOCs found, or something went wrong!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import csv
|
||||
import argparse
|
||||
|
||||
__author__ = "ditekSHen"
|
||||
__copyright__ = "Copyright 2020, ditekShen"
|
||||
__version__ = "1.0"
|
||||
__reference__ = "https://github.com/ditekshen"
|
||||
|
||||
def parse_csv(infile=None,hashtype='md5'):
|
||||
samples = list()
|
||||
if infile:
|
||||
infile = os.path.join(os.path.dirname(__file__), infile)
|
||||
try:
|
||||
with open(infile, 'r', encoding='utf-8') as csvfile:
|
||||
reader = csv.reader(csvfile, delimiter=',', quotechar='"', skipinitialspace=True)
|
||||
try:
|
||||
for row in reader:
|
||||
if not row[0].startswith('#'):
|
||||
sample = dict()
|
||||
if ("dosexec" or "executable" or "exe") in row[7] and ("exe" or "dll" or "elf") in row[6]:
|
||||
sample["first_seen"] = row[0]
|
||||
sample["md5"] = row[2]
|
||||
sample["sha1"] = row[3]
|
||||
sample["sha2"] = row[1]
|
||||
sample["filetype"] = row[6]
|
||||
sample["mimetype"] = row[7]
|
||||
sample["signature"] = row[8]
|
||||
sample["imphash"] = row[11]
|
||||
sample["ssdeep"] = row[12]
|
||||
|
||||
samples.append(sample)
|
||||
except IndexError as err:
|
||||
print("Input file is potentially not a CSV file")
|
||||
raise SystemExit(err)
|
||||
except IOError as err:
|
||||
raise SystemExit(err)
|
||||
|
||||
return samples
|
||||
else:
|
||||
return None
|
||||
|
||||
def write_yara(samples, hashtype, minsize, maxsize, outfile):
|
||||
rules = str()
|
||||
|
||||
try:
|
||||
fw = open(outfile, 'w')
|
||||
except IOError:
|
||||
print("Could not open file for writting output Yara rules file")
|
||||
|
||||
file_header = "/*\n"
|
||||
file_header += " Auto-generated hash-based Yara rules for executables (exe, dll, elf) from Abuse.ch MalwareBazar\n"
|
||||
file_header += " Author: Automatically generated by MBYar (ditekSHen)\n"
|
||||
file_header += " Reference: https://bazaar.abuse.ch/faq/\n"
|
||||
file_header += " Reference: https://github.com/ditekshen\n"
|
||||
file_header += "*/\n\n"
|
||||
fw.write(file_header)
|
||||
|
||||
fw.write('import "hash"\n\n')
|
||||
|
||||
rule_name_prefix = "rule INDICATOR_MB_Hash_"
|
||||
for sample in samples:
|
||||
if hashtype == "md5":
|
||||
rule_name = "rule INDICATOR_MB_Hash_%s {\n" % sample["md5"].lower()
|
||||
elif hashtype == "sha1":
|
||||
rule_name = "rule INDICATOR_MB_Hash_%s {\n" % sample["sha1"].lower()
|
||||
elif hashtype == "sha2":
|
||||
rule_name = "rule INDICATOR_MB_Hash_%s {\n" % sample["sha2"].lower()
|
||||
rule_meta = " meta:\n"
|
||||
rule_meta += " author = \"ditekSHen\"\n"
|
||||
rule_meta += " description = \"Detects malicious sample based on known hash from Abuse.ch MalwareBazar\"\n"
|
||||
rule_meta += " first_seen = \"%s\"\n" % sample["first_seen"].lower()
|
||||
rule_meta += " signature = \"%s\"\n" % sample["signature"]
|
||||
rule_meta += " md5 = \"%s\"\n" % sample["md5"].lower()
|
||||
rule_meta += " sha1 = \"%s\"\n" % sample["sha1"].lower()
|
||||
rule_meta += " sha2 = \"%s\"\n" % sample["sha2"].lower()
|
||||
if len(sample["imphash"]) == 32:
|
||||
rule_meta += " imphash = \"%s\"\n" % sample["imphash"].lower()
|
||||
rule_meta += " ssdeep = \"%s\"\n" % sample["ssdeep"]
|
||||
rule_condition = " condition:\n"
|
||||
if ("exe" or "dll") in sample["filetype"]:
|
||||
rule_condition += " uint16(0) == 0x5a4d and\n"
|
||||
elif ("elf") in sample["filetype"]:
|
||||
rule_condition += " uint16(0) == 0x457f and\n"
|
||||
rule_condition += " filesize > {0}KB and filesize < {1}KB and\n".format(minsize, maxsize)
|
||||
if hashtype == "md5":
|
||||
rule_condition += " hash.md5(0,filesize) == \"%s\"\n" % sample["md5"]
|
||||
elif hashtype == "sha1":
|
||||
rule_condition += " hash.sha1(0,filesize) == \"%s\"\n" % sample["sha1"]
|
||||
elif hashtype == "sha2":
|
||||
rule_condition += " hash.sha256(0,filesize) == \"%s\"\n" % sample["sha2"]
|
||||
rule_end = "}\n\n"
|
||||
|
||||
rules += rule_name + rule_meta + rule_condition + rule_end
|
||||
|
||||
fw.write(rules)
|
||||
|
||||
try:
|
||||
fw.close()
|
||||
except IOError:
|
||||
print("Could not close output Yara rules file")
|
||||
|
||||
def main():
|
||||
usage_text = '''Example Usage:
|
||||
mbfyar.py -i full.csv - Generate Yara rules from MalwareBazar CSV file (defaults - hash: md5, minsize:100, maxsize:2000)
|
||||
mbfyar.py -H sha1 -i full.csv - Generate SHA1-based Yara rules from MalwareBazar CSV file
|
||||
mbyar.py -n 500 -x 5000 -i full.csv -o output.yar - Generate MD5-based Yara rules limiting matches to file size range to custom output file name'''
|
||||
|
||||
parser = argparse.ArgumentParser(description='Generate Yara hash rules for executables (exe, dll, elf) from Absue.ch MalwareBazar', epilog=usage_text, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument('-H', '--hash', help='Hash type to generate Yara rules against', type=str, metavar="HASH", required=False, default="md5", choices=['md5', 'sha1', 'sha2'])
|
||||
parser.add_argument('-n', '--minsize', type=int, metavar='SIZE', required=False, action='store', default=100, help='Minimum file size in kilobytes (KB)')
|
||||
parser.add_argument('-x', '--maxsize', type=int, metavar='SIZE', required=False, action='store', default=2000, help='Maximum file size in kilobytes (KB)')
|
||||
parser.add_argument('-i', '--input', type=str, metavar='INPUT', required=True, action='store', help='Input full dump from Absue.ch MalwareBazar')
|
||||
parser.add_argument('-o', '--output', type=str, metavar='OUTPUT', required=False, default='hashes.yar', help='Output Yara rules file name')
|
||||
args = parser.parse_args()
|
||||
|
||||
data = parse_csv(args.input)
|
||||
if data and len(data) > 0:
|
||||
write_yara(data, args.hash, args.minsize, args.maxsize, args.output)
|
||||
else:
|
||||
print("No hash IOCs found, or something went wrong!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -855,6 +855,7 @@ rule INDICATOR_OOXML_Excel4Macros_EXEC {
|
||||
$s1 = ">FORMULA.FILL(" ascii nocase
|
||||
$s2 = ">REGISTER(" ascii nocase
|
||||
$s3 = ">EXEC(" ascii nocase
|
||||
$s4 = ">RUN(" ascii nocase
|
||||
condition:
|
||||
uint32(0) == 0x6d783f3c and $ms and 2 of ($s*)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user