mirror of
https://github.com/dobin/SuperMega
synced 2026-06-02 17:27:10 +00:00
feature: rework guardrails
This commit is contained in:
@@ -211,7 +211,8 @@ def add_project():
|
|||||||
settings.decoder_style = request.form['decoder_style']
|
settings.decoder_style = request.form['decoder_style']
|
||||||
payload_location = request.form['payload_location']
|
payload_location = request.form['payload_location']
|
||||||
settings.payload_location = PayloadLocation[payload_location]
|
settings.payload_location = PayloadLocation[payload_location]
|
||||||
settings.plugin_guardrail_data = request.form.get('guardrail_data', settings.plugin_guardrail_data)
|
settings.plugin_guardrail_data_key = request.form.get('guardrail_data_key', settings.plugin_guardrail_data_key)
|
||||||
|
settings.plugin_guardrail_data_value = request.form.get('guardrail_data_value', settings.plugin_guardrail_data_value)
|
||||||
settings.plugin_virtualprotect = request.form.get('virtualprotect', "standard")
|
settings.plugin_virtualprotect = request.form.get('virtualprotect', "standard")
|
||||||
|
|
||||||
# overwrite project
|
# overwrite project
|
||||||
|
|||||||
@@ -1,29 +1,46 @@
|
|||||||
|
|
||||||
|
char my_tolower(char c) {
|
||||||
|
if (c >= 'A' && c <= 'Z') {
|
||||||
|
return c + ('a' - 'A'); // or return c + 32;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
int mystrcmp(wchar_t* str1, wchar_t* str2) {
|
// Returns 1 if 'needle' is found in 'haystack' (case-insensitive), 0 otherwise
|
||||||
int i = 0;
|
int contains_case_insensitive(const char* haystack, const char* needle) {
|
||||||
while (str1[i] != L'\0' && str2[i] != L'\0') {
|
if (!haystack || !needle)
|
||||||
if (str1[i] != str2[i]) {
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
for (; *haystack; haystack++) {
|
||||||
i++;
|
const char* h = haystack;
|
||||||
}
|
const char* n = needle;
|
||||||
return 0;
|
|
||||||
|
while (*h && *n && my_tolower((unsigned char)*h) == my_tolower((unsigned char)*n)) {
|
||||||
|
h++;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*n == '\0') {
|
||||||
|
return 1; // Match found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // No match
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int executionguardrail() {
|
int executionguardrail() {
|
||||||
// Execution Guardrail: Env Check
|
// Execution Guardrail: Env Check
|
||||||
wchar_t envVarName[] = L"USERPROFILE";
|
LPCSTR envVarName = "{{guardrail_data_key}}";
|
||||||
wchar_t tocheck[] = L"{{guardrail_data}}";
|
LPCSTR tocheck = "{{guardrail_data_value}}";
|
||||||
WCHAR buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency!
|
char buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency!
|
||||||
DWORD result = GetEnvironmentVariableW(envVarName, buffer, 1024);
|
DWORD result = GetEnvironmentVariableA(envVarName, buffer, 1024);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
if (mystrcmp(buffer, tocheck) != 0) {
|
if (! contains_case_insensitive(buffer, tocheck)) {
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -17,7 +17,8 @@ class Settings():
|
|||||||
self.plugin_antiemulation: str = "none"
|
self.plugin_antiemulation: str = "none"
|
||||||
self.plugin_decoy: str = "none"
|
self.plugin_decoy: str = "none"
|
||||||
self.plugin_guardrail: str = "none"
|
self.plugin_guardrail: str = "none"
|
||||||
self.plugin_guardrail_data: str = "C:\\\\Users\\\\hacker"
|
self.plugin_guardrail_data_key: str = ""
|
||||||
|
self.plugin_guardrail_data_value: str = ""
|
||||||
self.plugin_virtualprotect: str = "standard"
|
self.plugin_virtualprotect: str = "standard"
|
||||||
self.plugin_virtualprotect_data: str = ""
|
self.plugin_virtualprotect_data: str = ""
|
||||||
|
|
||||||
|
|||||||
+10
-4
@@ -53,9 +53,14 @@ def create_c_from_template(settings: Settings, payload_len: int):
|
|||||||
logger.info(" Carrier AntiEmulation: {}".format(
|
logger.info(" Carrier AntiEmulation: {}".format(
|
||||||
settings.plugin_antiemulation)
|
settings.plugin_antiemulation)
|
||||||
)
|
)
|
||||||
logger.info(" Carrier Guardrail: {}".format(
|
if settings.plugin_guardrail != "none":
|
||||||
settings.plugin_guardrail)
|
logger.info(" Carrier Guardrail: {} (key: {} value: {})".format(
|
||||||
)
|
settings.plugin_guardrail,
|
||||||
|
settings.plugin_guardrail_data_key,
|
||||||
|
settings.plugin_guardrail_data_value)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.info(" Carrier Guardrail: none")
|
||||||
logger.info(" Carrier Decoy: {}".format(
|
logger.info(" Carrier Decoy: {}".format(
|
||||||
settings.plugin_decoy)
|
settings.plugin_decoy)
|
||||||
)
|
)
|
||||||
@@ -75,7 +80,8 @@ def create_c_from_template(settings: Settings, payload_len: int):
|
|||||||
with open(filepath_guardrails, "r", encoding='utf-8') as file:
|
with open(filepath_guardrails, "r", encoding='utf-8') as file:
|
||||||
plugin_guardrails = file.read()
|
plugin_guardrails = file.read()
|
||||||
plugin_guardrails = Template(plugin_guardrails).render({
|
plugin_guardrails = Template(plugin_guardrails).render({
|
||||||
'guardrail_data': settings.plugin_guardrail_data,
|
'guardrail_data_key': settings.plugin_guardrail_data_key,
|
||||||
|
'guardrail_data_value': settings.plugin_guardrail_data_value,
|
||||||
})
|
})
|
||||||
|
|
||||||
# Plugin: Decoder
|
# Plugin: Decoder
|
||||||
|
|||||||
+33
-7
@@ -34,7 +34,10 @@ def main():
|
|||||||
parser.add_argument('--carrier', type=str, help='carrier: data/source/carrier/* (alloc_rw_rx, peb_walk, ...)', default="alloc_rw_rx")
|
parser.add_argument('--carrier', type=str, help='carrier: data/source/carrier/* (alloc_rw_rx, peb_walk, ...)', default="alloc_rw_rx")
|
||||||
parser.add_argument('--decoder', type=str, help='decoder: data/source/decoders/* (xor_1, xor_2, plain, ...)', default="xor_2")
|
parser.add_argument('--decoder', type=str, help='decoder: data/source/decoders/* (xor_1, xor_2, plain, ...)', default="xor_2")
|
||||||
parser.add_argument('--antiemulation', type=str, help='anti-emulation: data/source/antiemulation/* (sirallocalot, timeraw, none, ...)', default="sirallocalot")
|
parser.add_argument('--antiemulation', type=str, help='anti-emulation: data/source/antiemulation/* (sirallocalot, timeraw, none, ...)', default="sirallocalot")
|
||||||
parser.add_argument('--fix-iat', action='store_true', help='Fix missing IAT entries in the infectable executable', default=True)
|
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('--no-fix-iat', action='store_true', help='Fix missing IAT entries in the infectable executable', default=False)
|
||||||
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, \"eop\" for entry point', choices=["eop", "backdoor"], default="backdoor")
|
||||||
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')
|
||||||
parser.add_argument('--short-call-patching', action='store_true', help='Debug: Make short calls long. You will know when you need it.')
|
parser.add_argument('--short-call-patching', action='store_true', help='Debug: Make short calls long. You will know when you need it.')
|
||||||
@@ -51,10 +54,23 @@ def main():
|
|||||||
else:
|
else:
|
||||||
setup_logging(logging.INFO)
|
setup_logging(logging.INFO)
|
||||||
|
|
||||||
settings.try_start_final_infected_exe = args.start_injected
|
settings.try_start_final_infected_exe = args.start
|
||||||
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.fix_missing_iat = not args.no_fix_iat
|
||||||
|
if args.guardrail:
|
||||||
|
settings.plugin_guardrail = args.guardrail
|
||||||
|
settings.plugin_guardrail_data_key = args.guardrail_key
|
||||||
|
settings.plugin_guardrail_data_value = args.guardrail_value
|
||||||
|
|
||||||
|
logger.info("-( Config: Implant IAT fixup if necessary: {}".format(settings.fix_missing_iat))
|
||||||
|
if settings.plugin_guardrail != "none":
|
||||||
|
logger.info("-( Config: Guardrails Plugin: {} {}/{}".format(
|
||||||
|
settings.plugin_guardrail,
|
||||||
|
settings.plugin_guardrail_data_key,
|
||||||
|
settings.plugin_guardrail_data_value))
|
||||||
|
|
||||||
# Shellcode: filename
|
# Shellcode: filename
|
||||||
# Inject: filename
|
# Inject: filename
|
||||||
settings.init_payload_injectable(
|
settings.init_payload_injectable(
|
||||||
@@ -130,14 +146,14 @@ def sanity_checks(settings):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def start_real(settings: Settings):
|
def start_real(settings: Settings) -> bool:
|
||||||
"""Main entry point for the application. This is where the magic happens (based on settings)"""
|
"""Main entry point for the application. This is where the magic happens (based on settings)"""
|
||||||
|
|
||||||
# Load our input
|
# Load our input
|
||||||
project = Project(settings)
|
project = Project(settings)
|
||||||
if not project.init():
|
if not project.init():
|
||||||
logger.error("Error initializing project")
|
logger.error("Error initializing project")
|
||||||
return 1
|
return False
|
||||||
|
|
||||||
# CHECK if 64 bit
|
# CHECK if 64 bit
|
||||||
if not project.injectable.superpe.is_64():
|
if not project.injectable.superpe.is_64():
|
||||||
@@ -158,7 +174,7 @@ def start_real(settings: Settings):
|
|||||||
phases.templater.create_c_from_template(settings, len(project.payload.payload_data))
|
phases.templater.create_c_from_template(settings, len(project.payload.payload_data))
|
||||||
except FileNotFoundError as e:
|
except FileNotFoundError as e:
|
||||||
logger.error("Error creating C from template: {}".format(e))
|
logger.error("Error creating C from template: {}".format(e))
|
||||||
return 1
|
return False
|
||||||
|
|
||||||
# PREPARE DataReuseEntry for usage in Compiler/AsmTextParser
|
# PREPARE DataReuseEntry for usage in Compiler/AsmTextParser
|
||||||
# So the carrier is able to find the payload
|
# So the carrier is able to find the payload
|
||||||
@@ -181,7 +197,7 @@ def start_real(settings: Settings):
|
|||||||
settings = project.settings)
|
settings = project.settings)
|
||||||
except ChildProcessError as e:
|
except ChildProcessError as e:
|
||||||
logger.error("Error compiling C to ASM: {}".format(e))
|
logger.error("Error compiling C to ASM: {}".format(e))
|
||||||
return
|
return False
|
||||||
|
|
||||||
# we have the carrier-required IAT entries in carrier.iat_requests
|
# we have the carrier-required IAT entries in carrier.iat_requests
|
||||||
# CHECK if all are available in infectable, or abort (early check)
|
# CHECK if all are available in infectable, or abort (early check)
|
||||||
@@ -190,7 +206,8 @@ def start_real(settings: Settings):
|
|||||||
logging.error("IAT entries not found in infectable: {}".format(", ".join(functions)))
|
logging.error("IAT entries not found in infectable: {}".format(", ".join(functions)))
|
||||||
logging.error("The carrier depends on these functions, but they are not available in the infectable exe.")
|
logging.error("The carrier depends on these functions, but they are not available in the infectable exe.")
|
||||||
logging.error("Use another infectable exe, or update the carrier to not depend on these functions.")
|
logging.error("Use another infectable exe, or update the carrier to not depend on these functions.")
|
||||||
raise Exception("Required carrier import not found in infectable: {}".format(", ".join(functions)))
|
logging.error(" or dont use --no-fix-iat")
|
||||||
|
return False
|
||||||
|
|
||||||
# ASSEMBLE: Assemble .asm to .shc (ASM -> SHC)
|
# ASSEMBLE: Assemble .asm to .shc (ASM -> SHC)
|
||||||
carrier_shellcode: bytes = phases.assembler.asm_to_shellcode(
|
carrier_shellcode: bytes = phases.assembler.asm_to_shellcode(
|
||||||
@@ -227,6 +244,15 @@ def start_real(settings: Settings):
|
|||||||
elif settings.try_start_final_infected_exe:
|
elif settings.try_start_final_infected_exe:
|
||||||
run_exe(settings.inject_exe_out, dllfunc=settings.dllfunc, check=False)
|
run_exe(settings.inject_exe_out, dllfunc=settings.dllfunc, check=False)
|
||||||
|
|
||||||
|
if settings.plugin_guardrail != "none":
|
||||||
|
logger.warning("! Remember your guardrails settings when testing")
|
||||||
|
logger.warning("! {}: {} / {}".format(
|
||||||
|
settings.plugin_guardrail,
|
||||||
|
settings.plugin_guardrail_data_key,
|
||||||
|
settings.plugin_guardrail_data_value))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def obfuscate_shc_loader(file_shc_in, file_shc_out):
|
def obfuscate_shc_loader(file_shc_in, file_shc_out):
|
||||||
logger.info(" Obfuscate shellcode with SGN")
|
logger.info(" Obfuscate shellcode with SGN")
|
||||||
|
|||||||
Reference in New Issue
Block a user