Malware Analysis - Pony
This blog post is available in french here.
Sumary
- Introduction
- 1) Unpack
- A) Stage 1
- B) Stage 2
- C) Stage 3
- D) Stage 4 (custom loader)
- I) Avast snxhk.dll
- II) Configuration file & payload extraction
- III) Downloader
- IV) Anti-VM & Anti-analysis
- V) Process hollowing
- 2) Pony payload
- A) History
- B) Anti-Disassembly (rogue-byte)
- C) Heuristic evasion
- D) Privilege escalation
- E) Environment awareness
- F) Cryptocurrency stealer
- G) Stealer capabilities
- I) FTP
- II) Browsers
- III) Mails
- IV) RDP
- V) Certificates
- H) Information gathering
- I) Data exfiltration
- IOCs
- Hashs
- ATT&CK Techniques
- Yara Rules
Introduction
The analyzed sample have the following hash:
b3b2e248d1ba2beb966faf9ed100d867
The file can be downloaded on VirusBay.
This sample is quite interesting because of it high obfuscation level and it multi-stage behavior that make it hard to reach the core of the malware. The first part of this analysis is going to be focused on the unpack of the Pony sample.
1) Unpack
A) Stage 1
The first stage of the malware is a .net executable. Unless my previous analysis of the RogueRobin malware, which is also written in .net, this one is heavily obfuscated. At this stage, the code is almost unintelligible:
The fact that all the executable’s methods name are called by an unprintable character, that the code is unreadable, the very few system calls and the presence of more unicode character within the binary code show that this file is indeed packed or obfuscated:
Luckily for us, there is some automated tools that can help in this situation. One of them is “de4dot”. This tool is able to find the obfuscation technique used on this sample (DeepSea 4.1), and to reestablish the original code:
B) Stage 2
The second stage of the malware is still obfuscated. The weird unicode characters are not here anymore, but the code is still unreadable. A lot of the functions seems to have no other purposes than making it artificially harder for us to read what’s going on:
Once more, de4dot make it handy by being able to find the protection mechanism involved (.Net reactor), and to bypass it:
C) Stage 3
This time, no more automated tools. The third stage of the malware look like a custom loader that aim to make the analysis harder, while laying the groundwork for the next stage.
The high entropy of the file point to the fact that some dynamic memory decryption techniques will be used:
The code’s content is still weird, since there is not that much system call being made, and that a lot of obfuscated strings are present:
By recursively digging from the Main() method, a memory injection function can be spot (Class3 @02000005):
In order to load the next stage of the malware in memory, a call to “Assembly.Load()” is done. The Assembly.Load() method take one single argument, and this argument is a pointer to the memory region where the code to inject is. Intercepting this argument should be easy, by placing a breakpoint on the function.
Regardless of all the decryption functions being called before, we can now dynamically extract the plaintext version of the next stage of the malware:
As expected, the “object_0” argument is an array that look like an executable file (The two first bytes ‘0x4D 0x5A’ match the hex magic byte “MZ”):
A dump of this array can be made in order to get a copy of the stage 4 of this Pony malware.
D) Stage 4 (custom loader)
This new stage does not have any proper signature. I assume that it is a loader++, since it execute some injection functions, but also some anti-analysis tricks before dropping the main payload in memory.
This executable is still a .net file, but in a DLL format. The main method of the DLL is located at @06000033, under the randomly generated name “flfvdNhm/rfeqkv()”.
I) Avast snxhk.dll
Before doing any malicious operation, the loader is going to check if the Avast antivirus is installed. To do that, the snxhk.dll external DLL is loaded. This DLL is needed by the Avast sandbox, in order to make some hook on the scanned processes. If the malware successfully load this DLL, it means that Avast (or AVG, those two antivirus share the same library) is installed on the infected computer.
In this case, the Pony loader will suspend it activities until Avast is uninstalled:
The fact that this check is only targeting the Avast AV make it really weird, especially knowing that this anti-AV function is not working very well. I’ve replicated this specific malware function, and it does not seems to run properly:
II) Configuration file & payload extraction
Next, the loader is going to follow a configuration file. This configuration file came from a bitmap picture, and this picture is in the resource segment of the previous stage.
The picture is deciphered in memory, bytes by bytes, through several functions (‘Decrypt()’ and ‘Pack().Deserialize()’):
The plaintext version of the configuration file involve 27 distinct fields, allowing to control the behavior of the loader. The following table resume the configuration file’s content:
III) Downloader
Although this loader is especially designed for the pony malware, it may download additional components, if the configuration flag “flag8” is set to “True”.
The address where to download stuff is passed to the webClient.DownloadData() function. Then, the downloaded component is deciphered with the same method that the one being used in the previous stage:
The downloaded executable is then launched:
By adding another malware to the Pony stealer, the operator behind the malicious campaign can maximizing it profits.
IV) Anti-VM & Anti-analysis
If the configuration file allow it, the loader will try to gather some information about the environment in order to detect the use of a virtual machine.
The anti-VM function is based on some WMI requests. Those requests target the video controller driver of the computer. Each virtual machine have it own video driver related to it virtualization brand. For instance, the VMware video driver is installed with the VMware tools, in order to quickly change the resolution and the format of the VM’s screen.
The malware is going to try to extract some information about those drivers on the infected computer, then check it against some well-known VM driver name.
If one of the virtualization related drivers is detected, the loader end it activities:
But once again, this function does not work with my setup. It looks like that my VMware version is too recent for the malware, and that the strings comparison cannot succeed (“VMware svga ii” vs “VMware SVGA 3D”):
Lastly, the loader is going to check is the “sandboxierpcss” process, related to sandboxie (a software sandbox), is present:
V) Process hollowing
To extract the Pony core payload, the loader will have to use a well-known injection technique called process hollowing.
This technique will replace the content of a legitimate process by some malicious code.
The process hollowing function is here called “NewRP.HandleRun()”. This function take four arguments: the targeted process (path), the command to execute when the newly legit process is created (cmd) and a pointer to the malicious code to inject (data):
The first step of a process hollowing injection is to spawn the targeted process in which the injection is going to occur. The function “ProcessInformation()” will do that.
In order to continue the injections steps, that process must be created in a suspended state. It can be achieved by setting the CREATE_SUSPENDED flag to 0x00000004:
With our configuration, the targeted process will be “RegASM.exe”.
Once launch in a suspended state, the legitimate content of the RegASM process need to be wipe-out with a syscall to NtUnmapViewOfSection. This will make room for our malicious code (the next stage):
Before injecting the code into our process, a memory allocation need to be performed. With a call to the VirtualAllocEx function, a memory space that have the exact same length that our malicious code (argument “data”) is initialized with zeros:
Finally, the injection can be done under our empty RegASM process with the help of the WriteProcessMemory function:
In order to resume our suspended process, and start the next stage of the malware, a call is made to ResumeThread:
This loader is able to replace the content of a live process that looks totally legit. If we want to access the Pony malware payload, we need to dump the injected code.
This can be done with a few breakpoints on the WriteProcessMemory function, or by monitoring the RegASM process until the ResumeThread call.
With the first technique, we have to intercept the lpBuffer argument of the WriteProcessMemory function:
It will give us the memory location where the code is injected. Alternately, it is also possible to search for the magic bytes “MZ” in the hole memory space of the RegASM process before the call to ResumeThread.
Both of those techniques will lead us to the next stage of the malware:
This stage may be packed with UPX, but that’s not a challenge for us.
2) Pony payload
A ) History
The real analysis of the Pony malware start here. After unpacking the UPX sample that we got during the previous memory injection, the Pony payload is finally ours.
Pony is fully written in ASM, and have emerged for the first time in 2011. This malware belongs to the “stealer” categories. Pony strength lies in the fact that it does only one thing, and it does it with much care as possible, without superficial things everywhere. The fact that this piece of code was written in assembly make it a mature malware, fully aware of it capabilities. Pony is often bind to others specific malware (RAT or Miners), but is still a powerful stealer alone.
Since the beginning, Pony is a successful piece of code, and take part to major malicious campaigns.
Lately, the stealer is focusing on cryptocurrency theft, and do it well.
Even today, Pony is still a massively used malware:
B) Anti-disassembly (rogue-bytes)
Pony have two main anti-analysis techniques. The first one seems to be what look like the “rogue-byte“ technique. It is an anti-disassembly technique that aim to confuse the disassembler by giving it hard to understand instructions.
With those multiple rogue-byte at every key function of the malware, IDA Pro is freaking out, and some functions are omitted:
In order to transform this particular code in a unique function, the displays instructions need to be patched. The 0xFE rogue-byte need to be turned into a NOP, as well as the previous “retn” instruction. IDA believes that the return instruction indicate the end of the function. As a result, every other instruction after the “retn” will not be displayed as it should be.
Once the code patched, we can start our analysis and properly read everything:
C) Heuristic evasion
The second anti-analysis technique used by this sample aim to circumvent automated heuristic analysis.
In order to perform a heuristic scan, the suspect program need to be run under a sandbox for a limited amount of time, since the user is waiting for it. The waiting time cannot be too long, otherwise the user is not going to use the heuristic solution anymore. Pony abuse this concept, and make it own thread do some pointless calculation during a large amount of time. As a result, heuristics mechanisms are easily fooled by this delay in the execution flow:
D) Privilege escalation
After retrieving some dynamically build API, Pony will try to do some privilege escalation:
The malware will try to spoof the local administrator account with the “SE IMPERSONATE NAME” parameter.
https://blogs.msdn.microsoft.com/mithuns/2007/07/03/seimpersonateprivilege/
Under normal circumstances, this parameter is transmitted to the local administrator group and to the local services accounts. If the Windows account from where the malware was launched have this parameter activates, Pony will gain a free administrator account on the system.
The used method is the following:
- First thing first, the malware check if it already have some administrator privileges. If it’s not the case, the impersonation technique start:
-
The session identifier is gain with the WTSGetActiveConsoleSessionId function.
-
A list of all the live process is gather with a call to CreateToolhelp32Snapshot. Then, the “explorer.exe” process is searched among the process list (with Process32First and Process32Next). “Explorer.exe” is a great target process, since it must have SYSTEM privilege.
-
The target process running under a SYSTEM account is opened with OpenProcess.
-
The security token is gain with OpenProcessToken.
-
The usurpation is made from the explorer.exe process, with the ImpersonateLoggedOnUser function.
-
Last, in order to check if the impersonation worked, a handle to the “HKEY_CURRENT_USER” key is created. This value, condensed into the “HKCU” acronym, contains the base address of the actual user on the registry.
Here is the corresponding pseudo-code:
E) Environment awareness
During this first recon-like stage, Pony will start by getting a list of the installed process, along with the computer’s name of the infected system. For this first step, the GetUsernameA function is used:
In order to deal with the installed softwares, the malware crawl the registry, more precisely under “SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall“:
Two keys are searched. The first one, “UninstallString”, contain the uninstaller path of some installed softwares:
The second key, “DisplayName”, contain the official name of the installed softwares:
Based on those array, pony will try to determine if an attractive app is installed, in order to later steal it content or extract some passwords.
F) Cryptocurrency stealer
Pony mainly target four applications types: FTP session managers, browsers, mail clients and everything related to cryptocurrency.
In this part, we’ll focus on the cryptocurrency theft.
This specific sample of Pony is able to steal wallet datas from 36 cryptocurrency wallets:
The stealing process is the same for every available cryptocurrency module:
- First, the name of the cryptocurrency default folder and the related wallet name are pushed. For instance, in the case of the Bitcoin function, it’s the “\Bitcoin” and “wallet.dat” strings:
- The potential paths where to look for the “wallet.dat” file are created, based on the “Shell Folder” registry key. This key contain user related default paths:
Pony will only search in the “Desktop”, “Documents” and “ProgramData” folders. A loop will be initialize in each of those folder, that aim to recursively inspect every sub-folders and files:
- If the wallet file is found, it content is saved in memory (MapViewOfFile function):
- At the end, the wallets datas are stored in a memory stream, with other passwords and cryptocurrency keys, before being extracted to the C2 server.
G) Stealer capabilities
Apart from e-wallets, Pony will try to steal valuable datas such as saved user passwords, login credentials and potentials servers IP address and password. This specific sample target 96 softwares, so we will only detailed the stealing procedure on each of the software families.
I) FTP
When it come to FTP clients, Pony can handle 62 of them.
The complete list of supported FTP software is the following:
Depending on the targeted software, the process of extracting saved passwords and saved FTP server’s IP is not always the same. Sometime the theft is done through some registry keys and sometime it’s from reading and decrypting some specific local files.
For instance, here is the stealing function for the poplar FTP manager Filezilla. First, the malware get the installation path where the software is installed:
Then, some specific valuable files for this FTP manager are stored in memory:
The “sitemanager.xml” file contains plaintext saved FTP sessions, such as the FTP server’s address, connection port, cipher method, username, password and comments. ”recentservers.xml” contains the same informations, but for the quick connect FileZilla option. Finally, “filezilla.xml” is an exported file that contains a summary of the two previous file.
That’s how easy it is to steal FTP passwords from one of the most used Windows FTP sessions manager.
When the FTP informations are stored in the registry, as with the WinSCP software, Pony will use a the following extraction method:
- The specific registry key where the software store some datas is simply pushed:
And the content of this key is then parsed for interesting values:
Pony will use those two simple technique, with sometime minor change, to extract datas from those 62 FTP related software. Each extracted file or registry key is store in a memory stream, for a later extraction.
II) Browsers
Browser usually contains a lot of personal valuable informations when a user choose to save his credentials into it. That’s naturally why Pony also target a list of 15 differents browser:
Apart from the fact that i’ve never heard about the third of them, browsers usually stored sensitive datas into regular local files (but not in plaintext this time, as for the FTP softwares).
With Firefox, credentials are stored in an encrypted format into a sqlite or text format file. So the malware need to dynamically locate those files, and get their content in memory:
That’s basically it. For the Chrome browser, the process is the same, but the files are called “Web Data” and “Login Data”:
Even if those file are clearly ciphered, they are sent to the C2 server as is, for a latter decryption on the attacker side.
III) Mails
Several mail applications are also targeted by Pony:
Pony will try to gather the user email address along with the corresponding password, by abusing some registry strings and some account related “.ini” file. The techniques are the same that what’s being used for the FTP and browser section.
IV) RDP
The final attempt to gather sensitive informations by the malware is to harvest RDP sessions. RDP sessions credentials can be saved in a “.rdp” file that contain the IP address, username, password and the domain being used to access a specific distant system.
Pony will check in the default location (“desktop”, “my documents” and “ProgramData”) for any “.rdp” file:
V) Certificates
Before leaving, Pony will try to take some certificates and some private keys stored on the infected computer. The malware start by listing all of the available certificates:
Each one of the retrieved objects nature is check, based on the “2.5.29.37” OID that identify a proper public certificate:
Then, the private key of that certificate is extracted and stored in memory for a future use:
H) Information gathering
Now that the malware have a memory stream that potentially contain several credentials, it’s time to exfiltrate everything. But before, Pony need to gather some informations about the infected computer.
First, a small anti-analysis technique is used:
The PEB (Process Environment Block) contains several flags related to the running environment, but it also contain the “BeingDebugged” key. This key indicate that a debugger may be attached to the running application. In order to bypass this, we can bypass this section of code, or manually change the flag’s value to 0.
The Windows OS version is determined with the GetVersionExA function:
Then, the architecture of the infected system is found with the dynamically resolved “IsWow64Process” API:
The user’s nationality is guessed through the “GetLocaleInfoA” function, with the LCType argument set to 0x1001 and 0x1004:
This will allow to get the user language and his country:
Every malware need to properly identify each victim. In order to do that, Pony will rely on an already existing identifier created by the WinRAR software:
If this registry key is not found because of the absence of WinRAR on the infected computer, a generic ID is given with the “CoCreateGuid” function:
This generic ID is formatted to the following format-string:
Finally, a last call is made to the “GetNativeSystemInfo” function, in order to get the processor type:
IOCs
Hashs
- Pony stage 1 (DeepSea packed): B3B2E248D1BA2BEB966FAF9ED100D867
- Pony stage 2 (NetReactor packed): 244F4A0785E2A43E0F14090905B29017
- Pony stage 3 (memory loader): 9C6F828A43D1DDCB8B123B8E950D1705
- Pony stage 4 (Loader++ DLL): 3804E555F711E1951F62D1EFF9AA8A6A
- Pony stage 5 (UPX packed): AD6D84336845F23FB0C0D9715AFDA446
- Pony stage 6 (payload sample 1): 73B626C28CD54284F3E2BB14D652653A
- Pony stage 6 (payload sample 2): 239AA52DBA8F33C965916D1003F600CD
- Snoop (packed): 17F51AB722963D73B5DCD050D06E6D40
- Snoop (clean): 80B750AACBC03F78BDACFFE847631E44
- Pony cleanup script: 3880EEB1C736D853EB13B44898B718AB
ATT&CK Techniques
- Spearphishing Link (T1192)
- Startup Folder (T1060)
- Access Token Manipulation (T1134)
- Process Injection (T1055)
- Deobfuscate (T1140)
- File Deletion (T1107)
- Obfuscated Files (T1027)
- Process Hollowing (T1093)
- Software Packing (T1045)
- Virtualization/Sandbox Evasion (T1497)
- Brute Force (T1110)
- Credential Dumping (T1003)
- Credential in Files (T1081)
- Credential in Registry (T1214)
- Account Discovery (T1087)
- File and Directory Discovery (T1083)
- Query Registry (T1012)
- Data from Local System (T1005)
- Custom Command and Control Protocol (T1094)
- Data Encoding (T1132)
- Data Compressed (T1002)
- Automated Exfiltration (T1020)
YARA rules
Pony DLL loader:
rule pony_dll_loader { meta: author = “HomardBoy” description = “Pony stage 3 loader (.net dll)” strings: $evasion = “SELECT Description FROM Win32_VideoController” $snoop = “snoop.exe” $class = “mydllclass” $avast = “snxhk.dll” condition: uint16(0) == 0x5A4D and uint8(uint32(0x3c)+23) == 0x21 and any of them }
Pony Payload:
rule pony_stealer { meta: author = “HomardBoy” description = “Pony stealer” strings: $rogue_byte_func = { 33 D0 33 C2 33 D0 68 ?? ?? ?? 00 90 F8 90 72 02 90 C3 FE} $user_agent = “Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/5.0)” $str = “STATUS-IMPORT-OK” $steal1 = “wallet” $steal2 = “FTP” $aplib = “aPLib v1.01” condition: uint32(uint32(0x3C)) == 0x00004550 and any of them }