From 0a710c1ec5c5dea858182fcd25da9f2627004af5 Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 6 Dec 2022 11:18:29 -0500 Subject: [PATCH] Removing zscript from master branch --- xample-malware/netwalker.md | 2 +- zscript/TODO | 3 - .../__pycache__/capa_analysis.cpython-310.pyc | Bin 3569 -> 0 bytes .../__pycache__/fill_header.cpython-310.pyc | Bin 4206 -> 0 bytes zscript/atx.py | 34 --- zscript/autofill.py | 277 ------------------ zscript/capa_analysis.py | 107 ------- zscript/cape_analysis.py | 57 ---- zscript/example_input | 10 - zscript/fill_detection.py | 215 -------------- zscript/fill_header.py | 176 ----------- zscript/input | 0 zscript/test_file.md | 69 ----- zscript/use_in_malware_method.py | 60 ---- 14 files changed, 1 insertion(+), 1009 deletions(-) delete mode 100644 zscript/TODO delete mode 100644 zscript/__pycache__/capa_analysis.cpython-310.pyc delete mode 100644 zscript/__pycache__/fill_header.cpython-310.pyc delete mode 100644 zscript/atx.py delete mode 100644 zscript/autofill.py delete mode 100755 zscript/capa_analysis.py delete mode 100644 zscript/cape_analysis.py delete mode 100644 zscript/example_input delete mode 100644 zscript/fill_detection.py delete mode 100644 zscript/fill_header.py delete mode 100644 zscript/input delete mode 100644 zscript/test_file.md delete mode 100644 zscript/use_in_malware_method.py diff --git a/xample-malware/netwalker.md b/xample-malware/netwalker.md index c169119..08ba9b0 100644 --- a/xample-malware/netwalker.md +++ b/xample-malware/netwalker.md @@ -37,7 +37,7 @@ See ATT&CK: [Netwalker - Techniques Used](https://attack.mitre.org/software/S045 |---|---| |[Execution::Command and Scripting Interpreter (E1049)](../execution/command-and-scripting-interpreter.md)|Netwalker is written and executed in Powershell [[1]](#1)| |[Defense Evasion::Obfuscated Files or Information (E1027)](../defense-evasion/obfuscated-files-or-information.md)|Netwalker is obfuscated with several layers of encoding, obfuscation, and encryption techniques such as base64, hexademcimal, and XOR [[1]](#1)| -|[Defense Evasion::Process Injection::Dynamic-Link Library Injection (E1055.001)](../defense-evasion/process-injection.md)|Netwalker uses reflective DLL loading to inject from memory [[1]](#1)| +|[Defense Evasion::Process Injection::Dynamic-link Library Injection (E1055.001)](../defense-evasion/process-injection.md)|Netwalker uses reflective DLL loading to inject from memory [[1]](#1)| |[Impact::Data Encrypted for Impact (E1486)](../impact/data-encrypted-for-impact.md)|Netwalker encrypts files for ransom [[1]](#1)| diff --git a/zscript/TODO b/zscript/TODO deleted file mode 100644 index 0fa4925..0000000 --- a/zscript/TODO +++ /dev/null @@ -1,3 +0,0 @@ -- Update capa_analysis.py to make it look pretty and increase usability -- update autofill.py to make it look pretty and increase usability -- Move global variables such as objective_list into a config file to reduce editing if things are changed \ No newline at end of file diff --git a/zscript/__pycache__/capa_analysis.cpython-310.pyc b/zscript/__pycache__/capa_analysis.cpython-310.pyc deleted file mode 100644 index 2a153cdcff81783531203e5a3523d39517500fcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3569 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 count: # Returns highest fuzzy match score - count = x - f = file - - if count == 0 or f is None: - raise Exception("Fuzzy file search did not find anything: ".format(string)) - - return f - - -def populate_behavior(name, date, reference, path, description, orig_file): - # if len(sys.argv) != 4: - # print("This script needs three command-and-scripting-interpreter parameters: the malware name, date, and reference link. Additionally, paste the markdown into the input file") - # return - - - # malware_name = sys.argv[1] - # malware_date = sys.argv[2] - # reference_link = sys.argv[3] - # input_regex = "\[[^]]*\]\(([^\)]*)\)\|(.*?) \[" - # input_regex2 = "\[[^]]*\]\(([^\)]*)\)\|" - reference_regex = " 0: - reference_diff -= 1 - reference = str(int(reference) + reference_diff) - reference_link = references[int(reference) - 1] - - if id in xample_file_whole: - print("[+] Skipping {} because already present".format(id)) - continue - - - if 'T' in id: # Determine if ATT&CK technique - attack_link = "https://attack.mitre.org/techniques/{}/".format(id.replace('(', '').replace(')', '').replace('.', '/')) - technique_text = "|[{} {}]({})|{} [[{}]](#{})|\n".format(technique_behavior, id, attack_link, description, reference, reference) - - behaviors_line = file_search(xample_file_lines, 'Behaviors') - xample_file_lines.insert(behaviors_line, technique_text) - - print("[+] Inserting ATT&CK technique: {}\n".format(technique_behavior)) - - else: # If it is an MBC behavior - # Try to fuzzy match the input behavior to a file - print("[+] Searching for {}".format(technique_behavior)) - mbc_file = fuzzy_file_directory_search(mbc_file_map, technique_behavior) - print("[+] Behavior found: {}".format(mbc_file)) - - behavior_text = "|[{} {}]({})|{} [[{}]](#{})|\n".format(technique_behavior, id, mbc_file, description, reference, reference) - - references_line = file_search(xample_file_lines, 'References') - xample_file_lines.insert(references_line, behavior_text) - - # Add malware entry into the behavior file itself - populate_behavior(name_line[0], date, reference_link, mbc_file, description, modified_xample_file) - - # Fix some spacing issues between sections if present - behaviors_line = file_search(xample_file_lines, 'Behaviors') - if xample_file_lines[behaviors_line - 1] != '\n': - xample_file_lines.insert(behaviors_line, '\n') - - references_line = file_search(xample_file_lines, 'References') - if xample_file_lines[references_line - 1] != '\n': - xample_file_lines.insert(references_line, '\n') - - - with open(modified_xample_file, "w") as f: - f.writelines(xample_file_lines) - -def main(): - if len(sys.argv) != 2: - print("This script needs one command-and-scripting-interpreter parameters: the path to the input file") - return - - - input_file = sys.argv[1] - populate_malware_example(input_file) - return - - -if __name__=="__main__": - main() \ No newline at end of file diff --git a/zscript/capa_analysis.py b/zscript/capa_analysis.py deleted file mode 100755 index 1327caa..0000000 --- a/zscript/capa_analysis.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/python3 - -import os -import re -import sys -from collections import Counter - -import termplotlib as tpl -import yaml - - -# Walk through capa directory, ignoring files within the ignorelist folders -# Read each file and use regex to match mbc or attack mappings -# If found, insert them into the corresponding Counter -def dir_walk(directory): - attack_regex = "att&ck:\s*- ([^\n]*)" - mbc_regex = "mbc:\s*- ([^\n]*)" - ignorelist = ["nursery", '.github', 'LICENSE.txt', 'README.md', '.gitattributes', '.git'] - - attack_mappings = Counter() - mbc_mappings = Counter() - - # Iterate recursively over all files in the repo - for root, dirs, files in os.walk(directory): - if not any(block in root for block in ignorelist): - for name in files: - f = open(os.path.join(root, name), "r") - capa_rule = f.read() # Read contents of each capa rule - - attack = re.search(attack_regex, capa_rule) # Search capa rule for attack mapping, if found, add to attack counter - if attack: - attack_mappings.update(Counter([attack.group(1)])) - - mbc = re.search(mbc_regex, capa_rule) - if mbc: - mbc_mappings.update(Counter([mbc.group(1)])) - - return attack_mappings, mbc_mappings - -def plot(dict): - keys = list(dict.keys()) - nums = [dict[x]['num'] for x in keys] - fig = tpl.figure() - fig.barh(nums, keys, force_ascii=True) - fig.show() - -# Takes a list of tactics/behaviors and converts them as keys in a dict -# Iterates over list of mappings and split the strings to separate tactics/techniques, behaviors/methods -# Insert into dictionary -# Print out results and create a histogram -def analysis(map, keys, mbc_micro_behaviors=None): - tactic_behavior_dict = {k: {'num':0, 'rule':[]} for k in keys} - if mbc_micro_behaviors: - micro_behavior_dict = {k: {'num':0, 'rule':[]} for k in mbc_micro_behaviors} - - for mapping in map: - try: - split_map = mapping.split("::", 1) - tactic_behavior = split_map[0] - tactic_behavior_dict[tactic_behavior]['rule'].append(split_map[1]) - tactic_behavior_dict[tactic_behavior]['num'] += 1 - except KeyError: - if mbc_micro_behaviors: - try: - micro_behavior_dict[tactic_behavior]['rule'].append(split_map[1]) - micro_behavior_dict[tactic_behavior]['num'] += 1 - except KeyError: - print("The following MBC mapping could not be identified: " + str(mapping)) - else: - print("The following ATT&CK mapping could not be identified: " + str(mapping)) - - - - - if mbc_micro_behaviors is None: - print("---------ATT&CK MAPPINGS---------") - print(yaml.dump(tactic_behavior_dict, default_flow_style=False)) - plot(tactic_behavior_dict) - else: - print("\n---------MBC MAPPINGS---------") - print(yaml.dump(tactic_behavior_dict, default_flow_style=False)) - plot(tactic_behavior_dict) - print("\n---------MBC MICRO-BEHAVIOR MAPPINGS---------") - print(yaml.dump(micro_behavior_dict, default_flow_style=False)) - plot(micro_behavior_dict) - -def return_mbc_mapping(capa_dir): - attack_mapping, mbc_mapping = dir_walk(capa_dir) - return dict(mbc_mapping) - - -if __name__ == "__main__": - if sys.argv[1] == "-h": - print("This script analyzes the capa repo to determine the coverage wrt ATT&CK + MBC. \n Usage: python3 capa_analysis.py ") - directory = sys.argv[1] - - attack_tactics = ["Reconnaissance", "Resource Development", "Initial Access", "Execution", "Persistence", "Privilege Escalation", "Defense Evasion", "Credential Access", "Discovery", "Lateral Movement", "Collection", "Command and Control", "Exfiltration", "Impact"] - mbc_behaviors = ["Anti-Behavioral Analysis", "Anti-Static Analysis", "Collection", "Command and Control", "Credential Access", "Defense Evasion", "Discovery", "Execution", "Exfiltration", "Impact", "Lateral Movement","Persistence", "Privilege Escalation"] - mbc_micro_behaviors = ["Communication", "Cryptography", "Data", "File System", "Hardware", "Memory", "Operating System", "Process"] - - - attack_mapping, mbc_mapping = dir_walk(directory) - analysis(attack_mapping, attack_tactics) - - analysis(mbc_mapping, mbc_behaviors, mbc_micro_behaviors=mbc_micro_behaviors) - - print(dict(mbc_mapping)) \ No newline at end of file diff --git a/zscript/cape_analysis.py b/zscript/cape_analysis.py deleted file mode 100644 index 923da11..0000000 --- a/zscript/cape_analysis.py +++ /dev/null @@ -1,57 +0,0 @@ -""" -Analyze CAPEv2 community signature modules, extract information, and produce -CSV content. -""" -import argparse -import csv -import importlib -import inspect -import logging -import logging.config -import pathlib -import stix2 -import stix2.utils -import sys - -# From CAPEv2, or the stubs -import lib.cuckoo.common.abstracts - -# From CAPEv2 community repo; successfully importing this module probably -# requires adding the appropriate path to $PYTHONPATH. -# -# See: https://github.com/kevoreilly/community -import modules.signatures - - -def parse_args(): - """ - Parse commandline arguments. - """ - arg_parser = argparse.ArgumentParser( - description="Analyze CAPEv2 community signatures and create CSV" - " content." - ) - - - arg_parser.add_argument( - "-o", "--out", required=True, - help=""" - Directory path to the CAPE community repo. - """ - ) - - arg_parser.add_argument( - "-o", "--out", required=True - help=""" - A filename to write content to. If not given, write to stdout. - """ - ) - - return arg_parser.parse_args() - - -def main(): - - -if __name__ == "__main__": - main() diff --git a/zscript/example_input b/zscript/example_input deleted file mode 100644 index 5e8a6a8..0000000 --- a/zscript/example_input +++ /dev/null @@ -1,10 +0,0 @@ -Kraken X0010 -Date 2008 -Reference [1] http://blog.threatexpert.com/2008/04/kraken-changes-tactics.html - - -Command and Control::Dynamic Resolution:Domain Generation Algorithms (T1568.002) [1] Uses a domain name generator.  -Command and Control::Application Layer Protocol::Web Protocols (T1568.002) [1] The malware uses HTTP to communicate with C2 - -Command and Control::Domain Name Generation (B0003) [1] -Anti-Behavioral Analysis::Memory Dump Evasion (B0006) [1] Dumping Kraken's c.dll module from the heap of its own process is tricky because its PE-header is wiped out. diff --git a/zscript/fill_detection.py b/zscript/fill_detection.py deleted file mode 100644 index 5dda876..0000000 --- a/zscript/fill_detection.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/python - -import argparse -import re -import subprocess -import yaml - -from capa_analysis import return_mbc_mapping - -objective_list = ['anti-behavioral-analysis', 'anti-static-analysis', 'collection', 'command-and-control', 'credential-access', 'defense-evasion', 'discovery', 'execution', 'exfiltration', 'impact', 'lateral-movement', 'micro-behaviors', 'persistence', 'privilege-escalation'] -capa_rule_blacklist = ['README', 'format'] - -def yaml_find(d, tag): - if tag in d: - yield d[tag] - for k, v in d.items(): - if isinstance(v, dict): - for i in yaml_find(v, tag): - yield i - - - -# Fills file with the detection capa + CAPE headers. Returns new lines and indexes of capa and cape indicating where new entries should be placed -def fill_detection(behavior_lines, index): - behavior_lines.insert(index, "\n") - behavior_lines.insert(index+1, "## Detection\n") - behavior_lines.insert(index+2, "\n") - behavior_lines.insert(index+3, "|Tool: capa|Mapping|APIs|\n") - behavior_lines.insert(index+4, "|---|---|---|\n") - behavior_lines.insert(index+5, "\n") - behavior_lines.insert(index+6, "|Tool: CAPE|Mapping|APIs|\n") - behavior_lines.insert(index+7, "|---|---|---|\n") - behavior_lines.insert(index+8, "\n") - - return behavior_lines, index+5, index+8 - - -# Starting at 'index', parse each line for text in between '[]', which is the rule name. Ends when a blank line is reached. Returns array of rules -def detect_existing_rules(behavior_lines, index): - rules = [] - rule_line = behavior_lines[index] - rule_re = "\[([^\]]+)]" - - while capa_line != "\n": - rules.append(re.search(rule_re, rule_line).group(1)) - - index += 1 - capa_line = behavior_lines[index] - - return rules - -# Searches capa-rules repo for mentions of id using subprocess + grep, returns list of capa files that have MBC rule -def search_capa_rules(id, capa_repo): - capa_rule_paths = [] - grep_output = subprocess.run(["grep", "-r", id, capa_repo], capture_output=True) - grep_output = grep_output.stdout - - rules = grep_output.decode().split('\n') - - for rule in rules: - if rule == '': - continue - - rule_path = rule.split(' ', 1)[0][:-1] - - if not any(substring in rule_path for substring in capa_rule_blacklist): - capa_rule_paths.append(rule_path) - - return capa_rule_paths - - -# Parses given capa rules and generates and inserts text into MBC file -def fill_capa_rules(capa_rules_path, behavior_lines): - for rule in capa_rules_path: - with open(rule) as f: - capa_yaml = yaml.safe_load(f) - f.close() - - # print(capa_yaml) - rule_name = capa_yaml['rule']['meta']['name'] - api = list(yaml_find(capa_yaml, 'api')) - - if len(api) > 1: - raise Exception(">1 API FOUND") - - api = api[0] - - - - print(capa_yaml.keys()) - print(rule_name) - print(api) - - - - raise Exception - - - - - -def test(file): - try: - with open(file) as f: - behavior_lines = f.readlines() - f.close() - except FileNotFoundError: - print("[X] FILE NOT FOUND: " + file) - return -1 - - # Determine if 'Detection' section already present - if "## Detection\n" not in behavior_lines: - if "## Code Snippets\n" in behavior_lines: - index = behavior_lines.index("## Code Snippets\n") - 1 - elif "## References\n" in behavior_lines: - index = behavior_lines.index("## References\n") - 1 - else: - print("[X] Code Snippet or Reference Section not found") - return -1 - - behavior_lines, capa_index, cape_index = fill_detection(behavior_lines, index) - - - else: - capa_index = behavior_lines.index("|Tool: capa|Mapping|APIs|\n") + 2 - cape_index = behavior_lines.index("|Tool: CAPE|Mapping|APIs|\n") + 2 - - # If 'Detection' section present, detect existing rules - capa_rules = detect_existing_rules(behavior_lines, capa_index) - cape_rules = detect_existing_rules(behavior_lines, cape_index) - - - - - - with open(file, 'w') as f: - for line in behavior_lines: - f.write(line) - f.close() - - -def main(): - # Initialize parser - parser = argparse.ArgumentParser(description="Inserts a 'detection' section into behaviors. The section will contain info on capa and cape rules related to that behavior") - - # Adding arguments - parser.add_argument("-i", "--id", help = "ID (B0001)") - parser.add_argument("-o", "--objective", nargs='+', help = "Objectives separated by spaces, replace spaces within the name with underscore (Anti-Behavioral_Analysis Anti-Static_Analysis)") - parser.add_argument("-a", "--attack", nargs='+', help = "Related ATT&CK Techniques grouped by name and ID (Debugger_Evasion,T1622 Virtualization/Standbox_Evasion_Checks,T1497.001,T1633.001)") - parser.add_argument("-t", "--type", help = "Anti-Analysis or Impact Types (Evasion, Detection, Integrity, Breach, Availability)") - parser.add_argument("-v", "--version", help="Version") - - parser.add_argument("-m", "--last_modified", help="Last modified date (1_August_2019)") - - parser.add_argument("-c", "--capa", help="capa-rules directory", required=True) - parser.add_argument("-f", "--file") - - # Read arguments from command line - args = parser.parse_args() - - if args.file: - test(args.file) - return - - # Gets a dict of all behaviors that are mentioned in capa, along with count - capa_behaviors = return_mbc_mapping(args.capa) - - for behavior, count in capa_behaviors.items(): - # Splitting dict entry into behavior and id - # EX: communication/socket-communication/create-udp-socket, C0001.010 - str_split = behavior.split(" [", 1) - behavior_path = str_split[0].lower().replace('::', '/').replace(' ', '-') - id = str_split[1][:-1] - - # if method or sub-microbehavior, remove portion from path - if '.' in id: - str_split = behavior_path.split("/")[:-1] - behavior_path = '/'.join(str_split) - - # If microbehavior, add 'micro-behaviors' to behavior path - objective = behavior_path.split('/')[0] - if objective not in objective_list: - behavior_path = 'micro-behaviors/' + behavior_path - - behavior_path = '../' + behavior_path + '.md' - try: - with open(behavior_path) as f: - behavior_lines = f.readlines() - f.close() - except FileNotFoundError: - print("[X] FILE NOT FOUND: " + behavior_path) - return -1 - - if "## Code Snippets\n" in behavior_lines: - index = behavior_lines.index("## Code Snippets\n") - 1 - elif "## References\n" in behavior_lines: - index = behavior_lines.index("## References\n") - 1 - else: # If Code Snippet or Reference Section missing, return index of last line - index = len(behavior_lines) - 1 - - x = search_capa_rules(id, args.capa) - - fill_capa_rules(x, behavior_lines) - - - - - # print(capa_behaviors.keys()) - # print(yaml.dump(capa_behaviors, default_flow_style=False)) - - - - -if __name__=="__main__": - main() \ No newline at end of file diff --git a/zscript/fill_header.py b/zscript/fill_header.py deleted file mode 100644 index 9bae604..0000000 --- a/zscript/fill_header.py +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/python - -import argparse - -from fuzzywuzzy import fuzz # pip install fuzzywuzzy python-Levenshtein - -objective_list = ['anti-behavioral-analysis', 'anti-static-analysis', 'collection', 'command-and-control', 'credential-access', 'defense-evasion', 'discovery', 'execution', 'exfiltration', 'impact', 'lateral-movement', 'micro-behaviors', 'persistence', 'privilege-escalation'] -anti_analysis_types = ['Evasion', 'Detection'] -impact_types = ['Integrity', 'Breach', 'Availability'] - -# Checks if 'string' in 'l' at index 'line_num'. If missing, insert 'string' into 'l' at index 'line_num' -# Return possibly modified 'l' -def insert_if_missing(l, line_num, string): - if l[line_num] != string: - l.insert(line_num, string) - - return l - -# Matches string to an entry in objective_list -def objective_search(string): - string = string.lower().replace('_', '-') - - if string not in objective_list: - raise Exception("Objective {} did not match anything: ".format(string)) - - return "../" + string - -def main(): - # Initialize parser - parser = argparse.ArgumentParser(description="Inserts a formatted header for MBC. Only add parameters that are missing. In case of bugs, only run on a second copy") - - # Adding arguments - parser.add_argument("-f", "--file", help = "File to modify", required=True) - parser.add_argument("-i", "--id", help = "ID (B0001)") - parser.add_argument("-o", "--objective", nargs='+', help = "Objectives separated by spaces, replace spaces within the name with underscore (Anti-Behavioral_Analysis Anti-Static_Analysis)") - parser.add_argument("-a", "--attack", nargs='+', help = "Related ATT&CK Techniques grouped by name and ID (Debugger_Evasion,T1622 Virtualization/Standbox_Evasion_Checks,T1497.001,T1633.001)") - parser.add_argument("-t", "--type", help = "Anti-Analysis or Impact Types (Evasion, Detection, Integrity, Breach, Availability)") - parser.add_argument("-v", "--version", help="Version") - parser.add_argument("-c", "--created", help="Method Creation Date (1_August_2019)") - parser.add_argument("-m", "--last_modified", help="Last modified date (1_August_2019)") - - # Read arguments from command line - args = parser.parse_args() - - # Read file - file = args.file - with open(file) as f: - lines = f.readlines() - f.close() - - offset = 0 # Handles unique fields such as anti-analysis/impact type - - # Some files have an empty line 1, delete that - if lines[0] == '\n': - lines.pop(0) - - # Checking if first line is , if not, that means this file does not have any appropriate header formatting - lines = insert_if_missing(lines, 0, "
\n") - lines = insert_if_missing(lines, 1, "\n") - - # Adding ID field - if args.id: - lines = insert_if_missing(lines, 2, "\n") - lines.insert(3, "\n".format(args.id)) - lines.insert(4, "\n") - - # Adding Objective field - if args.objective: - lines = insert_if_missing(lines, 5, "\n") - lines = insert_if_missing(lines, 6, "\n") - - # Build objectives if multiple - obj_str = "\n" - - lines.insert(7, obj_str) - lines.insert(8, "\n") - - # Adding Related ATT&CK Techniques Field - if args.attack: - lines = insert_if_missing(lines, 9, "\n") - lines = insert_if_missing(lines, 10, "\n") - - # Build attack links if multiple - attack_str = "\n" - - lines.insert(11, attack_str) - lines.insert(12, "\n") - print(attack_str) - - # Adding Anti-Analysis/Impact Type - if args.type: - if args.type in impact_types: - lines.insert(13, "\n") - lines = insert_if_missing(lines, 14, "\n") - - elif args.type in anti_analysis_types: - lines.insert(13, "\n") - lines = insert_if_missing(lines, 14, "\n") - - else: - raise Exception("Anti-Analysis/Impact Type is not valid") - - lines.insert(15, "\n".format(args.type)) - lines.insert(16, "\n") - - offset += 4 - - # Adding version field - if args.version: - lines = insert_if_missing(lines, 13+offset, "\n") - lines = insert_if_missing(lines, 14+offset, "\n") - - lines.insert(15+offset, "\n".format(args.version)) - lines.insert(16+offset, "\n") - - # Adding Created field - if args.created: - lines = insert_if_missing(lines, 17+offset, "\n") - lines = insert_if_missing(lines, 18+offset, "\n") - - created = args.created.replace('_', ' ') - lines.insert(19+offset, "\n".format(created)) - lines.insert(20+offset, "\n") - - # Adding Last Modified Field - if args.last_modified: - lines = insert_if_missing(lines, 21+offset, "\n") - lines = insert_if_missing(lines, 22+offset, "\n") - - last_modified = args.last_modified.replace('_', ' ') - lines.insert(23+offset, "\n".format(last_modified)) - lines.insert(24+offset, "\n") - - lines = insert_if_missing(lines, 25+offset, "
ID{}
Objective(s)" - for objective in args.objective: - obj_path = objective_search(objective) - objective = objective.replace('_', ' ') - - obj_str = obj_str + "{}, ".format(obj_path, objective) - - # Chop off last ', ' - obj_str = obj_str[:len(obj_str) - 2] - obj_str = obj_str + "
Related ATT&CK Techniques" - for attack in args.attack: - attack = attack.split(",") - attack_name = attack[0].replace('_', ' ') - - attack_str = attack_str + attack_name + " (" - - # Looking at technique IDs now - for i in range(1, len(attack)): - attack_id = attack[i] - attack_id_dash = attack_id.replace('.', '/') - - attack_str = attack_str + "{}, ".format(attack_id_dash, attack_id) - - # Chop off last ', ' - attack_str = attack_str[:len(attack_str) - 2] - attack_str = attack_str + "), " - - # Chop off last ', ' - attack_str = attack_str[:len(attack_str) - 2] - attack_str = attack_str + "
Impact Type
Anti-Analysis Type{}
Version{}
Created{}
Last Modified{}
\n") - lines = insert_if_missing(lines, 26+offset, "\n") - - # Now that modifications are complete, write to file - with open(file, "w") as f: - for line in lines: - f.write(line) - - f.close() - - return - -if __name__=="__main__": - main() \ No newline at end of file diff --git a/zscript/input b/zscript/input deleted file mode 100644 index e69de29..0000000 diff --git a/zscript/test_file.md b/zscript/test_file.md deleted file mode 100644 index cceedf9..0000000 --- a/zscript/test_file.md +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - -
IDE1113
Objective(s)Collection, Credential Access
Related ATT&CK TechniquesScreen Capture (T1113)
Version2.0
Created1 August 2019
Last Modified31 October 2022
- - -# Screen Capture - -Malware takes screen captures of the desktop. - -See ATT&CK: **Screen Capture ([T1113](https://attack.mitre.org/techniques/T1113/))**. - -## Methods - -|Name|ID|Description| -|---|---|---| -|**WinAPI**|E1113.m01|Screen is captured using WinAPI functions (e.g., user32.GetDesktopWindow).| - - -## Use in Malware - -|Name|Date|Description| -|---|---|---| -|[**GotBotKR**](../xample-malware/gobotkr.md)|2019| GoBotKR is capable of capturing screenshots. [[1]](#1)| -|[**BlackEnergy**](../xample-malware/blackenergy.md)|2007|Screenshot plugin allows for collection of screenshots [[2]](#2)| -|[**DarkComet**](../xample-malware/dark-comet.md)|2008|Can take screenshots of victim's computer [[3]](#3)| - - -## Detection - -|Tool: capa|Mapping|APIs| -|---|---|---| -|[check for microsoft office emulation](https://github.com/mandiant/capa-rules/blob/master/anti-analysis/anti-vm/vm-detection/check-for-microsoft-office-emulation.yml)|[Sandbox Detection::Product Key/ID Testing (B0007.005)|CreateFile| -|[check for sandbox and av modules](https://github.com/mandiant/capa-rules/blob/master/anti-analysis/anti-av/check-for-sandbox-and-av-modules.yml)|Sandbox Detection (B0007)|GetModuleHandle| - -|Tool: CAPE|Mapping|APIs| -|---|---|---| -|[antisandbox_joe_anubis_files.py](https://github.com/kevoreilly/community/blob/master/modules/signatures/antisandbox_joe_anubis_files.py)|Sandbox Detection::Check Files (B0007.002)|--| -|[antisandbox_cuckoo_files](https://github.com/kevoreilly/community/blob/master/modules/signatures/antisandbox_cuckoo_files.py)|Sandbox Detection::Check Files (B0007.002)|--| - -## References - -
[1] https://www.welivesecurity.com/2019/07/08/south-korean-users-backdoor-torrents/ - -[2] https://securelist.com/be2-custom-plugins-router-abuse-and-target-profiles/67353/ - -[3] https://blog.malwarebytes.com/threat-analysis/2012/06/you-dirty-rat-part-1-darkcomet/ diff --git a/zscript/use_in_malware_method.py b/zscript/use_in_malware_method.py deleted file mode 100644 index 769f2ba..0000000 --- a/zscript/use_in_malware_method.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import re - - -def dir_walk(directory): - ignorelist = ["nursery", '.github', '.git', 'LICENSE.txt', 'README.md', '.gitattributes', 'ynewsletters', 'yfaq', 'zscript'] - - # Iterate recursively over all files in the repo - for root, dirs, files in os.walk(directory): - if not any(block in root for block in ignorelist): - for name in files: - f = open(os.path.join(root, name), "r") - lines = f.readlines() # Read contents of each capa rule - f.close() - - try: - index = lines.index('## Use in Malware\n') - except ValueError: - continue - - # if lines[index+2] != "|Name|Date|Description|\n": - # print("{} has format issue".format(os.path.join(root,name))) - - try: - index = lines.index('|Name|Date|Method|Description|\n') - except ValueError: - print("{} has format issue".format(os.path.join(root,name))) - break - - index = lines.index("Last Modified\n") - lines[index+1] = "21 November 2022\n" - - - with open(os.path.join(root, name), 'w') as f: - for line in lines: - f.write(line) - f.close() - - - - - - # for line in lines: - # equals = re.search("={3,}\n", line) # Search capa rule for attack mapping, if found, add to attack counter - - # if equals: - # print(os.path.join(root, name)) - # index = lines.index(equals.group(0)) - # lines.remove(equals.group(0)) - # lines[index-1] = "# {0}\n".format(lines[index-1]) - - - # with open(os.path.join(root, name), 'w') as f: - # for line in lines: - # f.write(line) - # f.close() - - - -dir_walk('..') \ No newline at end of file