The first layer of an archive rarely tells the complete story. Some archives hide behind familiar formats, requiring deeper analysis to reveal their true shade. The examination of a sample named my new program called 2.rar (shown in Figure 1) uncovered one such case. Extracting this revealed a nested ZIP archive named TokenGrabberBuilder.zip. Inside it was a folder named “TokenGrabber Builder”, containing several suspicious files that warranted further analysis.

The analysis of this sample revealed two main components: a Python-based builder and an embedded infostealer payload. Rather than operating as a standalone stealer script, the builder follows a MaaS-style model. It allows operators to generate customized Windows executables using Nuitka or PyInstaller, with webhook configuration integrated into the build process.
1. Architectural Overview
The sample separates the malware-generation process from the final payload, allowing the same builder to be used to produce multiple customized binaries.
This design is consistent with a Malware-as-a-Service (MaaS) model, where a builder can be used to create customized samples for different operators.
This architecture provides several operational advantages for the threat actor:
- Affiliate scalability: Multiple operators can use the same builder to create and deploy their own customized malware samples.
- Reduced attribution: Each generated binary can contain a unique, encoded webhook, making it more difficult to correlate samples and identify shared infrastructure.
- Low barrier to entry: The interactive UI simplifies the build process, allowing operators with limited technical knowledge to generate deployable malware.
2. Builder Component Analysis
2.1 Dependency Auto-Installation
Automatic dependency resolution is performed at startup.

Required libraries are installed automatically, as shown in Figure 2, allowing execution on a clean Python environment without manual dependency setup. This reduces build failures caused by missing dependencies and simplifies deployment.
Detection Opportunity: Unexpected runtime invocation of pip.exe, particularly from non-development applications or processes, can serve as a behavioral indicator of this activity.
2.2 Webhook Configuration and Persistence
Webhook configuration is handled through a simple persistence mechanism:

Figure 3 illustrates, the configured webhook URL is stored in webhook.txt within the working directory. This allows the same endpoint to be reused across build sessions without requiring it to be entered again.
2.3 Webhook Encoding and Payload Injection
The most operationally significant function in the builder is the webhook injection mechanism, shown in Figure 4.

The webhook URL is XOR-encoded using the key 0x5A and then Base64-encoded before being inserted into the payload template as a string literal. At runtime, the payload’s _x() function reverses these operations to recover the original URL.
This results in three notable characteristics:
- The webhook URL is not stored as plaintext in the compiled binary.
- A different webhook produces a different encoded value and can result in a different binary hash.
- 1-1 signatures based directly on the webhook URL become less effective.
2.4 Compilation Backend Selection
The builder offers three compilation options, each producing a different type of executable.
Option 1: Nuitka

Nuitka compiles Python source code to C and then to native machine code. This produces a binary that:
- Contains no recoverable Python bytecode
- Has no .pyc files or Python-specific structures
- Defeats Python-specific decompilation tools (e.g., uncompyle6, decompile3)
- This can make detection based on Python-specific signatures more difficult.
The interface explicitly describes this option as:
“Nuitka — slower, stronger AV evasion”
This wording shows that the compilation method is presented as part of the tool’s evasion strategy.
Option 2: PyInstaller
PyInstaller packages the Python interpreter and application bytecode into a single executable.
- Can be unpacked using tools like pyinstxtractor
- Contains recoverable .pyc bytecode
The builder invokes PyInstaller as illustrated in Figure 6.

The builder generates a custom .spec file (_write_spec()) that explicitly excludes tkinter, matplotlib, numpy, and pandas to minimize binary size and reduce the detection surface.
Option 3: As a Raw Script
Saves stealer.py as a script without compiling it. This option is useful for manual deployment or when you want to customize the script further.
2.5 Python Interpreter Discovery
The application uses a Python interpreter discovery routine (_find_python()) to locate an available Python installation.
It checks several common locations, including:
- The PATH environment variable
- %LOCALAPPDATA%\Programs\Python\
- %USERPROFILE%\Python\
- Common system folders such as C:\, C:\Program Files, and C:\Program Files (x86)
- Version-specific folders, from Python 3.14 through Python 3.8
- Windows Registry entries under HKCU\SOFTWARE\Python\PythonCore and HKLM\SOFTWARE\Python\PythonCore
This approach allows the application to find Python installations regardless of where or how they were installed, making it more adaptable to different Windows environments.
3. Payload Component Analysis
The embedded payload (stored as the PAYLOAD string constant in the builder) is functionally equivalent to the Python-based infostealer, stealer.py, targeting Windows systems. The main capabilities include:
- Anti-Analysis Techniques
- Persistence Mechanisms
- Credential Harvesting
- Data Exfiltration
3.1. Initial Obfuscation and String Decryption
3.1.1 XOR-Based String Decoding
The malware’s first layer of defense against static analysis is a lightweight XOR cipher applied to all sensitive strings. Every hardcoded string — including API endpoints, registry paths, SQL queries, and system command strings — is stored as a Base64-encoded, XOR-encrypted blob.

The initial obfuscation process is depicted in Figure 7. The routine first decodes the Base64 data, then XORs each byte with the fixed key 0x5A. To avoid readability, it hides strings such as registry paths, API URLs, and SQL table names from basic signature-based detection.
Some examples of the decoded strings are shown below:
| Encoded Variable | Decoded Value | Purpose |
| `_H` | Discord/Telegram webhook URL | Exfiltration endpoint |
| `_E[“rk”]` | `Software\Microsoft\Windows\CurrentVersion\Run` | Persistence registry key |
| `_E[“pburl”]` | `https://pastebin.com/api/api_post.php` | Secondary exfil endpoint |
| `_E[“st”]` | `schtasks /create /tn` | Scheduled task persistence |
| `_E[“nw”]` | `netsh wlan show profiles` | Wi-Fi enumeration |
The _E dictionary stores the decoded strings, keeping sensitive values out of plaintext in the code.
3.1.2 Dynamic Import Resolution
Instead of loading sensitive libraries at startup, the malware loads all high-risk imports lazily through dedicated getter functions only when they are needed, as shown in Figure 8.

This pattern can make detection based on import activity more difficult. Libraries are only resolved when they are needed, reducing the observable activity during initial execution.
3.2. Anti-Analysis and Anti-VM Techniques
The _debug_check() function uses four checks to detect analysis environments and stop execution before the malware performs its main actions. Figure 9 provides an overview of these anti-analysis and anti-VM checks.

3.2.1 Debugger Detection via Windows API
The malware calls the Windows IsDebuggerPresent() API through ctypes to check whether a debugger is attached. This can detect common debugging tools such as x64dbg, WinDbg, and the PyCharm debugger.
3.2.2 Hypervisor and Sandbox Process Blacklisting
The malware enumerates all running processes using psutil and terminates if any process name matches known virtualization artifacts from VirtualBox, Xen, QEMU, and Parallels. This can help the malware avoid automated analysis in environments where these processes are present.
3.2.3 Disk Size Heuristic
The malware queries total disk capacity and exits if it is less than 50 GB. This is a well-known anti-sandbox heuristic, as automated analysis VMs are typically provisioned with minimal disk space (commonly 20–40 GB) to conserve storage resources.
3.2.4 Timing-Based Evasion
A variable sleep duration derived from the process ID introduces timing unpredictability. This technique may help the malware outlast sandbox time limits and reduce the chance of being observed during short analysis sessions.
3.3 Persistence Mechanisms
The malware establishes dual persistence to survive system reboots, using two independent mechanisms to maximize resilience.
3.3.1 Registry Run Key
The malware writes itself to HKCU\Software\Microsoft\Windows\CurrentVersion\Run under the deceptive key name WindowsUpdate, mimicking a legitimate Windows component to avoid casual inspection, as illustrated in Figure 10.

3.3.2 Scheduled Task Creation
A scheduled task is created with the trigger ONLOGON, ensuring execution at every user login. The creationflags=0x08000000, highlighted in Figure 11, value corresponds to CREATE_NO_WINDOW, suppressing any visible console window. Both stdout and stderr are redirected to DEVNULL to prevent any user-visible output.

3.4 Credential and Data Harvesting
3.4.1 Chromium-Based Browser Credential Extraction
The malware targets 17 Chromium-based browsers by checking their known User Data directories under %LOCALAPPDATA% and %APPDATA%. For each browser, it:
- Extracts the AES master key from Local State -> os_crypt.encrypted_key using Windows DPAPI (CryptUnprotectData).
- Copies locked database files to the system temp directory to bypass SQLite file locking.
- Decrypts stored credentials using Chrome’s encryption method (AES-256-GCM for newer versions) or falls back to the older DPAPI method, as shown in Figure 12.

The following table shows the main browser data targeted:
| Function | Database File | Data Extracted |
| `_f0()` | `Login Data` | URLs, usernames, passwords |
| `_f1()` | `History` | Browsing history with timestamps |
| `_f2()` | `Web Data` | Credit card numbers, names, expiry dates |
| `_f3()` | `Cookies` / `Network/Cookies` | Session cookies |
3.4.2 Firefox Data Discovery and Collection
The malware searches %APPDATA%\Mozilla\Firefox\Profiles for Firefox data. It reads “places.sqlite” for browsing history and cookies.sqlite for session cookies. Firefox cookies are stored in plaintext within SQLite, requiring no decryption.
3.4.3 Wi-Fi Password Harvesting

The malware uses the native Windows netsh utility to enumerate all saved Wi-Fi profiles and extract their cleartext passwords, as observed in Figure 13. The key=clear option reveals the stored password in plaintext without requiring decryption.
3.4.4 Discord Token Extraction
Discord token scanning/matching is performed through two complementary methods:
- LevelDB Scanning: The malware scans Discord’s LevelDB storage (Local Storage\leveldb) for encrypted token data and decrypts it using the application’s AES-GCM key.
- Regex Pattern Matching: A secondary regex pattern scans raw LevelDB files for older token formats.
Tokens are validated against the live Discord API (/api/v9/users/@me) before exfiltration, ensuring only active tokens are included in the stolen data package.
3.4.5 Roblox Session Cookie Theft
The malware specifically targets .ROBLOSECURITY cookies from both Chromium browsers and Firefox. These cookies can provide authenticated access to a victim’s Roblox account without needing the account password. The stolen cookies are checked against Roblox before being packaged.
3.5 Geolocation and System Reconnaissance

The malware also gathers basic information about the victim’s system and location, as highlighted in Figure 14. This includes:
- Public IP address
- Country, city, and ISP
- GPS coordinates (latitude and longitude)
- Timezone
- Windows username (%USERNAME%)
- Computer name (%COMPUTERNAME%)
This information is added to the ZIP archive along with the other stolen data. It can help the attacker understand where the victim is located and identify the affected computer.
3.6. Data Packaging and Exfiltration
3.6.1 In-Memory ZIP Archive Construction
All harvested data is assembled into a ZIP archive as evidenced in Figure 15, entirely in memory using Python’s BytesIO, avoiding any disk writes that could trigger file system monitoring:

The ZIP file is named StolenData_<USERNAME>.zip, allowing the attacker to immediately identify the victim upon receipt.
3.6.2 Webhook-Based Exfiltration
The ZIP archive is sent to an attacker-controlled webhook using an HTTP POST request, as depicted in Figure 16. The webhook address is decoded from _H.

4. Detection Opportunities
- Unexpected execution of pip.exe from non-development applications
- Creation of suspicious Run keys or scheduled tasks
- Use of netsh wlan show profiles
- Access to browser credential and cookie databases
- Suspicious HTTP POST requests to unknown webhook endpoints
- Creation of ZIP archives containing collected system data
5. Conclusion
This Python infostealer collects different types of sensitive information from the victim’s system and sends it to the attacker. It also uses techniques like in-memory execution, persistence, anti-VM checks, and obfuscation to make detection harder.
From a security point of view, this shows why monitoring suspicious behavior is important instead of relying only on file signatures. Detecting unusual data collection, persistence, and network activity can help identify this type of malware.
We should always be cautious and double-check the files that we download and install from any form of source. We at K7 Labs provide detection for all the latest threats. Users are advised to use a reliable security product such as “K7 Total Security” and keep it up-to-date to safeguard their devices.
Indicators of Compromise (IOCs)
| Hash | Detection Name |
| 610f0c65a3f8e88559f89ed90ea9ee5c | Password-Stealer ( 006dba241 ) |
| 429ed63ab3fbda8d22d0ac750ecfe8cc | Password-Stealer ( 006dba241 ) |
| 9ffe0e45c7a3f20e4481206c1c3b0854 | Trojan ( 006e632e1 ) |




