# Snakes on a Domain: An Analysis of a Python Malware Loader

A malicious sysmon.lnk in a startup folder launched a renamed IronPython interpreter running update.py, chaining six obfuscated payloads to inject a URSU RAT via msbuild.exe process hollowing.

- Payout: Real-world hack
- Program: URSU RAT
- Analysis by: Huntress
- Disclosed: 2021-08-17
- Write-up quality: 7/10
- Original: https://www.huntress.com/blog/snakes-on-a-domain-an-analysis-of-a-python-malware-loader
- Library page: https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-snakes-on-a-domain-an-analysis-of-a-python-malware-loader
- Tags: area:os domain:desktop impact:internal-access impact:rce kind:incident platform:threat-intel tech:dotnet tech:python tech:windows technique:reverse-engineering technique:source-review vuln:misconfiguration

**Target:** Windows endpoint startup folder / .lnk shortcut and Python loader chain
**Root cause:** A .lnk file placed in the user's Startup folder persisted across reboots and pointed to a renamed IronPython interpreter (ctfmon.exe) executing update.py, which decoded and executed a chain of obfuscated payloads ending in a RAT.
**Steps:**
1. Locate `c:\users\<username>\appdata\roaming\microsoft\windows\startmenu\programs\startup\sysmon.lnk`
2. Inspect the .lnk: it redirects to `c:\users\<username>\appdata\roaming\PpvcbBQh\ctfmon.exe` with `update.py` as argument
3. Identify ctfmon.exe as a renamed IronPython interpreter (0 VT detections)
4. stage1.py: Base64-decode string, convert to bytearray, subtract 12 from each byte, execute result
5. stage2.py: replace `!` with `A`, Base64-decode to get MZ executable (stage3.bin)
6. stage3.bin (.NET): Base64-decode + Gzip-decompress embedded payload, then Mandark.Load injects into `msbuild.exe` via process hollowing (ZwUnmapViewOfSection)
7. stage4.bin (C++): execute-assembly loader; extract embedded payload in format `0|0|0|0|1|sizeofpayload.b64_encoded_compressed_payload`, Base64+Gzip decode to stage5.bin
8. stage5.bin (.NET): Base64-decode AMSI patching script; decode second string with custom Cipher routine using key `avyhk` and encipher flag false to get stage6.bin
9. stage6.bin: URSU RAT; decrypt AES256+Base64 config in InitializeSettings to recover C2 domains and port
10. RAT performs WMI enumeration, anti-VM/debugger checks, then persists via scheduled task (admin) or Run key .bat (user) and contacts C2 for commands
**How found:** A suspicious sysmon.lnk persisting in a user's startup folder looked fishy; inspecting the shortcut revealed it launched a renamed ctfmon.exe (IronPython) with update.py, prompting staged deobfuscation in CyberChef and Dnspy.
**Exploitation:** Attacker placed sysmon.lnk in the victim's Startup folder for reboot persistence; on login it launched the renamed IronPython interpreter with update.py, which decoded and executed successive obfuscated stages, ultimately hollowing msbuild.exe (whitelisted by AppLocker) to run a URSU RAT that enumerated the host, evaded VM/analysis, established Run-key/scheduled-task persistence, and beaconed to C2 domains for update/plugin/unload/restart/self-delete commands.
**Escalation:** Chained six payloads with layered obfuscation (Base64, byte-shift, custom cipher, Gzip) and used msbuild.exe process hollowing plus AMSI patching to evade detection; admin privileges upgrade persistence to an elevated scheduled task.
**Insight:** Renamed legitimate interpreters (IronPython) and whitelisted binaries like msbuild.exe are ideal hollowing targets; when a .lnk in Startup points to a non-standard interpreter running a .py, treat the script as the real payload and peel layers with CyberChef/Dnspy, watching for custom ciphers with embedded keys.

