Case Study
Pure Logs Stealer first appeared on hacking forums at the end of October 2022. The stealer is developed by a malware developer going under the alias PureCoder.
The malware developer is also behind in developing the products shown above, such as Pure Miner, Pure Crypter, Pure hVNC, Blue Loader, and other products, including HWID reset, Discord DM Worm, and Pure Clipper.
The malware developer periodically pushes updates to their products. The
The view of the File Grabber panel:
The view of the File Builder panel:
The stealer can be purchased automatically via the Telegram Bot without interacting directly with the malware developer/seller.
Before diving into the technical part, I want to thank cod3nym for helping with the crypter and getting additional stealer samples.
Technical Analysis
Pure Logs Stealer comes crypted using their own Pure Crypter product. The stealer allegedly has antiVM, self-delete, persistence, file grabber, and file loader features, but the features currently do not work as expected within the stealer. The self-delete feature removes the stealer payload via PowerShell command **powershell Start-Sleep -Seconds 10; Remove-Item -Path ’“
The persistence is added via Registry Run Keys (T1547.001).
I will not go through the layers of unpacking and just go straight to the core payload, which is our Pure Logs stealer. The stealer is 64-bit and is slightly over 2MB in size. It is topped with Eazfuscator.NET, which obviously is a .NET obfuscator, as shown in the image below.
The stealer creates the folder under %TEMP%\Costura\1485B29524EF63EB83DF771D39CCA767\64** and drops the file **sqlite.interop.dll that is one of the dependencies for the stealer, likely facilitating access to the browser data.
The Main method within the PlgCore class loads the C2 address, and build ID (the default build ID is Default) as one of the arguments from the crypter, the other one is the value that will be used along with MD5 to generate the 3DES key for data encryption, but we will through that later in the article.
The stealer gets the host information, including the version of the OS, via WMI, specifically SELECT * FROM win32_operatingsystem statement. If neither 32-bit nor 64-bit OS systems cannot be determined, the OS is marked as “unknown”, the same goes for the username, machine name, antivirus products, the working directory (the path from where the stealer was launched), etc., enumeration.
It gets BIOS information via Win32_BaseBoard. ProcessorId and CPU information via Win32_Processor. The ProcessorId and CPU information are then used to generate an MD5 hash, which will be the HWID marker in the stealer’s log file for the infected machine.
The username and the HWID are separated by an underscore and displayed in the panel in the format “username_hwid”, as shown below.
Next, the stealer splits at the pipe the gathered information via SELECT * FROM win32_operatingsystem , specifically under the value Name, and likely grab only the Windows Version value to parse it to the stealer’s log file.
The query for antivirus products is performed via Select * from AntivirusProduct statement.
The method below captures a screenshot of the entire primary display screen of the infected host and converts it into a JPEG image format, returning the image as a byte array.
The method below gets the content of the clipboard.
The GPU information is accessed via Win32_VideoController under the Name value. The RAM value is accessed via Win32_ComputerSystem under the TotalPhysicalMemory value.
The method below is responsible for getting the screen size. It gets the dimensions of the display screen of the computer using Screen.GetBounds(Point.Empty)
The list of the cryptowallet extensions to be enumerated and collected by the stealer:
List of browser extensions to be enumerated and collected:
Some of the data collected from Chromium-based browsers and the mention of encrypted_mnemonic is shown in the image below. encrypted_mnemonic most likely stores a securely encrypted version of a mnemonic seed phrase, which is essential for accessing or recovering cryptowallets.
For Gecko-based applications such as:
- Mozilla\Firefox
- Waterfox
- K-Meleon
- Thunderbird
- Comodo\IceDragon
- 8pecxstudios\Cyberfox
- NETGATE Technologies\BlackHaw
- Moonchild Productions\Pale Moon
The stealer uses specific queries, for example, “SELECT * FROM moz_bookmarks” , the query that interacts with the SQLite database used by Mozilla Firefox for storing user bookmarks. For Gecko-based applications, the stealer accesses file logins.json, which Mozilla Firefox uses to store saved login information, including usernames and passwords for websites, as shown below.
The method below is responsible for extracting, processing, and decrypting credential information from specific registry paths related to Outlook profiles. The regex patterns are used to validate server names and email addresses.
The following Outlook registry paths are enumerated:
- Software\Microsoft\Office\15.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676
- Software\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676
- Software\Microsoft\Office\17.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676
- Software\Microsoft\Office\18.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676
- Software\Microsoft\Office\19.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676
- Software\Microsoft\Office\20.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676
- Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676
- Software\Microsoft\Windows Messaging Subsystem\Profiles\9375CFF0413111d3B88A00104B2A6676
The snippet below is the method responsible for grabbing Discord data. The method iterates through directories associated with different Discord builds (discord, discordcanary, discordptb).
- It searches for directories containing local storage data (specifically in the leveldb folder).
- The method calls \uE002 to extract certain data from the local storage files (ldb, log, sqlite)
- If any data is found, it attempts to make web requests to Discord API endpoints using these tokens. The regular expressions in the image below is created to match patterns that resemble Discord authentication tokens.
Funny fact: all Discord tokens start with dqw4w9wgxcq, let’s not get rickrolled …
Interestingly enough, Pure Logs Stealer also collects Windows product key and stores it under a separate log file named App_Windows Serial Key.txt. It accesses the key via the registry SOFTWARE\Microsoft\Windows NT\CurrentVersion under the value DigitalProductId.
I renamed each method so it is easy to visualize what type of data the stealer collects:
As you can see from the above image, the most current stealer version is v3.1.3, and some additional sensitive data is collected from the following applications:
- FileZilla
- WinSCP (collects username, and passwords)
- Foxmail
- Telegram
- Pidgin
- Signal
- InternetDownloadManager (IDM) (collects email addresses, first name, last name and serial number)
- OBS Studio (collects profiles data)
- Ngrok (collects ngrok.yml)
- OpenVPN
- ProtonVPN
I will leave it to you to explore what files it collects from some of the applications mentioned above.
The example of the logs folder is shown below:
It is worth noting that after successfully executing, the stealer creates a registry subkey under HKU:\Software with the HWID value.
C2 Communication
The stealer uses a Socket for TCP/IP communication. It sets up a TCP/IP socket and attempts to connect to a server, and if the connection is successful, it begins receiving data. It continuously tries to connect, with a 5-second delay between attempts, in case of initial failure. The default port for communication is 7702, but that can be changed.
Before sending the actual data to C2, it sends the data size as shown below.
The exfiltrated data is sent at once instead of in separate parts, which impacts the successful infection. The attacker will not receive any data if the communication is interrupted at a certain point. It is worth mentioning that stealers such as Raccoon Stealer send the data in parts to the C2 server, so in case of network interruption, at least some data is exfiltrated.
As it was briefly mentioned before, Pure Logs Stealer uses 3DES for data encryption that is sent over to C2. The 3DES key is derived from the value supplied as one of the parameters along with the C2 IP address in the stealer payload.
The Python implementation to decrypt the traffic:
Conclusion
Despite the obfuscation and layers of unpacking, Pure Logs Stealer is similar to other .NET stealers and does not possess any special functionalities. The effectiveness of its file grabber and file loader features remains to be questioned.
Detection Rules
You can access the Yara detection rule for Pure Logs Stealer here.
You can access the Sigma detection rule for Pure Logs Stealer here.
Indicators of Compromise
Name | Indicators |
---|---|
Stealer Payload | 2b84f504b2b8389d28f2a8179a8369fc511391e7331f852aaf3a6a2f26a79ee4 |
Stealer Payload | 8543ea15813ea170dd0538d7cd629f451ceb7e18b07c4db1cdbce5e089b227d4 |
Reference
https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/sockets/sockets-overview
https://github.com/RussianPanda95/Yara-Rules/blob/main/Pure%20Logs%20Stealer/purelogs_stealer.yar