At CYFIRMA, we continuously monitor and investigate emerging cyber threats targeting both organizations and individuals. In this report, we analysed a GitHub-hosted malware campaign in which threat actors disguised malicious payloads as “Free VPN for PC” and “Minecraft Skin Changer”. These lures are designed to attract users seeking free software and trick them into executing a malware dropper named Launch.exe.
This campaign leverages process injection, DLL side-loading, and stealthy execution techniques to implant Lumma Stealer, a notorious information-stealing malware. Our technical analysis covers both static and dynamic behaviours, unpacks the obfuscation and anti-analysis tactics used, and provides actionable indicators of compromise (IOCs) and YARA rules to help defend against similar threats.
GitHub remains a popular platform for malware distribution, particularly for luring users into downloading and executing seemingly harmless tools. In this case, a GitHub user github[.]com/SAMAIOEC hosted multiple malware samples under names like “free-vpn-for-pc” and “minecraft-skin”, accompanied by detailed instructions and password-protected ZIP files to evade browser-based security scanning.
The core payload in this campaign is a Base64-encoded, obfuscated DLL that is dynamically dropped and loaded at runtime. It uses common evasion techniques and ultimately injects the Lumma Stealer into memory, leveraging legitimate Windows processes such as MSBuild.exe and aspnet_regiis.exe to bypass security controls.
This report presents a comprehensive technical analysis of the malware, maps its behaviour to MITRE ATT&CK techniques, and outlines recommendations to detect and prevent such threats.
File name | Launch.exe |
File size | 1.52MB |
MD5 | bbc7fc957d4fff6a55bd004a3d124dda |
SHA256 | acbaa6041286f9e3c815cd1712771a490530f52c90ce64da20f28cfa0955a5ca |
Target technology | Windows |
The malware contains nonsensical and unrelated assembly metadata that does not correspond to any legitimate VPN software or known organization. This strongly suggests that the threat actor likely used a malware builder to auto-generate random assembly info to obfuscate attribution and avoid basic heuristics.
The malware leverages P/Invoke to import several Windows API functions from kernel32.dll, including LoadLibrary, GetProcAddress, FreeLibrary, CloseHandle, and WaitForSingleObject. These functions are commonly used to perform dynamic DLL loading, resolve function addresses at runtime, and manage handles and execution flow.
Entry Point of “Launch.exe”
The entry point of this malware is the AssemblyBoard.Main() method. It initiates the execution chain by loading a DLL that is embedded within the malware in Base64-encoded form. This DLL is de-obfuscated, written to disk, and then dynamically loaded into memory for further malicious execution.
The malware uses the peBytes function to decode a Base64-encoded payload retrieved from GetBase64String().
To evade detection, the Base64 data is hidden after 1177 characters of meaningless French text.
Stage-1: Decryption of base64 decoded byte via SinCosMath():
Stage-2: DLL Dropping, Stealth Mechanisms, and Evasion Techniques
After decoding the Base64-encoded bytes, the DLL is written to disk using File.WriteAllBytes() within the GetLocalError() function, which takes two parameters: the file path and the byte array. The file path is derived from the v_appdata variable in the TotalInc class, which uses Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) to point to the AppData directory. The DLL filename is initially set as msvcp110.dqq and then renamed to msvcp110.dll by replacing the character ‘q’ with ‘l’.
Immediately after dropping, the file is hidden using File.SetAttributes.Hidden via the GetMarked() function to make it invisible to users and file explorers.
Stage-3: Dynamic Loading of the Dropped DLL
The dropped DLL (msvcp110.dll) is dynamically loaded using LoadLibrary(). The malware resolves the GetGameData export function via GetProcAddress() and executes it using Marshal.GetDelegateForFunctionPointer. Finally, the program calls WaitForSingleObject() with an infinite timeout to maintain persistence or prevent premature unloading, and then uses CloseHandle() for resource cleanup.
The extracted DLL exhibits an entropy value greater than 7, indicating that it is likely packed or obfuscated. Additionally, it is a 32-bit binary written in C.
The DLL exports a function named GetGameData(), which is located at the address 0x01000DDD0.
Anti-Debug Techniques
The DLL explicitly checks for analysis environments using IsDebuggerPresent() to detect active debugging. If a debugger is found, the process may terminate prematurely to hinder reverse engineering.
Obfuscation Technique
Additionally, the DLL employs unnecessary control flow, including excessive while (true) loops and meaningless long strings, which are used to obstruct readability and frustrate automated analysis tools.
Memory Allocation:
The process begins with the use of VirtualAlloc(), which allocates memory in the current process space—likely as a staging area for the unpacked payload.
Once memory is allocated, NtWriteVirtualMemory() is invoked to write the decrypted or unpacked payload into the allocated region. To prepare for execution, the malware uses NtGetContextThread() to retrieve the context of a suspended thread, ensuring precise control over where execution resumes.
Process Injection:
The malware references legitimate Windows binaries like MSBuild.exe and aspnet_regiis.exe, indicating process injection into these trusted executables.
API calls similar to CreateProcessW() and NtCreateThreadEx() are used to spawn or hijack these processes for payload execution, a common technique to bypass security products and gain stealth.
Upon execution the malware “Launch.exe” dropped a msvcp110.dll in user AppData directory [C:\Users\<username>\AppData\Roaming\ msvcp110.dll]
While debugging the malware, we observed that the GetGameData function from msvcp110.dll was successfully loaded. However, the process was abruptly terminated shortly after, preventing further dynamic analysis. During this execution window, the malware also attempted to establish a connection to explorationmsn[.]store, which is likely associated with its command and control (C2) infrastructure.
Upon further investigation of the domain explorationmsn[.]store, multiple indicators were identified that align with known infrastructure patterns associated with the Lumma Stealer family. These include similarities in domain naming conventions, hosting characteristics, and behavioural footprints observed during past campaigns.
The threat actor hosted the malware on GitHub at [github[.]com/SAMAIOEC/free-vpn-for-pc], disguising it as a legitimate “Free VPN for PC” tool to deceive users into executing the payload. Additionally, a similar sample titled “Minecraft Skin” was uploaded to the same repository, containing the same malware with only the executable filename altered. No further identifiable information or contact details related to the threat actor were discovered.
The analysis of the “Free-VPN-For-PC” sample revealed that, behind its seemingly legitimate facade, it functions as a sophisticated malware dropper designed to implant the Lumma Stealer. Disguised as a helpful tool, the dropper uses multiple layers of obfuscation, in-memory execution, and process injection to evade detection. The same malware was also repackaged under the name “Minecraft Skin”, indicating a broader social engineering tactic targeting different user interests. Hosted on GitHub, the malware abuses the trust associated with the platform. Despite the insights gained from static and dynamic analysis, no other contact information or identifiable links to the threat actor were found. This highlights the importance of proactive threat hunting and monitoring of open-source platforms.
S. No | Indicators | type | context |
1. | acbaa6041286f9e3c815cd1712771a490530f52c90ce64da20f28cfa0955a5ca | EXE | Launch.exe |
2 | 15b644b42edce646e8ba69a677edcb09ec752e6e7920fd982979c714aece3925 | DLL | msvcp110.dll |
3 | Explorationmsn[.]store | domain | C2 |
4. | Snailyeductyi[.]sbs | domain | C2 |
5. | Ferrycheatyk[.]sbs | domain | C2 |
6. | Deepymouthi[.]sbs | domain | C2 |
7. | Wrigglesight[.]sbs | domain | C2 |
8. | Captaitwik[.]sbs | domain | C2 |
9. | Sidercotay[.]sbs | domain | C2 |
10. | Heroicmint[.]sbs | domain | C2 |
11. | monstourtu[.]sbs | domain | C2 |
Tactic | ID | Technique Name |
Initial Access | T1189 | Drive-by Compromise |
Execution | T1059 | Command and Scripting Interpreter |
Persistence | T1574.002 | DLL Side-Loading |
Privilege Escalation | T1574.002 | DLL Side-Loading |
Defense Evasion | T1036 | Masquerading |
T1497 | Virtualization/Sandbox Evasion | |
T1140 | De-obfuscate/Decode Files or Information | |
T1027 | Obfuscated Files or Information | |
T1574.002 | DLL Side-Loading | |
Discovery | T1124 | System Time Discovery |
T1497 | Virtualization/Sandbox Evasion | |
T1010 | Application Window Discovery | |
T1018 | Remote System Discovery | |
T1083 | File and Directory Discovery | |
T1082 | System Information Discovery | |
Collection | T1560 | Archive Collected Data |
Command and Control | T1573 | Encrypted Channel |
T1105 | Ingress Tool Transfer | |
T1095 | Non-Application Layer Protocol | |
T1071 | Application Layer Protocol |
rule Free_VPN_Lumma_Dropper_Detection
{
meta:
description = “Detects Lumma Stealer dropper disguised as VPN or Minecraft tool based on domains, and hashes”
author = “Cyfirma Research”
date = “2025-07-08”
mal_type = “Stealer”
strings:
// Malicious files
$sha256_launcher = “acbaa6041286f9e3c815cd1712771a490530f52c90ce64da20f28cfa0955a5ca”
$sha256_dll = “15b644b42edce646e8ba69a677edcb09ec752e6e7920fd982979c714aece3925”
// Known C2 domains
$dom1 = “explorationmsn.store”
$dom2 = “snailyeductyi.sbs”
$dom3 = “ferrycheatyk.sbs”
$dom4 = “deepymouthi.sbs”
$dom5 = “wrigglesight.sbs”
$dom6 = “captaitwik.sbs”
$dom7 = “sidercotay.sbs”
$dom8 = “heroicmint.sbs”
$dom9 = “monstourtu.sbs”
condition:
any of ($dom*) or $sha256_launcher or $sha256_dll
}
Block Known C2 Domains:
Proactively block all identified C2 domains (e.g., explorationmsn.store, snailyeductyi.sbs, etc.) at the firewall, DNS, and proxy levels to prevent malware from communicating with its server.
Restrict Executable Downloads from GitHub:
Implement web filtering policies to restrict the download of executables or password-protected ZIP files from platforms like GitHub and unknown sources.
Monitor for Suspicious DLL Names:
Flag creation or execution of suspicious DLLs in user directories, such as AppData\Roaming\msvcp110.dll, especially when dropped by unknown executables.
Detect Use of Low-level Windows APIs:
Monitor and alert on uncommon or high-entropy DLLs being loaded via LoadLibrary, GetProcAddress, and memory APIs like VirtualAlloc, NtWriteVirtualMemory, or NtCreateThreadEx.
Apply YARA Rules at Endpoint and Email Gateways:
Use the provided YARA rules in endpoint security tools and file scanning engines to detect embedded indicators in files.
Restrict Execution from User Space (AppData):
Enforce rules via Group Policy or EDR to block execution of any binaries from folders like %AppData%.
User Awareness Campaigns:
Educate employees and users about the risks of downloading “free tools” like VPNs or game mods from GitHub or unverified forums. Emphasize the use of trusted sources.
Implement Behaviour-Based Detection:
Use EDR solutions that can detect behavioural patterns like DLL side-loading, process injection into MSBuild.exe, and persistence via WaitForSingleObject().
Threat Hunting for Indicators of Compromise (IOCs):
Hunt across endpoints and network logs for the dropped file hashes, suspicious filenames, and domain indicators to identify possible infections.