An analysis of reconnaissance and lateral movement in the recent [not] Carbanak source code leak.
A rare learning opportunity
Figure 1: Tweet with link to research by Minerva Labs
Putting aside questions of attribution, it is clear that this is the source code of a self-distributing worm. This malware targets financial systems of Russian banks by spreading itself within the bank’s network, finding the computers that run the targeted software and manipulating payment information flowing through them. A substantial part of the code is dedicated to spreading itself as widely as possible.
Malware source code leaks often provide an unusual peek into how attackers think, allowing us to gain insights regarding questions such as:
- Why did they chose to implement the malware one way rather than another?
- What do they consider to be critical elements of the code, versus components that were written as afterthoughts?
- What does it reflect about how the larger operation is designed?
In this blog we’ll focus on analyzing the code that drives the reconnaissance and lateral movement phases of the Buhtrap/Ratopak/Pegasus operation.
First let’s take a look at how the malware as a whole is structured. Luckily for us, the leak contains a readme file, which briefly describes each of the code’s modules. The code itself is wonderfully documented, making it easy to understand.
Figure 2: The opening of the readme file, translated by Denis O'Brien
*From now on we’ll use italics to mark internal names from the code, and bold to mark technical terms.
When a machine is first infected, the shellcode loads an installation DLL by the name of InstallDispatcherDll, which does the following:
- Performs privilege escalation if needed, relying on known vulnerabilities.
- Creates an SVCHOST process and uses Process Hollowing to inject the main DLL (WorkDispatcherDll) into it, while trying to avoid triggering malware detection systems such as Kaspersky Internet Security (KIS) by avoiding the decryption of the string ““%SYSTEM%\svchost.exe” in its memory at a certain stage of the injection.
Figure 3: Creating a suspended SVCHOST for process hollowing, taking care not to trigger KIS
When WorkDispatcherDll starts running inside the SVCHOST process, it does the following:
- Performs some general initialization steps.
- Starts listening, via named pipes, for incoming data from other malware agents (from now on we’ll refer to a single instance of the malware on an infected machine as “agent”) in the network, primarily to receive domain credentials they have harvested.
- Loads the different modules:
- mod_CmdExec – This module receives commands to execute from the C&C server.
- mod_KBRI and mod_KBRI_hd – These are payload modules that only run on machines marked beforehand as relevant, e.g “crown jewels” of the network -- machines that run the targeted financial software . The goal of these modules is to intercept and swap payment data.
- mod_NetworkConnectivity – This module establishes network connectivity for the agent. It can either connect directly to C&C via the Internet and serve as a proxy for other agents, or, if it doesn’t have Internet connectivity, it can broadcast within the local network to find another agent to use as a proxy.
- mod_LogonPasswords and mod_DomainReplication – These two modules harvest credentials from the machine, share them with the fellow agents in the network and use them (and ones shared by other agents) to propagate throughout the entire network. These two modules will be our focus in the next part of the blog, as they are the core lateral movement modules.
Figure 4: C&C panel, which displays for the attackers the list of infected machines and allows them to send the commands
Reaching out – the lateral movement scheme
The goal of this operation is to manipulate payment information flow within the bank. To do this, attackers need access to specific computers in the organization, namely ones where the relevant software runs. The approach chosen by the malware authors is as follows:
- Let the malware spread itself to as many machines as possible in the network
- Every time a new machine is infected, the installed malware checks to see if it landed on one of the “crown jewels” where the financial software runs;
- If so, the malware executes the payload;
- The financial manipulation part of the operation begins.
So how does the malware recognize that it is running on a “crown jewel” machine? Here comes an interesting bit: the hostnames of the “crown jewel” machines are hard-coded in the malware. That’s right! Not a regex, not a generic name that these machines tend to have, not by looking for a specific software or process, but by the actual hostname of the hosts being targeted.
Figure 5: Checking if the payload module should inject on this specific host, by hostname
This last bit of information suggests that there are at least two distinct stages to this operation because the names of the specific hosts would had to have been gathered through a preceding process, presumably from a previous visit to the network.
It appears that attackers first gain access to the network and harvest the Active Directory database of the organization, along with some credentials. (In this case, some of this information, or perhaps all of it, was leaked along with the source code). Additionally, a hard-coded domain admin password is present in the code. So the code we now see is meant to be used after the initial intel-gathering stage, when the attackers have already identified the systems they need to reach in the network.
To facilitate the actual propagation across e the network, the malware agents do the following:
- Harvest credentials;
- Share credentials among themselves;
- Try the credentials on all available machines in the network.
There are no signs in the code indicating the usage of remote code execution exploits or any other form of lateral movement besides harvesting passwords and using them for authenticated remote execution.
Password harvesting details
In order to harvest passwords, the authors incorporated code from an old version of Mimikatz into the malware’s Com_LogonPasswords module. They specifically used only the most famous feature of Mimikatz - the one which enable extraction of plain text passwords from the LSASS process. This method would not work on Windows 10 hosts that have Credentials Guard enabled, or on under some configurations of Windows 8.1 and later only hashes will be extracted without plaintext passwords. However, it seems that this operation was based on intel that the network is Windows XP-based. The code comments show that they are aware of other methods of harvesting credentials, such as gathering them from .RDP files, but at least in this version, these methods are not implemented.
Figure 6: Giving credit where credit is due. Mimikatz code inside the project.
Figure 7: Managing credentials. Harvesting from .RDP file is mentioned but not implemented.
Remote code execution
The next question is how to use the credentials to execute code on remote machines. Here the malware has a few tricks up its sleeve, and a few more under development, according to the comments in the code. Let’s list them in the order in which the malware tries to execute them:
- WMI remote process – Copies shellcode and libraries to target by ADMIN$ share, then uses WMI ExecMethod to remotely start a process.
- Remote service - Copies shellcode and libraries to target by ADMIN$ share, then uses SCM CreateService API to start the payload as a remote service at the targeted host.
- RDP alternate shell – Utilizes a feature of RDP that enables selection of a program to be run at the server immediately when a connection is created, as specified by the “alternate shell” property in the .RDP file. This feature can be used for remote code execution in the following way:
- Create an .RDP file set to connect to the target;
- Set the “alternate shell” property to execute a payload at the \\tsclient\... share;
- Use DPAPI to properly encrypt the credentials and add them to the .RDP file;
- Connect and cause the payload to be executed by the target.
The following methods are mentioned in comments but were not actually implemented in this version of the code:
Figure 8: List of supported and planned remote execution methods
Figure 9: Preparing .RDP file for remote code execution with alternate shell
Even though wide network access was the code authors’ top priority, there are several indications in the code of care that was taken to minimize evidence of their activity:
- When WorkDispatcherDll loads a module, the authors intended it to make random modifications to the PE header and data section to prevent security products from detecting the modules by hash. Unfortunately (for them!), they haven’t gotten to implementing it yet.
- They used strict limitations concerning network connections outside the local network.
- Their remote service creation routine omits reporting Service Manager at its startup. The reason for this, as a code comment reveals, is to “avoid using too much code suitable for signatures”, referring to AV signatures that could be used to detect malicious code.
Figure 10: Future design to randomly modify PE header and data section
Figure 11: Planning connectivity to avoid detection
So what does it all mean?
Our analysis leads to some conclusions and speculations:
- It doesn’t take high-end level technology to breach a bank. Overall, the code here is not remarkably sophisticated. It doesn’t use any zero-days and it leverages some well-known techniques such as Process Hollowing or injecting code via CreateRemoteThread.
- Intelligence gathering can remove many obstacles for attackers, including AV software. It is very clear that the attackers here knew what to expect within the network. They knew it contained a Domain of Windows XP machines protected by Kaspersky Internet Security. This knowledge allowed them to plan accordingly and dedicate effort to address only the specific challenges they expected as a result of these condition-- they countered KIS detection, for example, using certain manipulations of the string “%SYSTEM%\svchost.exe”. This preemptive intel enables them to create a minimal code, tailored to their specific needs and the context of the target environment.
- The authors felt secure enough to spread their code to many hosts where it wasn’t really required. Their approach was obviously to maximize network access and data gathering. They didn’t seem to hesitate to make a lot of noise via unnecessary lateral movement; perhaps they assumed no one was listening carefully enough to notice.
- The campaign was designed to be ongoing, not as a hit and run. This is evidenced by the incorporation of data gathered beforehand, and also by the code’s version control and update mechanisms. Some parts of the code suggest that there were at least nine prior versions to it (CORE_APIS_V10), although it is possible earlier versions were used in different campaigns.
- The project is remarkably well documented in both English and While the external files are in Russian, the code itself has very verbose English documentation. This is not entirely unusual; the gozi-isfb leaked code was also documented in English. Zeus leaked code, in contrast, is documented almost entirely in Russian.
This example of a source code leak allows us to examine in detail the inner workings of a targeted campaign. It demonstrates a typical approach to lateral movement, relying on credential harvesting to distribute as widely as possible. In this case, the attack was against a bank’s financial system, but the same methodology can be applied to an attack against the critical systems of any organization. The analysis also shows how attackers prepare to face off against the organization’s AV product, and highlights the limitations of such traditional products in defending against a modern bank heist. From our perspective as designers of deception approaches, it also shows the value an organization could derive from placing deceptive passwords, deceptive .RDP files, etc. to enable early detection for protection of the network.
https://blog.minerva-labs.com/pimped-buhtrap-source-leaked by Minerva Labs
http://malwageddon.blogspot.com/2018/07/you-only-had-one-job.html by Denis O’Brien