🚀 Forge Free is now live! Try it now

Unmarshalling Malware: Reverse Engineering a Python Infostealer on Windows

This writeup covers my reverse engineering process and analysis on a Python based Windows infostealer that is being actively distributed online. This malware targets browser credentials, crypto wallets, Discord accounts, telegram sessions and includes persistence and privilege escalation mechanisms.

Fake Roblox shader website

The Loader

The loader is being distributed as a Roblox shader installer (RobloxShaderCC Setup 1.0.0.exe). I placed it into an isolated Windows VM and executed it alongside Procmon. The most important finding was that it dropped another executable named RBXShader.exe and executed it. RBXShader.exe then installed Python and dropped a file named script.py and executed it.

Procmon output showing dropped a file
Procmon output showing file execution

The Payload

At first glance the script.py file did not contain any valid python source code. Instead it was largely non ASCII characters and data that could not be parsed or executed directly. But there were some indicators that there was a marshalled code object present. The loader must unmarshal the bytes and execute it in memory via exec, bypassing Pythons normal parsing and compilation process.

Marshalled python code object

There was a huge hex string in the unmarshalled data so I extracted and converted it to bytes then to UTF-8 and saw a few clear patterns. Roughly every 10 to 14 characters there was a Greek zeta symbol and each symbol in between was within the Unicode range. Analysis revealed that each of these characters had a fixed offset, 0x9F06F added to it. Adding each ASCII letter to the offset value would give me a value that appears in the huge hex blob. Using Python I deobfuscated the entire blob. After that it looked like python code except most of the syntax was gibberish. Shifting each letter forward in the alphabet by one fully restored the original source code. Now I could clearly see the malwares functionality.

Privilege Escalation

Or rather privilege impersonation. This malware attempts to impersonate lsass.exe (Local Security Subsystem Service) to get SYSTEM privileges temporarily. It does this by giving the current process SeDebugPrivilege and then opening a handle to the lsass process and duplicating its access token using the TokenImpersonation type with the SecurityImpersonation level. It uses the SYSTEM privileges to derive the v20 master key from Chrome to steal cookies and saved credentials in chromium based web browsers.

Privilege escalation impersonating lsass.exe

Persistence

This malware creates a batch file that launches the malicious python script and then creates a shortcut and drops it in the Startup folder. Upon execution The batch file checks itself for admin privileges using net session and if its not elevated it relaunches itself through Powershell with Start-Process -Verb RunAs which triggers a standard UAC prompt. If the users doesn’t elevate it, it exits and will retry next time the startup programs get executed.

Persistence in startup folder

In addition to traditional startup persistence, the malware implements client side persistence within Discord itself. It injects JavaScript code into index.js within the discord_desktop_core module of the Discord desktop client. This injected code hooks HTTP request functions and continuously re-extracts authentication tokens during sensitive account events, including new logins, backup code generation, email and password changes, and payment method updates. This technique allows the attacker to regain access to the victims Discord account even after credentials have been changed and can even block the user from viewing what other devices are logged into their account. It downloads the code that get injected from Github here.

Injecting code into Discords Javascript files