From 381aee2580e3171e5540d85f2d4b65576ca61952 Mon Sep 17 00:00:00 2001 From: Ryan O'Horo <10855297+ryanohoro@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:18:51 -0600 Subject: [PATCH 1/4] Update Scanner class to provide options to init(), update scanners to include updated init() --- src/python/strelka/scanners/scan_antiword.py | 3 ++ src/python/strelka/scanners/scan_base64.py | 3 ++ src/python/strelka/scanners/scan_base64_pe.py | 3 ++ src/python/strelka/scanners/scan_batch.py | 2 +- src/python/strelka/scanners/scan_bmp_eof.py | 3 ++ src/python/strelka/scanners/scan_bzip2.py | 3 ++ src/python/strelka/scanners/scan_ccn.py | 3 ++ src/python/strelka/scanners/scan_cuckoo.py | 2 +- src/python/strelka/scanners/scan_delay.py | 3 ++ src/python/strelka/scanners/scan_dmg.py | 3 ++ src/python/strelka/scanners/scan_docx.py | 21 ++++++++------ src/python/strelka/scanners/scan_donut.py | 3 ++ src/python/strelka/scanners/scan_elf.py | 3 ++ src/python/strelka/scanners/scan_email.py | 3 ++ .../strelka/scanners/scan_encrypted_doc.py | 3 ++ .../strelka/scanners/scan_encrypted_zip.py | 3 ++ src/python/strelka/scanners/scan_entropy.py | 3 ++ src/python/strelka/scanners/scan_exception.py | 2 +- src/python/strelka/scanners/scan_exiftool.py | 3 ++ .../strelka/scanners/scan_falcon_sandbox.py | 2 +- src/python/strelka/scanners/scan_footer.py | 3 ++ src/python/strelka/scanners/scan_gif.py | 3 ++ src/python/strelka/scanners/scan_gzip.py | 3 ++ src/python/strelka/scanners/scan_hash.py | 3 ++ src/python/strelka/scanners/scan_header.py | 3 ++ src/python/strelka/scanners/scan_html.py | 3 ++ src/python/strelka/scanners/scan_ini.py | 3 ++ src/python/strelka/scanners/scan_iqy.py | 3 ++ src/python/strelka/scanners/scan_iso.py | 29 ++++++++++--------- .../strelka/scanners/scan_jar_manifest.py | 3 ++ .../strelka/scanners/scan_javascript.py | 2 +- src/python/strelka/scanners/scan_jpeg.py | 3 ++ src/python/strelka/scanners/scan_json.py | 3 ++ .../strelka/scanners/scan_libarchive.py | 3 ++ src/python/strelka/scanners/scan_lnk.py | 15 ++++++---- src/python/strelka/scanners/scan_lsb.py | 3 ++ src/python/strelka/scanners/scan_lzma.py | 3 ++ src/python/strelka/scanners/scan_macho.py | 3 ++ src/python/strelka/scanners/scan_manifest.py | 3 ++ src/python/strelka/scanners/scan_msi.py | 3 ++ src/python/strelka/scanners/scan_nf.py | 3 ++ src/python/strelka/scanners/scan_ocr.py | 3 ++ src/python/strelka/scanners/scan_ole.py | 3 ++ src/python/strelka/scanners/scan_onenote.py | 3 ++ src/python/strelka/scanners/scan_pcap.py | 3 ++ src/python/strelka/scanners/scan_pdf.py | 3 ++ src/python/strelka/scanners/scan_pe.py | 27 +++++++++-------- src/python/strelka/scanners/scan_pgp.py | 27 +++++++++-------- src/python/strelka/scanners/scan_php.py | 2 +- src/python/strelka/scanners/scan_pkcs7.py | 3 ++ src/python/strelka/scanners/scan_plist.py | 3 ++ src/python/strelka/scanners/scan_png_eof.py | 3 ++ src/python/strelka/scanners/scan_qr.py | 3 ++ src/python/strelka/scanners/scan_rar.py | 6 ++-- src/python/strelka/scanners/scan_rpm.py | 3 ++ src/python/strelka/scanners/scan_rtf.py | 3 ++ src/python/strelka/scanners/scan_save.py | 2 +- src/python/strelka/scanners/scan_seven_zip.py | 3 ++ src/python/strelka/scanners/scan_strings.py | 2 +- src/python/strelka/scanners/scan_swf.py | 3 ++ src/python/strelka/scanners/scan_tar.py | 3 ++ src/python/strelka/scanners/scan_tlsh.py | 2 +- src/python/strelka/scanners/scan_tnef.py | 3 ++ src/python/strelka/scanners/scan_transcode.py | 3 ++ src/python/strelka/scanners/scan_udf.py | 3 ++ src/python/strelka/scanners/scan_upx.py | 3 ++ src/python/strelka/scanners/scan_url.py | 2 +- src/python/strelka/scanners/scan_vb.py | 2 +- src/python/strelka/scanners/scan_vba.py | 3 ++ src/python/strelka/scanners/scan_vhd.py | 3 ++ src/python/strelka/scanners/scan_vsto.py | 3 ++ src/python/strelka/scanners/scan_x509.py | 3 ++ src/python/strelka/scanners/scan_xl4ma.py | 3 ++ src/python/strelka/scanners/scan_xml.py | 3 ++ src/python/strelka/scanners/scan_yara.py | 2 +- src/python/strelka/scanners/scan_zip.py | 3 ++ src/python/strelka/scanners/scan_zlib.py | 3 ++ src/python/strelka/strelka.py | 9 ++++-- 78 files changed, 265 insertions(+), 70 deletions(-) diff --git a/src/python/strelka/scanners/scan_antiword.py b/src/python/strelka/scanners/scan_antiword.py index f217ec9b..b422824d 100644 --- a/src/python/strelka/scanners/scan_antiword.py +++ b/src/python/strelka/scanners/scan_antiword.py @@ -12,6 +12,9 @@ class ScanAntiword(strelka.Scanner): Defaults to '/tmp/'. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): tmp_directory = options.get("tmp_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_base64.py b/src/python/strelka/scanners/scan_base64.py index b2739430..4c6d143b 100644 --- a/src/python/strelka/scanners/scan_base64.py +++ b/src/python/strelka/scanners/scan_base64.py @@ -6,6 +6,9 @@ class ScanBase64(strelka.Scanner): """Decodes base64-encoded file.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): decoded = base64.b64decode(data) diff --git a/src/python/strelka/scanners/scan_base64_pe.py b/src/python/strelka/scanners/scan_base64_pe.py index 4323e78b..b2434201 100644 --- a/src/python/strelka/scanners/scan_base64_pe.py +++ b/src/python/strelka/scanners/scan_base64_pe.py @@ -8,6 +8,9 @@ class ScanBase64PE(strelka.Scanner): """Decodes base64-encoded file.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): with io.BytesIO(data) as encoded_file: extract_data = b"" diff --git a/src/python/strelka/scanners/scan_batch.py b/src/python/strelka/scanners/scan_batch.py index 8e096104..66bff761 100644 --- a/src/python/strelka/scanners/scan_batch.py +++ b/src/python/strelka/scanners/scan_batch.py @@ -13,7 +13,7 @@ class ScanBatch(strelka.Scanner): lexer: Pygments lexer ('batch') used to parse the file. """ - def init(self): + def init(self, options): self.lexer = lexers.get_lexer_by_name("batch") def scan(self, data, file, options, expire_at): diff --git a/src/python/strelka/scanners/scan_bmp_eof.py b/src/python/strelka/scanners/scan_bmp_eof.py index 0f72cacc..1ea6491e 100644 --- a/src/python/strelka/scanners/scan_bmp_eof.py +++ b/src/python/strelka/scanners/scan_bmp_eof.py @@ -7,6 +7,9 @@ class ScanBmpEof(strelka.Scanner): the expected marker. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): expectedSize = int.from_bytes(data[2:6], "little") actualSize = len(data) diff --git a/src/python/strelka/scanners/scan_bzip2.py b/src/python/strelka/scanners/scan_bzip2.py index 8fad65b3..d75a17df 100644 --- a/src/python/strelka/scanners/scan_bzip2.py +++ b/src/python/strelka/scanners/scan_bzip2.py @@ -7,6 +7,9 @@ class ScanBzip2(strelka.Scanner): """Decompresses bzip2 files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): with io.BytesIO(data) as bzip2_io: with bz2.BZ2File(filename=bzip2_io) as bzip2_obj: diff --git a/src/python/strelka/scanners/scan_ccn.py b/src/python/strelka/scanners/scan_ccn.py index 08c63fac..96f29fb9 100644 --- a/src/python/strelka/scanners/scan_ccn.py +++ b/src/python/strelka/scanners/scan_ccn.py @@ -22,6 +22,9 @@ def digits_of(n): def is_luhn_valid(self, card_number): return self.luhn_checksum(card_number) == 0 + def init(self, options): + pass + def scan(self, data, file, options, expire_at): # re_amex = re.compile(rb"[^0-9](3[47][0-9]{13})[^0-9]") # re_disc = re.compile(rb"[^0-9](6[0-9]{15})[^0-9]") diff --git a/src/python/strelka/scanners/scan_cuckoo.py b/src/python/strelka/scanners/scan_cuckoo.py index 205aaecf..a8ef0310 100644 --- a/src/python/strelka/scanners/scan_cuckoo.py +++ b/src/python/strelka/scanners/scan_cuckoo.py @@ -33,7 +33,7 @@ class ScanCuckoo(strelka.Scanner): password: See description above. """ - def init(self): + def init(self, options): self.username = None self.password = None self.auth_check = False diff --git a/src/python/strelka/scanners/scan_delay.py b/src/python/strelka/scanners/scan_delay.py index 5cd6d181..b174ab3b 100644 --- a/src/python/strelka/scanners/scan_delay.py +++ b/src/python/strelka/scanners/scan_delay.py @@ -6,6 +6,9 @@ class ScanDelay(strelka.Scanner): """Delays scanner execution.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): delay = options.get("delay", 5.0) diff --git a/src/python/strelka/scanners/scan_dmg.py b/src/python/strelka/scanners/scan_dmg.py index 07c277f3..3a555501 100644 --- a/src/python/strelka/scanners/scan_dmg.py +++ b/src/python/strelka/scanners/scan_dmg.py @@ -13,6 +13,9 @@ class ScanDmg(strelka.Scanner): EXCLUDED_ROOT_DIRS = ["[SYSTEM]"] + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 1000) tmp_directory = options.get("tmp_file_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_docx.py b/src/python/strelka/scanners/scan_docx.py index ae1baabd..b4c8781e 100644 --- a/src/python/strelka/scanners/scan_docx.py +++ b/src/python/strelka/scanners/scan_docx.py @@ -16,6 +16,9 @@ class ScanDocx(strelka.Scanner): Defaults to False. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): extract_text = options.get("extract_text", False) with io.BytesIO(data) as docx_io: @@ -30,17 +33,17 @@ def scan(self, data, file, options, expire_at): self.event["identifier"] = docx_doc.core_properties.identifier self.event["keywords"] = docx_doc.core_properties.keywords self.event["language"] = docx_doc.core_properties.language - self.event["last_modified_by"] = ( - docx_doc.core_properties.last_modified_by - ) + self.event[ + "last_modified_by" + ] = docx_doc.core_properties.last_modified_by if docx_doc.core_properties.last_printed is not None: - self.event["last_printed"] = ( - docx_doc.core_properties.last_printed.isoformat() - ) + self.event[ + "last_printed" + ] = docx_doc.core_properties.last_printed.isoformat() if docx_doc.core_properties.modified is not None: - self.event["modified"] = ( - docx_doc.core_properties.modified.isoformat() - ) + self.event[ + "modified" + ] = docx_doc.core_properties.modified.isoformat() self.event["revision"] = docx_doc.core_properties.revision self.event["subject"] = docx_doc.core_properties.subject self.event["title"] = docx_doc.core_properties.title diff --git a/src/python/strelka/scanners/scan_donut.py b/src/python/strelka/scanners/scan_donut.py index 0e13afe4..a04303da 100644 --- a/src/python/strelka/scanners/scan_donut.py +++ b/src/python/strelka/scanners/scan_donut.py @@ -10,6 +10,9 @@ class ScanDonut(strelka.Scanner): """Extracts configs and modules from donut payloads""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): tmp_directory = options.get("tmp_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_elf.py b/src/python/strelka/scanners/scan_elf.py index 6a373312..a3f604f5 100644 --- a/src/python/strelka/scanners/scan_elf.py +++ b/src/python/strelka/scanners/scan_elf.py @@ -9,6 +9,9 @@ class ScanElf(strelka.Scanner): """Collects metadata from ELF files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): elf = ELF.parse(raw=list(data)) diff --git a/src/python/strelka/scanners/scan_email.py b/src/python/strelka/scanners/scan_email.py index b5bea6a8..4b7149e5 100644 --- a/src/python/strelka/scanners/scan_email.py +++ b/src/python/strelka/scanners/scan_email.py @@ -32,6 +32,9 @@ class ScanEmail(strelka.Scanner): including inline images. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): """ Processes the email, extracts metadata and attachments, and optionally generates a thumbnail. diff --git a/src/python/strelka/scanners/scan_encrypted_doc.py b/src/python/strelka/scanners/scan_encrypted_doc.py index 1e2b0f92..b2ef914f 100644 --- a/src/python/strelka/scanners/scan_encrypted_doc.py +++ b/src/python/strelka/scanners/scan_encrypted_doc.py @@ -119,6 +119,9 @@ class ScanEncryptedDoc(strelka.Scanner): Defaults to /etc/strelka/passwords.dat. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): jtr_path = options.get("jtr_path", "/jtr/") tmp_directory = options.get("tmp_file_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_encrypted_zip.py b/src/python/strelka/scanners/scan_encrypted_zip.py index 1a816732..bd2b4385 100644 --- a/src/python/strelka/scanners/scan_encrypted_zip.py +++ b/src/python/strelka/scanners/scan_encrypted_zip.py @@ -109,6 +109,9 @@ class ScanEncryptedZip(strelka.Scanner): Defaults to /etc/strelka/passwords.dat. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): jtr_path = options.get("jtr_path", "/jtr/") tmp_directory = options.get("tmp_file_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_entropy.py b/src/python/strelka/scanners/scan_entropy.py index 4f64c4dc..31db945f 100644 --- a/src/python/strelka/scanners/scan_entropy.py +++ b/src/python/strelka/scanners/scan_entropy.py @@ -6,5 +6,8 @@ class ScanEntropy(strelka.Scanner): """Calculates entropy of files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): self.event["entropy"] = entropy.shannon_entropy(data) diff --git a/src/python/strelka/scanners/scan_exception.py b/src/python/strelka/scanners/scan_exception.py index f5e2707b..8cb1f691 100644 --- a/src/python/strelka/scanners/scan_exception.py +++ b/src/python/strelka/scanners/scan_exception.py @@ -14,7 +14,7 @@ class ScanException(strelka.Scanner): Defaults to 0 (unlimited). """ - def init(self): + def init(self, options): pass def scan(self, data, file, options, expire_at): diff --git a/src/python/strelka/scanners/scan_exiftool.py b/src/python/strelka/scanners/scan_exiftool.py index 2b4dc832..fb40cf1f 100644 --- a/src/python/strelka/scanners/scan_exiftool.py +++ b/src/python/strelka/scanners/scan_exiftool.py @@ -16,6 +16,9 @@ class ScanExiftool(strelka.Scanner): Defaults to '/tmp/'. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): tmp_directory = options.get("tmp_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_falcon_sandbox.py b/src/python/strelka/scanners/scan_falcon_sandbox.py index 0806ea83..7859483f 100644 --- a/src/python/strelka/scanners/scan_falcon_sandbox.py +++ b/src/python/strelka/scanners/scan_falcon_sandbox.py @@ -38,7 +38,7 @@ class ScanFalconSandbox(strelka.Scanner): Defaults to [100] """ - def init(self): + def init(self, options): self.api_key = None self.api_secret = None self.server = "" diff --git a/src/python/strelka/scanners/scan_footer.py b/src/python/strelka/scanners/scan_footer.py index f0f5c551..bc8d3c83 100644 --- a/src/python/strelka/scanners/scan_footer.py +++ b/src/python/strelka/scanners/scan_footer.py @@ -12,6 +12,9 @@ class ScanFooter(strelka.Scanner): encodings: List of which fields/encodings should be emitted, one of classic, raw, hex, backslash """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): length = options.get("length", 50) encodings = options.get("encodings", ["classic"]) diff --git a/src/python/strelka/scanners/scan_gif.py b/src/python/strelka/scanners/scan_gif.py index 04ba7a9b..e333d3c9 100644 --- a/src/python/strelka/scanners/scan_gif.py +++ b/src/python/strelka/scanners/scan_gif.py @@ -7,6 +7,9 @@ class ScanGif(strelka.Scanner): This scanner extracts data that is inserted past the GIF trailer. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): if not data.endswith(b"\x00\x3b"): trailer_index = data.rfind(b"\x00\x3b") diff --git a/src/python/strelka/scanners/scan_gzip.py b/src/python/strelka/scanners/scan_gzip.py index 318a9364..dfa89834 100644 --- a/src/python/strelka/scanners/scan_gzip.py +++ b/src/python/strelka/scanners/scan_gzip.py @@ -8,6 +8,9 @@ class ScanGzip(strelka.Scanner): """Decompresses gzip files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): try: with io.BytesIO(data) as gzip_io: diff --git a/src/python/strelka/scanners/scan_hash.py b/src/python/strelka/scanners/scan_hash.py index b3ec6f2b..f972103e 100644 --- a/src/python/strelka/scanners/scan_hash.py +++ b/src/python/strelka/scanners/scan_hash.py @@ -9,6 +9,9 @@ class ScanHash(strelka.Scanner): """Calculates file hash values.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): self.event["md5"] = md5(data).hexdigest() self.event["sha1"] = sha1(data).hexdigest() diff --git a/src/python/strelka/scanners/scan_header.py b/src/python/strelka/scanners/scan_header.py index 4604e414..9959257f 100644 --- a/src/python/strelka/scanners/scan_header.py +++ b/src/python/strelka/scanners/scan_header.py @@ -12,6 +12,9 @@ class ScanHeader(strelka.Scanner): encodings: List of which fields/encodings should be emitted, one of classic, raw, hex, backslash """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): length = options.get("length", 50) encodings = options.get("encodings", ["classic"]) diff --git a/src/python/strelka/scanners/scan_html.py b/src/python/strelka/scanners/scan_html.py index 59a8100a..e73f20a8 100644 --- a/src/python/strelka/scanners/scan_html.py +++ b/src/python/strelka/scanners/scan_html.py @@ -15,6 +15,9 @@ class ScanHtml(strelka.Scanner): Defaults to 'html.parser'. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): parser = options.get("parser", "html.parser") max_hyperlinks = options.get("max_hyperlinks", 50) diff --git a/src/python/strelka/scanners/scan_ini.py b/src/python/strelka/scanners/scan_ini.py index ebc115c2..dab7e190 100644 --- a/src/python/strelka/scanners/scan_ini.py +++ b/src/python/strelka/scanners/scan_ini.py @@ -4,6 +4,9 @@ class ScanIni(strelka.Scanner): """Parses keys from INI files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): self.event["comments"] = [] self.event["keys"] = [] diff --git a/src/python/strelka/scanners/scan_iqy.py b/src/python/strelka/scanners/scan_iqy.py index c0cf03d6..4c00a30f 100644 --- a/src/python/strelka/scanners/scan_iqy.py +++ b/src/python/strelka/scanners/scan_iqy.py @@ -19,6 +19,9 @@ class ScanIqy(strelka.Scanner): Reference for IQY file format: https://learn.microsoft.com/en-us/office/vba/api/excel.querytable """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): """ Processes the provided IQY data to extract URLs. diff --git a/src/python/strelka/scanners/scan_iso.py b/src/python/strelka/scanners/scan_iso.py index b949e5cc..5478c687 100644 --- a/src/python/strelka/scanners/scan_iso.py +++ b/src/python/strelka/scanners/scan_iso.py @@ -11,6 +11,9 @@ class ScanIso(strelka.Scanner): """Extracts files from ISO files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 1000) @@ -27,19 +30,19 @@ def scan(self, data, file, options, expire_at): # Attempt to get Meta try: - self.event["meta"]["date_created"] = ( - self._datetime_from_volume_date(iso.pvd.volume_creation_date) - ) - self.event["meta"]["date_effective"] = ( - self._datetime_from_volume_date(iso.pvd.volume_effective_date) - ) - self.event["meta"]["date_expiration"] = ( - self._datetime_from_volume_date(iso.pvd.volume_expiration_date) - ) - self.event["meta"]["date_modification"] = ( - self._datetime_from_volume_date( - iso.pvd.volume_modification_date - ) + self.event["meta"][ + "date_created" + ] = self._datetime_from_volume_date(iso.pvd.volume_creation_date) + self.event["meta"][ + "date_effective" + ] = self._datetime_from_volume_date(iso.pvd.volume_effective_date) + self.event["meta"][ + "date_expiration" + ] = self._datetime_from_volume_date(iso.pvd.volume_expiration_date) + self.event["meta"][ + "date_modification" + ] = self._datetime_from_volume_date( + iso.pvd.volume_modification_date ) self.event["meta"][ "volume_identifier" diff --git a/src/python/strelka/scanners/scan_jar_manifest.py b/src/python/strelka/scanners/scan_jar_manifest.py index 31d08216..30041c40 100644 --- a/src/python/strelka/scanners/scan_jar_manifest.py +++ b/src/python/strelka/scanners/scan_jar_manifest.py @@ -6,6 +6,9 @@ class ScanJarManifest(strelka.Scanner): """Collects metadata from JAR manifest files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): headers = options.get("headers", []) diff --git a/src/python/strelka/scanners/scan_javascript.py b/src/python/strelka/scanners/scan_javascript.py index 4d0f92a5..72e5cc09 100644 --- a/src/python/strelka/scanners/scan_javascript.py +++ b/src/python/strelka/scanners/scan_javascript.py @@ -19,7 +19,7 @@ class ScanJavascript(strelka.Scanner): (default: 50). """ - def init(self): + def init(self, options): # Regular expression to capture URLs, considering various schemes and TLDs. self.url_regex = re.compile( r'(?:\b[a-z\d.-]+://[^<>\s\(\)]+|\b(?:(?:(?:[^\s!@#$%^&*()_=+[\]{}\|;:\'",.<>/?]+)\.)+(?:aaa|aarp|abarth|abb|abbott|abbvie|abc|able|abogado|abudhabi|ac|academy|accenture|accountant|accountants|aco|active|actor|ad|adac|ads|adult|ae|aeg|aero|aetna|af|afamilycompany|afl|africa|ag|agakhan|agency|ai|aig|aigo|airbus|airforce|airtel|akdn|al|alfaromeo|alibaba|alipay|allfinanz|allstate|ally|alsace|alstom|am|americanexpress|americanfamily|amex|amfam|amica|amsterdam|analytics|android|anquan|anz|ao|aol|apartments|app|apple|aq|aquarelle|ar|arab|aramco|archi|army|arpa|art|arte|as|asda|asia|associates|at|athleta|attorney|au|auction|audi|audible|audio|auspost|author|auto|autos|avianca|aw|aws|ax|axa|az|azure|ba|baby|baidu|banamex|bananarepublic|band|bank|bar|barcelona|barclaycard|barclays|barefoot|bargains|baseball|basketball|bauhaus|bayern|bb|bbc|bbt|bbva|bcg|bcn|bd|be|beats|beauty|beer|bentley|berlin|best|bestbuy|bet|bf|bg|bh|bharti|bi|bible|bid|bike|bing|bingo|bio|biz|bj|black|blackfriday|blanco|blockbuster|blog|bloomberg|blue|bm|bms|bmw|bn|bnl|bnpparibas|bo|boats|boehringer|bofa|bom|bond|boo|book|booking|bosch|bostik|boston|bot|boutique|box|br|bradesco|bridgestone|broadway|broker|brother|brussels|bs|bt|budapest|bugatti|build|builders|business|buy|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|call|calvinklein|cam|camera|camp|cancerresearch|canon|capetown|capital|capitalone|car|caravan|cards|care|career|careers|cars|cartier|casa|case|caseih|cash|casino|cat|catering|catholic|cba|cbn|cbre|cbs|cc|cd|ceb|center|ceo|cern|cf|cfa|cfd|cg|ch|chanel|channel|charity|chase|chat|cheap|chintai|christmas|chrome|chrysler|church|ci|cipriani|circle|cisco|citadel|citi|citic|city|cityeats|ck|cl|claims|cleaning|click|clinic|clinique|clothing|cloud|club|clubmed|cm|cn|co|coach|codes|coffee|college|cologne|com|comcast|commbank|community|company|compare|computer|comsec|condos|construction|consulting|contact|contractors|cooking|cookingchannel|cool|coop|corsica|country|coupon|coupons|courses|cr|credit|creditcard|creditunion|cricket|crown|crs|cruise|cruises|csc|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|data|date|dating|datsun|day|dclk|dds|de|deal|dealer|deals|degree|delivery|dell|deloitte|delta|democrat|dental|dentist|desi|design|dev|dhl|diamonds|diet|digital|direct|directory|discount|discover|dish|diy|dj|dk|dm|dnp|do|docs|doctor|dodge|dog|doha|domains|dot|download|drive|dtv|dubai|duck|dunlop|duns|dupont|durban|dvag|dvr|dz|earth|eat|ec|eco|edeka|edu|education|ee|eg|email|emerck|energy|engineer|engineering|enterprises|epost|epson|equipment|er|ericsson|erni|es|esq|estate|esurance|et|etisalat|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|extraspace|fage|fail|fairwinds|faith|family|fan|fans|farm|farmers|fashion|fast|fedex|feedback|ferrari|ferrero|fi|fiat|fidelity|fido|film|final|finance|financial|fire|firestone|firmdale|fish|fishing|fit|fitness|fj|fk|flickr|flights|flir|florist|flowers|fly|fm|fo|foo|food|foodnetwork|football|ford|forex|forsale|forum|foundation|fox|fr|free|fresenius|frl|frogans|frontdoor|frontier|ftr|fujitsu|fujixerox|fun|fund|furniture|futbol|fyi|ga|gal|gallery|gallo|gallup|game|games|gap|garden|gb|gbiz|gd|gdn|ge|gea|gent|genting|george|gf|gg|ggee|gh|gi|gift|gifts|gives|giving|gl|glade|glass|gle|global|globo|gm|gmail|gmbh|gmo|gmx|gn|godaddy|gold|goldpoint|golf|goo|goodhands|goodyear|goog|google|gop|got|gov|gp|gq|gr|grainger|graphics|gratis|green|gripe|grocery|group|gs|gt|gu|guardian|gucci|guge|guide|guitars|guru|gw|gy|hair|hamburg|hangout|haus|hbo|hdfc|hdfcbank|health|healthcare|help|helsinki|here|hermes|hgtv|hiphop|hisamitsu|hitachi|hiv|hk|hkt|hm|hn|hockey|holdings|holiday|homedepot|homegoods|homes|homesense|honda|honeywell|horse|hospital|host|hosting|hot|hoteles|hotels|hotmail|house|how|hr|hsbc|ht|hu|hughes|hyatt|hyundai|ibm|icbc|ice|icu|id|ie|ieee|ifm|ikano|il|im|imamat|imdb|immo|immobilien|in|inc|industries|infiniti|info|ing|ink|institute|insurance|insure|int|intel|international|intuit|investments|io|ipiranga|iq|ir|irish|is|iselect|ismaili|ist|istanbul|it|itau|itv|iveco|jaguar|java|jcb|jcp|je|jeep|jetzt|jewelry|jio|jlc|jll|jm|jmp|jnj|jo|jobs|joburg|jot|joy|jp|jpmorgan|jprs|juegos|juniper|kaufen|kddi|ke|kerryhotels|kerrylogistics|kerryproperties|kfh|kg|kh|ki|kia|kim|kinder|kindle|kitchen|kiwi|km|kn|koeln|komatsu|kosher|kp|kpmg|kpn|kr|krd|kred|kuokgroup|kw|ky|kyoto|kz|la|lacaixa|ladbrokes|lamborghini|lamer|lancaster|lancia|lancome|land|landrover|lanxess|lasalle|lat|latino|latrobe|law|lawyer|lb|lc|lds|lease|leclerc|lefrak|legal|lego|lexus|lgbt|li|liaison|lidl|life|lifeinsurance|lifestyle|lighting|like|lilly|limited|limo|lincoln|linde|link|lipsy|live|living|lixil|lk|llc|loan|loans|locker|locus|loft|lol|london|lotte|lotto|love|lpl|lplfinancial|lr|ls|lt|ltd|ltda|lu|lundbeck|lupin|luxe|luxury|lv|ly|ma|macys|madrid|maif|maison|makeup|man|management|mango|map|market|marketing|markets|marriott|marshalls|maserati|mattel|mba|mc|mckinsey|md|me|med|media|meet|melbourne|meme|memorial|men|menu|merckmsd|metlife|mg|mh|miami|microsoft|mil|mini|mint|mit|mitsubishi|mk|ml|mlb|mls|mm|mma|mn|mo|mobi|mobile|mobily|moda|moe|moi|mom|monash|money|monster|mopar|mormon|mortgage|moscow|moto|motorcycles|mov|movie|movistar|mp|mq|mr|ms|msd|mt|mtn|mtr|mu|museum|mutual|mv|mw|mx|my|mz|na|nab|nadex|nagoya|name|nationwide|natura|navy|nba|nc|ne|nec|net|netbank|netflix|network|neustar|new|newholland|news|next|nextdirect|nexus|nf|nfl|ng|ngo|nhk|ni|nico|nike|nikon|ninja|nissan|nissay|nl|no|nokia|northwesternmutual|norton|now|nowruz|nowtv|np|nr|nra|nrw|ntt|nu|nyc|nz|obi|observer|off|office|okinawa|olayan|olayangroup|oldnavy|ollo|om|omega|one|ong|onl|online|onyourside|ooo|open|oracle|orange|org|organic|origins|osaka|otsuka|ott|ovh|pa|page|panasonic|panerai|paris|pars|partners|parts|party|passagens|pay|pccw|pe|pet|pf|pfizer|pg|ph|pharmacy|phd|philips|phone|photo|photography|photos|physio|piaget|pics|pictet|pictures|pid|pin|ping|pink|pioneer|pizza|pk|pl|place|play|playstation|plumbing|plus|pm|pn|pnc|pohl|poker|politie|porn|post|pr|pramerica|praxi|press|prime|pro|prod|productions|prof|progressive|promo|properties|property|protection|pru|prudential|ps|pt|pub|pw|pwc|py|qa|qpon|quebec|quest|qvc|racing|radio|raid|re|read|realestate|realtor|realty|recipes|red|redstone|redumbrella|rehab|reise|reisen|reit|reliance|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rexroth|rich|richardli|ricoh|rightathome|ril|rio|rip|rmit|ro|rocher|rocks|rodeo|rogers|room|rs|rsvp|ru|rugby|ruhr|run|rw|rwe|ryukyu|sa|saarland|safe|safety|sakura|sale|salon|samsclub|samsung|sandvik|sandvikcoromant|sanofi|sap|sarl|sas|save|saxo|sb|sbi|sbs|sc|sca|scb|schaeffler|schmidt|scholarships|school|schule|schwarz|science|scjohnson|scor|scot|sd|se|search|seat|secure|security|seek|select|sener|services|ses|seven|sew|sex|sexy|sfr|sg|sh|shangrila|sharp|shaw|shell|shia|shiksha|shoes|shop|shopping|shouji|show|showtime|shriram|si|silk|sina|singles|site|sj|sk|ski|skin|sky|skype|sl|sling|sm|smart|smile|sn|sncf|so|soccer|social|softbank|software|sohu|solar|solutions|song|sony|soy|space|spiegel|sport|spot|spreadbetting|sr|srl|srt|st|stada|staples|star|starhub|statebank|statefarm|statoil|stc|stcgroup|stockholm|storage|store|stream|studio|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swatch|swiftcover|swiss|sx|sy|sydney|symantec|systems|sz|tab|taipei|talk|taobao|target|tatamotors|tatar|tattoo|tax|taxi|tc|tci|td|tdk|team|tech|technology|tel|telefonica|temasek|tennis|teva|tf|tg|th|thd|theater|theatre|tiaa|tickets|tienda|tiffany|tips|tires|tirol|tj|tjmaxx|tjx|tk|tkmaxx|tl|tm|tmall|tn|to|today|tokyo|tools|top|toray|toshiba|total|tours|town|toyota|toys|tr|trade|trading|training|travel|travelchannel|travelers|travelersinsurance|trust|trv|tt|tube|tui|tunes|tushu|tv|tvs|tw|tz|ua|ubank|ubs|uconnect|ug|uk|unicom|university|uno|uol|ups|us|uy|uz|va|vacations|vana|vanguard|vc|ve|vegas|ventures|verisign|versicherung|vet|vg|vi|viajes|video|vig|viking|villas|vin|vip|virgin|visa|vision|vistaprint|viva|vivo|vlaanderen|vn|vodka|volkswagen|volvo|vote|voting|voto|voyage|vu|vuelos|wales|walmart|walter|wang|wanggou|warman|watch|watches|weather|weatherchannel|webcam|weber|website|wed|wedding|weibo|weir|wf|whoswho|wien|wiki|williamhill|win|windows|wine|winners|wme|wolterskluwer|woodside|work|works|world|wow|ws|wtc|wtf|xbox|xerox|xfinity|xihuan|xin|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--30rr7y|xn--3bst00m|xn--3ds443g|xn--3e0b707e|xn--3hcrj9c|xn--3oq18vl8pn36a|xn--3pxu8k|xn--42c2d9a|xn--45br5cyl|xn--45brj9c|xn--45q11c|xn--4gbrim|xn--54b7fta0cc|xn--55qw42g|xn--55qx5d|xn--5su34j936bgsg|xn--5tzm5g|xn--6frz82g|xn--6qq986b3xl|xn--80adxhks|xn--80ao21a|xn--80aqecdr1a|xn--80asehdb|xn--80aswg|xn--8y0a063a|xn--90a3ac|xn--90ae|xn--90ais|xn--9dbq2a|xn--9et52u|xn--9krt00a|xn--b4w605ferd|xn--bck1b9a5dre4c|xn--c1avg|xn--c2br7g|xn--cck2b3b|xn--cg4bki|xn--clchc0ea0b2g2a9gcd|xn--czr694b|xn--czrs0t|xn--czru2d|xn--d1acj3b|xn--d1alf|xn--e1a4c|xn--eckvdtc9d|xn--efvy88h|xn--estv75g|xn--fct429k|xn--fhbei|xn--fiq228c5hs|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--fjq720a|xn--flw351e|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--fzys8d69uvgm|xn--g2xx48c|xn--gckr3f0f|xn--gecrj9c|xn--gk3at1e|xn--h2breg3eve|xn--h2brj9c|xn--h2brj9c8c|xn--hxt814e|xn--i1b6b1a6a2e|xn--imr513n|xn--io0a7i|xn--j1aef|xn--j1amh|xn--j6w193g|xn--jlq61u9w7b|xn--jvr189m|xn--kcrx77d1x4a|xn--kprw13d|xn--kpry57d|xn--kpu716f|xn--kput3i|xn--l1acc|xn--lgbbat1ad8j|xn--mgb9awbf|xn--mgba3a3ejt|xn--mgba3a4f16a|xn--mgba7c0bbn0a|xn--mgbaakc7dvf|xn--mgbaam7a8h|xn--mgbab2bd|xn--mgbai9azgqp6j|xn--mgbayh7gpa|xn--mgbb9fbpob|xn--mgbbh1a|xn--mgbbh1a71e|xn--mgbc0a9azcg|xn--mgbca7dzdo|xn--mgberp4a5d4ar|xn--mgbgu82a|xn--mgbi4ecexp|xn--mgbpl2fh|xn--mgbt3dhd|xn--mgbtx2b|xn--mgbx4cd0ab|xn--mix891f|xn--mk1bu44c|xn--mxtq1m|xn--ngbc5azd|xn--ngbe9e0a|xn--ngbrx|xn--node|xn--nqv7f|xn--nqv7fs00ema|xn--nyqy26a|xn--o3cw4h|xn--ogbpf8fl|xn--otu796d|xn--p1acf|xn--p1ai|xn--pbt977c|xn--pgbs0dh|xn--pssy2u|xn--q9jyb4c|xn--qcka1pmc|xn--qxam|xn--rhqv96g|xn--rovu88b|xn--rvc1e0am3e|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--tckwe|xn--tiq49xqyj|xn--unup4y|xn--vermgensberater-ctb|xn--vermgensberatung-pwb|xn--vhquv|xn--vuq861b|xn--w4r85el8fhu5dnra|xn--w4rs40l|xn--wgbh1c|xn--wgbl6a|xn--xhq521b|xn--xkc2al3hye2a|xn--xkc2dl3a5ee0h|xn--y9a3aq|xn--yfro4i67o|xn--ygbi2ammx|xn--zfr164b|xxx|xyz|yachts|yahoo|yamaxun|yandex|ye|yodobashi|yoga|yokohama|you|youtube|yt|yun|za|zappos|zara|zero|zip|zippo|zm|zone|zuerich|zw)|(?:(?:[0-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:[0-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))(?:[;/][^#?<>\s]*)?(?:\?[^#<>\s]*)?(?:#[^<>\s\(\)]*)?(?!\w))', diff --git a/src/python/strelka/scanners/scan_jpeg.py b/src/python/strelka/scanners/scan_jpeg.py index 5e86f9d5..edb6d110 100644 --- a/src/python/strelka/scanners/scan_jpeg.py +++ b/src/python/strelka/scanners/scan_jpeg.py @@ -9,6 +9,9 @@ class ScanJpeg(strelka.Scanner): This scanner extracts data that is inserted past the JFIF EOI marker. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): try: offset = 0 diff --git a/src/python/strelka/scanners/scan_json.py b/src/python/strelka/scanners/scan_json.py index 6e38bc41..7f9f1472 100644 --- a/src/python/strelka/scanners/scan_json.py +++ b/src/python/strelka/scanners/scan_json.py @@ -6,6 +6,9 @@ class ScanJson(strelka.Scanner): """Collects keys from JSON files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): self.event.setdefault("keys", []) diff --git a/src/python/strelka/scanners/scan_libarchive.py b/src/python/strelka/scanners/scan_libarchive.py index 40d173bc..7a836cb7 100644 --- a/src/python/strelka/scanners/scan_libarchive.py +++ b/src/python/strelka/scanners/scan_libarchive.py @@ -11,6 +11,9 @@ class ScanLibarchive(strelka.Scanner): Defaults to 1000. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 1000) diff --git a/src/python/strelka/scanners/scan_lnk.py b/src/python/strelka/scanners/scan_lnk.py index 7759529d..a824c8f0 100644 --- a/src/python/strelka/scanners/scan_lnk.py +++ b/src/python/strelka/scanners/scan_lnk.py @@ -15,6 +15,9 @@ class ScanLNK(strelka.Scanner): """Collects metadata from LNK files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): header = ShellLinkHeader.parse(data) offset = header.HeaderSize @@ -140,18 +143,18 @@ def scan(self, data, file, options, expire_at): try: if extradata.IconEnvironmentDataBlock: - self.event["icon_target"] = ( - extradata.IconEnvironmentDataBlock.TargetAnsi - ) + self.event[ + "icon_target" + ] = extradata.IconEnvironmentDataBlock.TargetAnsi except strelka.ScannerTimeout: raise except Exception: self.flags.append("Unable to parse IconEnvironmentDataBlock") if extradata.TrackerDataBlock: - self.event["machine_id"] = ( - extradata.TrackerDataBlock.MachineID.strip(b"\x00") - ) + self.event[ + "machine_id" + ] = extradata.TrackerDataBlock.MachineID.strip(b"\x00") self.event["mac"] = str( uuid.UUID(bytes_le=extradata.TrackerDataBlock.Droid[16:]) ).split("-")[-1] diff --git a/src/python/strelka/scanners/scan_lsb.py b/src/python/strelka/scanners/scan_lsb.py index 8dac8a6f..a5e96b29 100644 --- a/src/python/strelka/scanners/scan_lsb.py +++ b/src/python/strelka/scanners/scan_lsb.py @@ -7,6 +7,9 @@ class ScanLsb(strelka.Scanner): """This scanner checks if there is any hidden strings at the end of each RGB value""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): try: image = np.frombuffer(data, np.uint8) diff --git a/src/python/strelka/scanners/scan_lzma.py b/src/python/strelka/scanners/scan_lzma.py index 11b85199..34a95e9a 100644 --- a/src/python/strelka/scanners/scan_lzma.py +++ b/src/python/strelka/scanners/scan_lzma.py @@ -7,6 +7,9 @@ class ScanLzma(strelka.Scanner): """Decompresses LZMA files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): try: with io.BytesIO(data) as lzma_io: diff --git a/src/python/strelka/scanners/scan_macho.py b/src/python/strelka/scanners/scan_macho.py index ab503e46..3db3dcc0 100644 --- a/src/python/strelka/scanners/scan_macho.py +++ b/src/python/strelka/scanners/scan_macho.py @@ -178,6 +178,9 @@ class ScanMacho(strelka.Scanner): """Collects metadata from Mach-O files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): tmp_directory = options.get("tmp_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_manifest.py b/src/python/strelka/scanners/scan_manifest.py index 89ed2cc9..f0cd6687 100644 --- a/src/python/strelka/scanners/scan_manifest.py +++ b/src/python/strelka/scanners/scan_manifest.py @@ -17,6 +17,9 @@ def flatten(input: list) -> list: class ScanManifest(strelka.Scanner): """Parses browser extension's manifest.json.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): try: jsondata = json.loads(data) diff --git a/src/python/strelka/scanners/scan_msi.py b/src/python/strelka/scanners/scan_msi.py index 081c5d9d..39204b84 100644 --- a/src/python/strelka/scanners/scan_msi.py +++ b/src/python/strelka/scanners/scan_msi.py @@ -15,6 +15,9 @@ class ScanMsi(strelka.Scanner): Defaults to '/tmp/'. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): # Get a list of keys to collect from the MSI file keys = options.get("keys", []) diff --git a/src/python/strelka/scanners/scan_nf.py b/src/python/strelka/scanners/scan_nf.py index 6ec7e718..c35b8c01 100644 --- a/src/python/strelka/scanners/scan_nf.py +++ b/src/python/strelka/scanners/scan_nf.py @@ -19,6 +19,9 @@ class ScanNf(strelka.Scanner): The higher the value for both variables, the more strict the algorithm is. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): try: # Convert image to HSV color space diff --git a/src/python/strelka/scanners/scan_ocr.py b/src/python/strelka/scanners/scan_ocr.py index c10c5969..b3707543 100644 --- a/src/python/strelka/scanners/scan_ocr.py +++ b/src/python/strelka/scanners/scan_ocr.py @@ -27,6 +27,9 @@ class ScanOcr(strelka.Scanner): thumbnail_size: Size of the thumbnail to create. (default: (250, 250)) """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): extract_text = options.get("extract_text", False) remove_formatting = options.get("remove_formatting", True) diff --git a/src/python/strelka/scanners/scan_ole.py b/src/python/strelka/scanners/scan_ole.py index 9af0c044..5f5b2421 100644 --- a/src/python/strelka/scanners/scan_ole.py +++ b/src/python/strelka/scanners/scan_ole.py @@ -9,6 +9,9 @@ class ScanOle(strelka.Scanner): """Extracts files from OLECF files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): ole = None self.event["total"] = {"streams": 0, "extracted": 0} diff --git a/src/python/strelka/scanners/scan_onenote.py b/src/python/strelka/scanners/scan_onenote.py index 7fd5e615..ee3d9f93 100644 --- a/src/python/strelka/scanners/scan_onenote.py +++ b/src/python/strelka/scanners/scan_onenote.py @@ -13,6 +13,9 @@ class ScanOnenote(strelka.Scanner): """Extracts embedded files in OneNote files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): self.event["total"] = {"files": 0, "extracted": 0} diff --git a/src/python/strelka/scanners/scan_pcap.py b/src/python/strelka/scanners/scan_pcap.py index dd7d4969..707d45b9 100644 --- a/src/python/strelka/scanners/scan_pcap.py +++ b/src/python/strelka/scanners/scan_pcap.py @@ -15,6 +15,9 @@ class ScanPcap(strelka.Scanner): Defaults to 1000. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 1000) tmp_directory = options.get("tmp_file_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_pdf.py b/src/python/strelka/scanners/scan_pdf.py index 78620800..f7dc3a03 100644 --- a/src/python/strelka/scanners/scan_pdf.py +++ b/src/python/strelka/scanners/scan_pdf.py @@ -49,6 +49,9 @@ def _convert_timestamp(timestamp): except Exception: return None + def init(self, options): + pass + def scan(self, data, file, options, expire_at): """ Performs the scanning process on the provided data. diff --git a/src/python/strelka/scanners/scan_pe.py b/src/python/strelka/scanners/scan_pe.py index fa8dd84b..fa9d3af8 100644 --- a/src/python/strelka/scanners/scan_pe.py +++ b/src/python/strelka/scanners/scan_pe.py @@ -391,6 +391,9 @@ def parse_certificates(data): class ScanPe(strelka.Scanner): """Collects metadata from PE files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): try: pe = pefile.PE(data=data) @@ -532,18 +535,18 @@ def scan(self, data, file, options, expire_at): self.event["address_of_entry_point"] = pe.OPTIONAL_HEADER.AddressOfEntryPoint self.event["image_base"] = pe.OPTIONAL_HEADER.ImageBase self.event["size_of_code"] = pe.OPTIONAL_HEADER.SizeOfCode - self.event["size_of_initialized_data"] = ( - pe.OPTIONAL_HEADER.SizeOfInitializedData - ) + self.event[ + "size_of_initialized_data" + ] = pe.OPTIONAL_HEADER.SizeOfInitializedData self.event["size_of_headers"] = pe.OPTIONAL_HEADER.SizeOfHeaders self.event["size_of_heap_reserve"] = pe.OPTIONAL_HEADER.SizeOfHeapReserve self.event["size_of_image"] = pe.OPTIONAL_HEADER.SizeOfImage self.event["size_of_stack_commit"] = pe.OPTIONAL_HEADER.SizeOfStackCommit self.event["size_of_stack_reserve"] = pe.OPTIONAL_HEADER.SizeOfStackReserve self.event["size_of_heap_commit"] = pe.OPTIONAL_HEADER.SizeOfHeapCommit - self.event["size_of_uninitialized_data"] = ( - pe.OPTIONAL_HEADER.SizeOfUninitializedData - ) + self.event[ + "size_of_uninitialized_data" + ] = pe.OPTIONAL_HEADER.SizeOfUninitializedData self.event["file_alignment"] = pe.OPTIONAL_HEADER.FileAlignment self.event["section_alignment"] = pe.OPTIONAL_HEADER.SectionAlignment self.event["checksum"] = pe.OPTIONAL_HEADER.CheckSum @@ -552,12 +555,12 @@ def scan(self, data, file, options, expire_at): self.event["minor_image_version"] = pe.OPTIONAL_HEADER.MinorImageVersion self.event["major_linker_version"] = pe.OPTIONAL_HEADER.MajorLinkerVersion self.event["minor_linker_version"] = pe.OPTIONAL_HEADER.MinorLinkerVersion - self.event["major_operating_system_version"] = ( - pe.OPTIONAL_HEADER.MajorOperatingSystemVersion - ) - self.event["minor_operating_system_version"] = ( - pe.OPTIONAL_HEADER.MinorOperatingSystemVersion - ) + self.event[ + "major_operating_system_version" + ] = pe.OPTIONAL_HEADER.MajorOperatingSystemVersion + self.event[ + "minor_operating_system_version" + ] = pe.OPTIONAL_HEADER.MinorOperatingSystemVersion self.event["major_subsystem_version"] = pe.OPTIONAL_HEADER.MajorSubsystemVersion self.event["minor_subsystem_version"] = pe.OPTIONAL_HEADER.MinorSubsystemVersion self.event["image_version"] = float( diff --git a/src/python/strelka/scanners/scan_pgp.py b/src/python/strelka/scanners/scan_pgp.py index 7c3259d4..ac93cc8f 100644 --- a/src/python/strelka/scanners/scan_pgp.py +++ b/src/python/strelka/scanners/scan_pgp.py @@ -17,6 +17,9 @@ class ScanPgp(strelka.Scanner): """Collects metadata from PGP files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): self.event["total"] = { "public_keys": 0, @@ -74,9 +77,9 @@ def parse_pgpdump(self, data): secret_key_entry["creation_time"] = creation_time.isoformat() expiration_time = getattr(packet, "expiration_time", None) if expiration_time is not None: - secret_key_entry["expiration_time"] = ( - expiration_time.isoformat() - ) + secret_key_entry[ + "expiration_time" + ] = expiration_time.isoformat() if secret_key_entry not in self.event["secret_keys"]: self.event["secret_keys"].append(secret_key_entry) @@ -98,9 +101,9 @@ def parse_pgpdump(self, data): public_key_entry["creation_time"] = creation_time.isoformat() expiration_time = getattr(packet, "expiration_time", None) if expiration_time is not None: - public_key_entry["expiration_time"] = ( - expiration_time.isoformat() - ) + public_key_entry[ + "expiration_time" + ] = expiration_time.isoformat() if public_key_entry not in self.event["public_keys"]: self.event["public_keys"].append(public_key_entry) @@ -135,14 +138,14 @@ def parse_pgpdump(self, data): } creation_time = getattr(packet, "creation_time", None) if creation_time is not None: - signature_packet_entry["creation_time"] = ( - creation_time.isoformat() - ) + signature_packet_entry[ + "creation_time" + ] = creation_time.isoformat() expiration_time = getattr(packet, "expiration_time", None) if expiration_time is not None: - signature_packet_entry["expiration_time"] = ( - expiration_time.isoformat() - ) + signature_packet_entry[ + "expiration_time" + ] = expiration_time.isoformat() if signature_packet_entry not in self.event["signatures"]: self.event["signatures"].append(signature_packet_entry) diff --git a/src/python/strelka/scanners/scan_php.py b/src/python/strelka/scanners/scan_php.py index 449bc442..e3c0a61c 100644 --- a/src/python/strelka/scanners/scan_php.py +++ b/src/python/strelka/scanners/scan_php.py @@ -13,7 +13,7 @@ class ScanPhp(strelka.Scanner): lexer: Pygments lexer ('php') used to parse the file. """ - def init(self): + def init(self, options): self.lexer = lexers.get_lexer_by_name("php") def scan(self, data, file, options, expire_at): diff --git a/src/python/strelka/scanners/scan_pkcs7.py b/src/python/strelka/scanners/scan_pkcs7.py index 90395fd0..b411262c 100644 --- a/src/python/strelka/scanners/scan_pkcs7.py +++ b/src/python/strelka/scanners/scan_pkcs7.py @@ -8,6 +8,9 @@ class ScanPkcs7(strelka.Scanner): """Extracts files from PKCS7 certificate files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): # Set the temporary directory for storing data. The default is "/tmp/". tmp_directory = options.get("tmp_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_plist.py b/src/python/strelka/scanners/scan_plist.py index 08e19a0d..b1929f09 100644 --- a/src/python/strelka/scanners/scan_plist.py +++ b/src/python/strelka/scanners/scan_plist.py @@ -13,6 +13,9 @@ class ScanPlist(strelka.Scanner): Defaults to all. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): keys = options.get("keys", []) diff --git a/src/python/strelka/scanners/scan_png_eof.py b/src/python/strelka/scanners/scan_png_eof.py index b0ef9f23..e6c283b6 100644 --- a/src/python/strelka/scanners/scan_png_eof.py +++ b/src/python/strelka/scanners/scan_png_eof.py @@ -7,6 +7,9 @@ class ScanPngEof(strelka.Scanner): This scanner extracts data that is inserted past the PNG file end """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): # PNG IEND chunk png_iend = b"\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82" diff --git a/src/python/strelka/scanners/scan_qr.py b/src/python/strelka/scanners/scan_qr.py index 7f795394..06ad1739 100644 --- a/src/python/strelka/scanners/scan_qr.py +++ b/src/python/strelka/scanners/scan_qr.py @@ -14,6 +14,9 @@ class ScanQr(strelka.Scanner): Collects QR code metadata from image files. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): support_inverted = options.get("support_inverted", True) diff --git a/src/python/strelka/scanners/scan_rar.py b/src/python/strelka/scanners/scan_rar.py index 51717e5f..73243ca9 100644 --- a/src/python/strelka/scanners/scan_rar.py +++ b/src/python/strelka/scanners/scan_rar.py @@ -31,7 +31,7 @@ class ScanRar(strelka.Scanner): Defaults to /etc/strelka/passwords.dat """ - def init(self): + def init(self, options): self.passwords = [] def scan(self, data, file, options, expire_at): @@ -79,7 +79,7 @@ def scan(self, data, file, options, expire_at): data = rar_obj.open( name, mode="r", - psw=pw.decode("utf-8"), + pwd=pw.decode("utf-8"), ) if data.readable(): extract_data = data.readall() @@ -100,7 +100,7 @@ def scan(self, data, file, options, expire_at): else: try: data = rar_obj.open( - name, mode="r", psw=password + name, mode="r", pwd=password ) if data.readable(): extract_data = data.readall() diff --git a/src/python/strelka/scanners/scan_rpm.py b/src/python/strelka/scanners/scan_rpm.py index a336d627..86f13647 100644 --- a/src/python/strelka/scanners/scan_rpm.py +++ b/src/python/strelka/scanners/scan_rpm.py @@ -13,6 +13,9 @@ class ScanRpm(strelka.Scanner): Defaults to '/tmp/'. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): tmp_directory = options.get("tmp_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_rtf.py b/src/python/strelka/scanners/scan_rtf.py index 508a1ad1..b3509b36 100644 --- a/src/python/strelka/scanners/scan_rtf.py +++ b/src/python/strelka/scanners/scan_rtf.py @@ -11,6 +11,9 @@ class ScanRtf(strelka.Scanner): Defaults to 1000. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 1000) diff --git a/src/python/strelka/scanners/scan_save.py b/src/python/strelka/scanners/scan_save.py index a5fc7ef9..7e1c81cf 100644 --- a/src/python/strelka/scanners/scan_save.py +++ b/src/python/strelka/scanners/scan_save.py @@ -11,7 +11,7 @@ class ScanSave(strelka.Scanner): """Compress and encode raw file data""" - def init(self): + def init(self, options): # Compression algorithm choices self.compress_data = { "gzip": gzip.compress, diff --git a/src/python/strelka/scanners/scan_seven_zip.py b/src/python/strelka/scanners/scan_seven_zip.py index a58a0e77..01aaeb77 100644 --- a/src/python/strelka/scanners/scan_seven_zip.py +++ b/src/python/strelka/scanners/scan_seven_zip.py @@ -19,6 +19,9 @@ class ScanSevenZip(strelka.Scanner): EXCLUDED_ROOT_DIRS: list[str] = [] + def init(self, options): + pass + def scan(self, data: bytes, file: strelka.File, options: dict, expire_at) -> None: file_limit = options.get("limit", 100) tmp_directory = options.get("tmp_file_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_strings.py b/src/python/strelka/scanners/scan_strings.py index 6c0cfcb8..04e667ac 100644 --- a/src/python/strelka/scanners/scan_strings.py +++ b/src/python/strelka/scanners/scan_strings.py @@ -16,7 +16,7 @@ class ScanStrings(strelka.Scanner): Defaults to 0 (unlimited). """ - def init(self): + def init(self, options): self.strings_regex = re.compile(rb"[^\x00-\x1F\x7F-\xFF]{4,}") def scan(self, data, file, options, expire_at): diff --git a/src/python/strelka/scanners/scan_swf.py b/src/python/strelka/scanners/scan_swf.py index 9067771d..f6a9dc9f 100644 --- a/src/python/strelka/scanners/scan_swf.py +++ b/src/python/strelka/scanners/scan_swf.py @@ -10,6 +10,9 @@ class ScanSwf(strelka.Scanner): """Decompresses SWF files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): with io.BytesIO(data) as swf_io: swf_io.seek(4) diff --git a/src/python/strelka/scanners/scan_tar.py b/src/python/strelka/scanners/scan_tar.py index f3ca0714..e5d86ff6 100644 --- a/src/python/strelka/scanners/scan_tar.py +++ b/src/python/strelka/scanners/scan_tar.py @@ -12,6 +12,9 @@ class ScanTar(strelka.Scanner): Defaults to 1000. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 1000) diff --git a/src/python/strelka/scanners/scan_tlsh.py b/src/python/strelka/scanners/scan_tlsh.py index dcdec38e..826bde61 100644 --- a/src/python/strelka/scanners/scan_tlsh.py +++ b/src/python/strelka/scanners/scan_tlsh.py @@ -26,7 +26,7 @@ class ScanTlsh(strelka.Scanner): Defaults to 30. """ - def init(self): + def init(self, options): self.tlsh_rules = None def scan(self, data, file, options, expire_at): diff --git a/src/python/strelka/scanners/scan_tnef.py b/src/python/strelka/scanners/scan_tnef.py index ad114fab..120b60dd 100644 --- a/src/python/strelka/scanners/scan_tnef.py +++ b/src/python/strelka/scanners/scan_tnef.py @@ -6,6 +6,9 @@ class ScanTnef(strelka.Scanner): """Collects metadata and extract files from TNEF files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): self.event["total"] = {"attachments": 0, "extracted": 0} self.event.setdefault("object_names", []) diff --git a/src/python/strelka/scanners/scan_transcode.py b/src/python/strelka/scanners/scan_transcode.py index 4e518415..e552a1f5 100644 --- a/src/python/strelka/scanners/scan_transcode.py +++ b/src/python/strelka/scanners/scan_transcode.py @@ -23,6 +23,9 @@ class ScanTranscode(strelka.Scanner): gif webp jpeg bmp png tiff """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): output_format = options.get("output_format", "jpeg") diff --git a/src/python/strelka/scanners/scan_udf.py b/src/python/strelka/scanners/scan_udf.py index 108eb184..87510e0e 100644 --- a/src/python/strelka/scanners/scan_udf.py +++ b/src/python/strelka/scanners/scan_udf.py @@ -13,6 +13,9 @@ class ScanUdf(strelka.Scanner): EXCLUDED_ROOT_DIRS = ["[SYSTEM]"] + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 100) tmp_directory = options.get("tmp_file_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_upx.py b/src/python/strelka/scanners/scan_upx.py index 638f98cd..34d4cda6 100644 --- a/src/python/strelka/scanners/scan_upx.py +++ b/src/python/strelka/scanners/scan_upx.py @@ -13,6 +13,9 @@ class ScanUpx(strelka.Scanner): Defaults to '/tmp/'. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): tmp_directory = options.get("tmp_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_url.py b/src/python/strelka/scanners/scan_url.py index 599d1940..5f92af33 100644 --- a/src/python/strelka/scanners/scan_url.py +++ b/src/python/strelka/scanners/scan_url.py @@ -23,7 +23,7 @@ class ScanUrl(strelka.Scanner): Defaults to False (uses default regex). """ - def init(self): + def init(self, options): # Default compiled regex pattern for URL extraction. # This default pattern aims to match a wide range of URLs including those with TLDs. self.regexes = { diff --git a/src/python/strelka/scanners/scan_vb.py b/src/python/strelka/scanners/scan_vb.py index 8fd51674..cb114455 100644 --- a/src/python/strelka/scanners/scan_vb.py +++ b/src/python/strelka/scanners/scan_vb.py @@ -19,7 +19,7 @@ class ScanVb(strelka.Scanner): url_regex: A compiled regex pattern for extracting URLs from the script. """ - def init(self): + def init(self, options): # Initialize the lexer for VB.NET language using Pygments self.lexer = lexers.get_lexer_by_name("vbnet") diff --git a/src/python/strelka/scanners/scan_vba.py b/src/python/strelka/scanners/scan_vba.py index c07b8544..af53bc09 100644 --- a/src/python/strelka/scanners/scan_vba.py +++ b/src/python/strelka/scanners/scan_vba.py @@ -15,6 +15,9 @@ class ScanVba(strelka.Scanner): Defaults to True. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): vba = None analyze_macros = options.get("analyze_macros", True) diff --git a/src/python/strelka/scanners/scan_vhd.py b/src/python/strelka/scanners/scan_vhd.py index 0ffe7d3f..dd1d5c0f 100644 --- a/src/python/strelka/scanners/scan_vhd.py +++ b/src/python/strelka/scanners/scan_vhd.py @@ -13,6 +13,9 @@ class ScanVhd(strelka.Scanner): EXCLUDED_ROOT_DIRS = ["[SYSTEM]"] + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 100) tmp_directory = options.get("tmp_file_directory", "/tmp/") diff --git a/src/python/strelka/scanners/scan_vsto.py b/src/python/strelka/scanners/scan_vsto.py index 8e139257..95070acc 100644 --- a/src/python/strelka/scanners/scan_vsto.py +++ b/src/python/strelka/scanners/scan_vsto.py @@ -24,6 +24,9 @@ class ScanVsto(strelka.Scanner): """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): """ Extracts information from the VSTO file. diff --git a/src/python/strelka/scanners/scan_x509.py b/src/python/strelka/scanners/scan_x509.py index 9a24df10..683f1aec 100644 --- a/src/python/strelka/scanners/scan_x509.py +++ b/src/python/strelka/scanners/scan_x509.py @@ -16,6 +16,9 @@ class ScanX509(strelka.Scanner): Defaults to empty string. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_type = options.get("type", "") diff --git a/src/python/strelka/scanners/scan_xl4ma.py b/src/python/strelka/scanners/scan_xl4ma.py index 840b2274..b4f8e3ff 100644 --- a/src/python/strelka/scanners/scan_xl4ma.py +++ b/src/python/strelka/scanners/scan_xl4ma.py @@ -19,6 +19,9 @@ class ScanXl4ma(strelka.Scanner): - iocs (list): List of IOCs extracted during scanning. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): """ Overrideable scan method from strelka.Scanner. diff --git a/src/python/strelka/scanners/scan_xml.py b/src/python/strelka/scanners/scan_xml.py index 52f40aa6..5dd83f67 100644 --- a/src/python/strelka/scanners/scan_xml.py +++ b/src/python/strelka/scanners/scan_xml.py @@ -15,6 +15,9 @@ class ScanXml(strelka.Scanner): Defaults to empty list. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): xml_args = { "extract_tags": options.get("extract_tags", []), diff --git a/src/python/strelka/scanners/scan_yara.py b/src/python/strelka/scanners/scan_yara.py index 87f0b570..5252cb3a 100644 --- a/src/python/strelka/scanners/scan_yara.py +++ b/src/python/strelka/scanners/scan_yara.py @@ -31,7 +31,7 @@ class ScanYara(strelka.Scanner): offset match for context """ - def init(self): + def init(self, options): """Initializes the ScanYara class. Sets up the initial state for the scanner by ensuring that diff --git a/src/python/strelka/scanners/scan_zip.py b/src/python/strelka/scanners/scan_zip.py index a5297a0d..cfadcf46 100644 --- a/src/python/strelka/scanners/scan_zip.py +++ b/src/python/strelka/scanners/scan_zip.py @@ -20,6 +20,9 @@ class ScanZip(strelka.Scanner): Defaults to /etc/strelka/passwords.dat. """ + def init(self, options): + pass + def scan(self, data, file, options, expire_at): file_limit = options.get("limit", 100) size_limit = options.get("size_limit", 250000000) diff --git a/src/python/strelka/scanners/scan_zlib.py b/src/python/strelka/scanners/scan_zlib.py index 9c8125c1..789d6838 100644 --- a/src/python/strelka/scanners/scan_zlib.py +++ b/src/python/strelka/scanners/scan_zlib.py @@ -6,6 +6,9 @@ class ScanZlib(strelka.Scanner): """Decompresses zlib files.""" + def init(self, options): + pass + def scan(self, data, file, options, expire_at): try: # Decompress file and collect metadata diff --git a/src/python/strelka/strelka.py b/src/python/strelka/strelka.py index 48521951..76a29ded 100644 --- a/src/python/strelka/strelka.py +++ b/src/python/strelka/strelka.py @@ -714,12 +714,15 @@ def __init__( if not self.tracer: self.tracer = trace.get_tracer(__name__) - self.init() + mapping = backend_cfg.get("scanners", {}).get(self.name, [{}]).pop() + options = mapping.get("options", {}) - def init(self) -> None: + self.init(options=options) + + def init(self, options: dict = None) -> None: """Overrideable init. - This method can be used to setup one-time variables required + This method can be used to set up one-time variables required during scanning.""" def timeout_handler(self, signal_number: int, frame: Optional[FrameType]) -> None: From 63bacefff9b6553a9ed2e55ee75b31d77b8af8a2 Mon Sep 17 00:00:00 2001 From: Ryan O'Horo <10855297+ryanohoro@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:34:48 -0600 Subject: [PATCH 2/4] Update Scanner documentation --- docs/README.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index ae440b6b..bec148bf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -767,6 +767,21 @@ This option is set to false by default. ## Scanners Each scanner parses files of a specific flavor and performs data collection and/or file extraction on them. Scanners are typically named after the type of file they are intended to scan (e.g. "ScanHtml", "ScanPe", "ScanRar") but may also be named after the type of function or tool they use to perform their tasks (e.g. "ScanExiftool", "ScanHeader", "ScanOcr"). +Scanners implement the following functions: + +- init(options) + - Executes when Strelka starts +- scan(data, file, options, expire_at)) + - Does the work of the scanner when a file is submitted + +Scanners have access to the following helpers: +- emit_file(data, name, flavors) + - Submits data extracted in a scanner as a new file + +Scanners should use the following standard event fields: +- flags + - Highlights error conditions or important attributes e.g. "bad_format", "encrypted_headers" + ### Scanner List The table below describes each scanner and its options. Each scanner has the hidden option "scanner_timeout" which can override the distribution scanner_timeout. @@ -789,7 +804,7 @@ The table below describes each scanner and its options. Each scanner has the hid | ScanFalconSandbox | Sends files to an instance of Falcon Sandbox | `server` -- URL of the Falcon Sandbox API inteface
`priority` -- Falcon Sandbox priority assigned to the task (defaults to `3`)
`timeout` -- amount of time (in seconds) to wait for the task to upload (defaults to `60`)
`envID` -- list of numeric envrionment IDs that tells Falcon Sandbox which sandbox to submit a sample to (defaults to `[100]`)
`api_key` -- API key used for authenticating to Falcon Sandbox (defaults to None, optionally read from environment variable "FS_API_KEY")
`api_secret` -- API secret key used for authenticating to Falcon Sandbox (defaults to None, optionally read from environment variable "FS_API_SECKEY") | | ScanFooter | Collects file footer | `length` -- number of footer characters to log as metadata (defaults to `50`)
`encodings` -- list of output encodings, any of `classic`, `raw`, `hex`, `backslash` | | ScanGif | Extracts data embedded in GIF files | N/A | -| ScanGzip | Decompresses gzip files | N/A +| ScanGzip | Decompresses gzip files | N/A | ScanHash | Calculates file hash values | N/A | | ScanHeader | Collects file header | `length` -- number of header characters to log as metadata (defaults to `50`)
`encodings` -- list of output encodings, any of `classic`, `raw`, `hex`, `backslash` | | ScanHtml | Collects metadata and extracts embedded files from HTML files | `parser` -- sets the HTML parser used during scanning (defaults to `html.parser`)
`max_links` -- Maximum amount of links to output in hyperlinks field (defaults to `50`) | @@ -839,7 +854,7 @@ The table below describes each scanner and its options. Each scanner has the hid | ScanXml | Log metadata and extract files from XML files | `extract_tags` -- list of XML tags that will have their text extracted as child files (defaults to empty list)
`metadata_tags` -- list of XML tags that will have their text logged as metadata (defaults to empty list) | | ScanYara | Scans files with YARA rules | `location` -- location of the YARA rules file or directory (defaults to `/etc/strelka/yara/`)
`compiled` -- Enable use of compiled YARA rules, as well as the path.
`store_offset` -- Stores file offset for YARA match
`offset_meta_key` -- YARA meta key that must exist in the YARA rule for the offset to be stored.
`offset_padding` -- Amount of data to be stored before and after offset for additional context.
`category_key` -- Metadata key used to extract categories for YARA matches.
`categories` -- List of categories to organize YARA rules, which can be individually toggled to show metadata.
`show_meta` -- Toggles whether to show metadata for matches in each category.
`meta_fields` -- Specifies which metadata fields should be extracted for display.
`show_all_meta` -- Displays all metadata for each YARA rule match when enabled. | | ScanZip | Extracts files from zip archives | `limit` -- maximum number of files to extract (defaults to `1000`)
`limit_metadata` -- stop adding file metadata when `limit` is reached (defaults to true)
`size_limit` -- maximum size for extracted files (defaults to `250000000`)
`crack_pws` -- use a dictionary to crack encrypted files (defaults to false)
`log_pws` -- log cracked passwords (defaults to true)
`password_file` -- location of passwords file for zip archives (defaults to `/etc/strelka/passwords.dat`) | -| ScanZlib | Decompresses gzip files | N/A +| ScanZlib | Decompresses gzip files | N/A ## Tests As Strelka consists of many scanners and dependencies for those scanners. Pytests are particularly valuable for testing the ongoing functionality of Strelka and it's scanners. Tests allow users to write test cases that verify the correct behavior of Strelka scanners to ensure that the scanners remain reliable and accurate. Additionally, using pytests can help streamline the development process, allowing developers to focus on writing new features and improvements for the scanners. Strelka contains a set of standard test fixture files that represent the types of files Strelka ingests. Test fixtures can also be loaded remotely with the helper functions `get_remote_fixture` and `get_remote_fixture_archive` for scanner tests that need malicious samples. From 5bdfdc3a8637f2f2f12eca730d5405ebac572ae8 Mon Sep 17 00:00:00 2001 From: Ryan O'Horo <10855297+ryanohoro@users.noreply.github.com> Date: Sat, 9 Mar 2024 00:41:02 -0600 Subject: [PATCH 3/4] Update pre-commit config --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a121cff1..376e12d9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ --- repos: - repo: https://github.com/psf/black - rev: "22.6.0" + rev: "24.2.0" hooks: - id: black - repo: https://github.com/pre-commit/pre-commit-hooks @@ -17,16 +17,16 @@ repos: args: - -b main - repo: https://github.com/PyCQA/flake8 - rev: "4.0.1" + rev: "7.0.0" hooks: - id: flake8 - repo: https://github.com/PyCQA/isort - rev: "5.11.5" + rev: "5.13.2" hooks: - id: isort args: ["--profile", "black", "--filter-files"] # - repo: https://github.com/pre-commit/mirrors-mypy -# rev: v0.961 +# rev: "1.9.0" # hooks: # - id: mypy # additional_dependencies: From f1117126a4e4928d23893fd5446f7c7dedff70fb Mon Sep 17 00:00:00 2001 From: Ryan O'Horo <10855297+ryanohoro@users.noreply.github.com> Date: Sat, 9 Mar 2024 00:41:30 -0600 Subject: [PATCH 4/4] Formatting --- src/python/strelka/scanners/scan_docx.py | 18 ++++++++-------- src/python/strelka/scanners/scan_iso.py | 26 ++++++++++++------------ src/python/strelka/scanners/scan_lnk.py | 12 +++++------ src/python/strelka/scanners/scan_pe.py | 24 +++++++++++----------- src/python/strelka/scanners/scan_pgp.py | 24 +++++++++++----------- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/python/strelka/scanners/scan_docx.py b/src/python/strelka/scanners/scan_docx.py index b4c8781e..257a7e57 100644 --- a/src/python/strelka/scanners/scan_docx.py +++ b/src/python/strelka/scanners/scan_docx.py @@ -33,17 +33,17 @@ def scan(self, data, file, options, expire_at): self.event["identifier"] = docx_doc.core_properties.identifier self.event["keywords"] = docx_doc.core_properties.keywords self.event["language"] = docx_doc.core_properties.language - self.event[ - "last_modified_by" - ] = docx_doc.core_properties.last_modified_by + self.event["last_modified_by"] = ( + docx_doc.core_properties.last_modified_by + ) if docx_doc.core_properties.last_printed is not None: - self.event[ - "last_printed" - ] = docx_doc.core_properties.last_printed.isoformat() + self.event["last_printed"] = ( + docx_doc.core_properties.last_printed.isoformat() + ) if docx_doc.core_properties.modified is not None: - self.event[ - "modified" - ] = docx_doc.core_properties.modified.isoformat() + self.event["modified"] = ( + docx_doc.core_properties.modified.isoformat() + ) self.event["revision"] = docx_doc.core_properties.revision self.event["subject"] = docx_doc.core_properties.subject self.event["title"] = docx_doc.core_properties.title diff --git a/src/python/strelka/scanners/scan_iso.py b/src/python/strelka/scanners/scan_iso.py index 5478c687..53ecab4b 100644 --- a/src/python/strelka/scanners/scan_iso.py +++ b/src/python/strelka/scanners/scan_iso.py @@ -30,19 +30,19 @@ def scan(self, data, file, options, expire_at): # Attempt to get Meta try: - self.event["meta"][ - "date_created" - ] = self._datetime_from_volume_date(iso.pvd.volume_creation_date) - self.event["meta"][ - "date_effective" - ] = self._datetime_from_volume_date(iso.pvd.volume_effective_date) - self.event["meta"][ - "date_expiration" - ] = self._datetime_from_volume_date(iso.pvd.volume_expiration_date) - self.event["meta"][ - "date_modification" - ] = self._datetime_from_volume_date( - iso.pvd.volume_modification_date + self.event["meta"]["date_created"] = ( + self._datetime_from_volume_date(iso.pvd.volume_creation_date) + ) + self.event["meta"]["date_effective"] = ( + self._datetime_from_volume_date(iso.pvd.volume_effective_date) + ) + self.event["meta"]["date_expiration"] = ( + self._datetime_from_volume_date(iso.pvd.volume_expiration_date) + ) + self.event["meta"]["date_modification"] = ( + self._datetime_from_volume_date( + iso.pvd.volume_modification_date + ) ) self.event["meta"][ "volume_identifier" diff --git a/src/python/strelka/scanners/scan_lnk.py b/src/python/strelka/scanners/scan_lnk.py index a824c8f0..6763d1b8 100644 --- a/src/python/strelka/scanners/scan_lnk.py +++ b/src/python/strelka/scanners/scan_lnk.py @@ -143,18 +143,18 @@ def scan(self, data, file, options, expire_at): try: if extradata.IconEnvironmentDataBlock: - self.event[ - "icon_target" - ] = extradata.IconEnvironmentDataBlock.TargetAnsi + self.event["icon_target"] = ( + extradata.IconEnvironmentDataBlock.TargetAnsi + ) except strelka.ScannerTimeout: raise except Exception: self.flags.append("Unable to parse IconEnvironmentDataBlock") if extradata.TrackerDataBlock: - self.event[ - "machine_id" - ] = extradata.TrackerDataBlock.MachineID.strip(b"\x00") + self.event["machine_id"] = ( + extradata.TrackerDataBlock.MachineID.strip(b"\x00") + ) self.event["mac"] = str( uuid.UUID(bytes_le=extradata.TrackerDataBlock.Droid[16:]) ).split("-")[-1] diff --git a/src/python/strelka/scanners/scan_pe.py b/src/python/strelka/scanners/scan_pe.py index fa9d3af8..943f5e41 100644 --- a/src/python/strelka/scanners/scan_pe.py +++ b/src/python/strelka/scanners/scan_pe.py @@ -535,18 +535,18 @@ def scan(self, data, file, options, expire_at): self.event["address_of_entry_point"] = pe.OPTIONAL_HEADER.AddressOfEntryPoint self.event["image_base"] = pe.OPTIONAL_HEADER.ImageBase self.event["size_of_code"] = pe.OPTIONAL_HEADER.SizeOfCode - self.event[ - "size_of_initialized_data" - ] = pe.OPTIONAL_HEADER.SizeOfInitializedData + self.event["size_of_initialized_data"] = ( + pe.OPTIONAL_HEADER.SizeOfInitializedData + ) self.event["size_of_headers"] = pe.OPTIONAL_HEADER.SizeOfHeaders self.event["size_of_heap_reserve"] = pe.OPTIONAL_HEADER.SizeOfHeapReserve self.event["size_of_image"] = pe.OPTIONAL_HEADER.SizeOfImage self.event["size_of_stack_commit"] = pe.OPTIONAL_HEADER.SizeOfStackCommit self.event["size_of_stack_reserve"] = pe.OPTIONAL_HEADER.SizeOfStackReserve self.event["size_of_heap_commit"] = pe.OPTIONAL_HEADER.SizeOfHeapCommit - self.event[ - "size_of_uninitialized_data" - ] = pe.OPTIONAL_HEADER.SizeOfUninitializedData + self.event["size_of_uninitialized_data"] = ( + pe.OPTIONAL_HEADER.SizeOfUninitializedData + ) self.event["file_alignment"] = pe.OPTIONAL_HEADER.FileAlignment self.event["section_alignment"] = pe.OPTIONAL_HEADER.SectionAlignment self.event["checksum"] = pe.OPTIONAL_HEADER.CheckSum @@ -555,12 +555,12 @@ def scan(self, data, file, options, expire_at): self.event["minor_image_version"] = pe.OPTIONAL_HEADER.MinorImageVersion self.event["major_linker_version"] = pe.OPTIONAL_HEADER.MajorLinkerVersion self.event["minor_linker_version"] = pe.OPTIONAL_HEADER.MinorLinkerVersion - self.event[ - "major_operating_system_version" - ] = pe.OPTIONAL_HEADER.MajorOperatingSystemVersion - self.event[ - "minor_operating_system_version" - ] = pe.OPTIONAL_HEADER.MinorOperatingSystemVersion + self.event["major_operating_system_version"] = ( + pe.OPTIONAL_HEADER.MajorOperatingSystemVersion + ) + self.event["minor_operating_system_version"] = ( + pe.OPTIONAL_HEADER.MinorOperatingSystemVersion + ) self.event["major_subsystem_version"] = pe.OPTIONAL_HEADER.MajorSubsystemVersion self.event["minor_subsystem_version"] = pe.OPTIONAL_HEADER.MinorSubsystemVersion self.event["image_version"] = float( diff --git a/src/python/strelka/scanners/scan_pgp.py b/src/python/strelka/scanners/scan_pgp.py index ac93cc8f..02c6329f 100644 --- a/src/python/strelka/scanners/scan_pgp.py +++ b/src/python/strelka/scanners/scan_pgp.py @@ -77,9 +77,9 @@ def parse_pgpdump(self, data): secret_key_entry["creation_time"] = creation_time.isoformat() expiration_time = getattr(packet, "expiration_time", None) if expiration_time is not None: - secret_key_entry[ - "expiration_time" - ] = expiration_time.isoformat() + secret_key_entry["expiration_time"] = ( + expiration_time.isoformat() + ) if secret_key_entry not in self.event["secret_keys"]: self.event["secret_keys"].append(secret_key_entry) @@ -101,9 +101,9 @@ def parse_pgpdump(self, data): public_key_entry["creation_time"] = creation_time.isoformat() expiration_time = getattr(packet, "expiration_time", None) if expiration_time is not None: - public_key_entry[ - "expiration_time" - ] = expiration_time.isoformat() + public_key_entry["expiration_time"] = ( + expiration_time.isoformat() + ) if public_key_entry not in self.event["public_keys"]: self.event["public_keys"].append(public_key_entry) @@ -138,14 +138,14 @@ def parse_pgpdump(self, data): } creation_time = getattr(packet, "creation_time", None) if creation_time is not None: - signature_packet_entry[ - "creation_time" - ] = creation_time.isoformat() + signature_packet_entry["creation_time"] = ( + creation_time.isoformat() + ) expiration_time = getattr(packet, "expiration_time", None) if expiration_time is not None: - signature_packet_entry[ - "expiration_time" - ] = expiration_time.isoformat() + signature_packet_entry["expiration_time"] = ( + expiration_time.isoformat() + ) if signature_packet_entry not in self.event["signatures"]: self.event["signatures"].append(signature_packet_entry)