Files

96 lines
3.6 KiB
Python
Raw Permalink Normal View History

2026-08-27 11:22:11 -06:00
"""
Launch Remcos with SSL_CERT_FILE + apply IAT patches.
Run WHILE server_only.py is running in another terminal.
"""
import ctypes, ctypes.wintypes as wt, struct, subprocess, os, sys, time
PROCESS_ALL_ACCESS = 0x1F0FFF
PAGE_EXECUTE_READWRITE = 0x40
MEM_COMMIT, MEM_RESERVE = 0x1000, 0x2000
UNPACK_ADDR, UNPACK_SIG = 0x8EEED8, b'\x55\x8b\xec\x6a'
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
OpenProcess = kernel32.OpenProcess; OpenProcess.restype = wt.HANDLE
ReadProcessMemory = kernel32.ReadProcessMemory; ReadProcessMemory.restype = wt.BOOL
WriteProcessMemory = kernel32.WriteProcessMemory; WriteProcessMemory.restype = wt.BOOL
VirtualAllocEx = kernel32.VirtualAllocEx; VirtualAllocEx.restype = wt.LPVOID
VirtualProtectEx = kernel32.VirtualProtectEx; VirtualProtectEx.restype = wt.BOOL
CloseHandle = kernel32.CloseHandle
def read_mem(h, addr, sz):
buf = ctypes.create_string_buffer(sz); n = ctypes.c_size_t(0)
return buf.raw[:n.value] if ReadProcessMemory(h, addr, buf, sz, ctypes.byref(n)) else None
def write_mem(h, addr, data):
old = wt.DWORD(0)
VirtualProtectEx(h, addr, len(data), PAGE_EXECUTE_READWRITE, ctypes.byref(old))
n = ctypes.c_size_t(0); buf = ctypes.create_string_buffer(data)
ok = WriteProcessMemory(h, addr, buf, len(data), ctypes.byref(n))
VirtualProtectEx(h, addr, len(data), old.value, ctypes.byref(old))
return ok and n.value == len(data)
def main():
d = os.path.dirname(os.path.abspath(__file__))
exe = os.path.join(d, "Remcos v7.2.2 Pro.exe")
# Set SSL env
ca = os.path.join(d, "certs", "ca_bundle.pem")
if os.path.exists(ca):
os.environ["SSL_CERT_FILE"] = ca
os.environ["SSL_CERT_DIR"] = os.path.join(d, "certs")
print(f"[+] SSL_CERT_FILE={ca}")
# Kill old
subprocess.run(['taskkill', '/F', '/IM', 'Remcos v7.2.2 Pro.exe'], capture_output=True)
time.sleep(1)
# Launch
proc = subprocess.Popen([exe], cwd=d)
pid = proc.pid; print(f"[+] PID {pid}")
h = None
for _ in range(30):
h = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if h: break
time.sleep(0.1)
if not h: print("[-] Can't open"); return
# Wait unpack
print("[*] Waiting for unpack...")
t0 = time.time()
while time.time() - t0 < 45:
if proc.poll() is not None: print("[-] Exited early"); CloseHandle(h); return
if read_mem(h, UNPACK_ADDR, 4) == UNPACK_SIG: break
time.sleep(0.05)
else: print("[-] Timeout"); CloseHandle(h); return
print(f"[+] Unpacked {time.time()-t0:.1f}s"); time.sleep(0.2)
# Stubs
page = VirtualAllocEx(h, None, 4096, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
stub = bytearray(32)
stub[0x00] = 0xC3 # ret
stub[0x04:0x07] = b'\xC2\x04\x00' # ret 4
stub[0x08:0x10] = b'\xB8\x01\x00\x00\x00\xC2\x18\x00' # CryptVerify -> TRUE
write_mem(h, page, bytes(stub))
# Exit hooks
for addr, off, name in [(0x9DF18C,0,"Halt"),(0x4C36428,4,"PostQuitMessage"),
(0xA1007C,4,"ExitProcess1"),(0x4C36590,4,"ExitProcess2"),(0x4C36AE8,4,"ExitProcess3")]:
write_mem(h, addr, struct.pack('<I', page+off)); print(f" [+] {name}")
# Crypto IAT
for addr in [0x9DF0F8, 0x4C364FC]:
write_mem(h, addr, struct.pack('<I', page+0x08)); print(" [+] CryptVerify IAT")
# Builder gate
write_mem(h, 0x983F9C, b'\x01'); print(" [+] Builder gate=1")
# TLS init
write_mem(h, 0x97126C, struct.pack('<I', 1)); print(" [+] TLS flag=1")
print(f"\n[+] Done. Remcos PID {pid}")
print("[*] Enter email in auth dialog. Server handles the rest.")
CloseHandle(h)
proc.wait()
if __name__ == "__main__": main()