A dive into Turla PowerShell usage

ESET researchers analyze new TTPs attributed to the Turla group that leverage PowerShell to run malware in-memory only

ESET researchers analyze new TTPs attributed to the Turla group that leverage PowerShell to run malware in-memory only

Turla, also known as Snake, is an infamous espionage group recognized for its complex malware. To confound detection, its operators recently started using PowerShell scripts that provide direct, in-memory loading and execution of malware executables and libraries. This allows them to bypass detection that can trigger when a malicious executable is dropped on disk.

Turla is believed to have been operating since at least 2008, when it successfully breached the US military. More recently, it was involved in major attacks against the German Foreign Office and the French military.

This is not the first time Turla has used PowerShell in-memory loaders to increase its chances of bypassing security products. In 2018, Kaspersky Labs published a report that analyzed a Turla PowerShell loader that was based on the open-source project Posh-SecMod. However, it was quite buggy and often led to crashes.

After a few months, Turla has improved these scripts and is now using them to load a wide range of custom malware from its traditional arsenal.

The victims are quite usual for Turla. We identified several diplomatic entities in Eastern Europe that were compromised using these scripts. However, it is likely the same scripts are used more globally against many traditional Turla targets in Western Europe and the Middle East. Thus, this blogpost aims to help defenders counter these PowerShell scripts. We will also present various payloads, including an RPC-based backdoor and a backdoor leveraging OneDrive as its Command and Control (C&C) server.

PowerShell Loader

The PowerShell loader has three main steps: persistence, decryption and loading into memory of the embedded executable or library.


The PowerShell scripts are not simple droppers; they persist on the system as they regularly load into memory only the embedded executables. We have seen Turla operators use two persistence methods:

  • A Windows Management Instrumentation (WMI) event subscription
  • Alteration of the PowerShell profile (profile.ps1 file).

Windows Management Instrumentation

In the first case, attackers create two WMI event filters and two WMI event consumers. The consumers are simply command lines launching base64-encoded PowerShell commands that load a large PowerShell script stored in the Windows registry. Figure 1 shows how the persistence is established.

Figure 1. Persistence using WMI

These events will run respectively at 15:30:40 and when the system uptime is between 300 and 400 seconds. The variable $HL39fjh contains the base64-encoded PowerShell command shown in Figure 2. It reads the Windows Registry key where the encrypted payload is stored, and contains the password and the salt needed to decrypt the payload.

Figure 2. WMI consumer PowerShell command

Finally, the script stores the encrypted payload in the Windows registry. Note that the attackers seem to use a different registry location per organization. Thus, it is not a useful indicator to detect similar intrusions.


In the latter case, attackers alter the PowerShell profile. According to the Microsoft documentation:

A PowerShell profile is a script that runs when PowerShell starts. You can use the profile as a logon script to customize the environment. You can add commands, aliases, functions, variables, snap-ins, modules, and PowerShell drives.

Figure 3 shows a PowerShell profile modified by Turla.

Figure 3. Hijacked profile.ps1 file

The base64-encoded PowerShell command is very similar to the one used in the WMI consumers.


The payload stored in the Windows registry is another PowerShell script. It is generated using the open-source script Out-EncryptedScript.ps1 from the Penetration testing framework PowerSploit. In addition, the variable names are randomized to obfuscate the script, as shown in Figure 4.

Figure 4. Decryption routine

The payload is decrypted using the 3DES algorithm. The Initialization Vector, PINGQXOMQFTZGDZX in this example, is different for each sample. The key and the salt are also different for each script and are not stored in the script, but only in the WMI filter or in the profile.ps1 file.

PE loader

The payload decrypted at the previous step is a PowerShell reflective loader. It is based on the script Invoke-ReflectivePEInjection.ps1 from the same PowerSploit framework. The executable is hardcoded in the script and is loaded directly into the memory of a randomly chosen process that is already running on the system.

In some samples, the attackers specify a list of executables that the binary should not be injected into, as shown in Figure 5.

Figure 5. Example list of excluded processes

It is interesting to note that the names avp.exe, avpsus.exe, klnagent.exe and vapm.exe refer to Kaspersky Labs executables. It seems that Turla operators really want to avoid injecting their malware into Kaspersky software.

AMSI bypass

In some samples deployed since March 2019, Turla developers modified their PowerShell scripts in order to bypass the Antimalware Scan Interface (AMSI). This is an interface allowing any Windows application to integrate with the installed antimalware product. It is particularly useful for PowerShell and macros.

They did not find a new bypass but re-used a technique presented at Black Hat Asia 2018 in the talk The Rise and Fall of AMSI. It consists of the in-memory patching of the beginning of the function AmsiScanBuffer in the library amsi.dll.

The PowerShell script loads a .NET executable to retrieve the address of AmsiScanBuffer. Then, it calls VirtualProtect to allow writing at the retrieved address.

Finally, the patching is done directly in the PowerShell script as shown in Figure 6. It modifies the beginning of AmsiScanBuffer to always return 1 (AMSI_RESULT_NOT_DETECTED). Thus, the antimalware product will not receive the buffer, which prevents any scanning.

Figure 6. Patching of AmsiScanBuffer function


The PowerShell scripts we have presented are generic components used to load various payloads, such as an RPC Backdoor and a PowerShell backdoor.

RPC backdoor

Turla has developed a whole set of backdoors relying on the RPC protocol. These backdoors are used to perform lateral movement and take control of other machines in the local network without relying on an external C&C server.

The features implemented are quite basic: file upload, file download and command execution via cmd.exe or PowerShell. However, the malware also supports the addition of plugins.

This RPC backdoor is split into two components: a server and a client. An operator will use the client component to execute commands on another machine where the server component exists, as summarized in Figure 7.

Figure 7. RPC backdoor usage

For instance, the sample identified by the following SHA-1 hash EC54EF8D79BF30B63C5249AF7A8A3C652595B923 is a client version. This component opens the named pipe \\pipe\\atctl with the protocol sequence being “ncacn_np” via the RpcStringBindingComposeW function. The sample can then send commands by calling the NdrClientCall2 function. The exported procedure HandlerW , responsible for parsing the arguments, shows that it is also possible to try to impersonate an anonymous token or try to steal another’s process token just for the execution of a command.

Its server counterpart does the heavy lifting and implements the different commands. It first checks if the registry key value HKLM\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters\NullSessionPipes contains “atctl”. If so, the server sets the security descriptor on the pipe object to “S:(ML;;NW;;;S-1-16-0)” via the SetSecurityInfo function. This will make the pipe available to everyone (untrusted/anonymous integrity level).

The following image shows the corresponding MIDL stub descriptor and the similar syntax and interface ID.

Figure 8. RPC backdoor client’s MIDL on the left, server’s on the right

As mentioned previously, this backdoor also supports loading plugins. The server creates a thread that searches for files matching the following pattern lPH*.dll. If such a file exists, it is loaded and its export function ModuleStart is called. Among the various plugins we have located so far, one is able to steal recent files and files from USB thumb drives.

Many variants of this RPC backdoor are used in the wild. Among some of them, we have seen local proxies (using upnprpc as the endpoint and ncalrpc as the protocol sequence) and newer versions embedding PowerShellRunner to run scripts directly without using powershell.exe.

RPC Spoof Server

During our research, we also discovered a portable executable with the embedded pdb path C:\Users\Devel\source\repos\RPCSpoofer\x64\Release_Win2016_10\RPCSpoofServerInstall.pdb (SHA-1: 9D1C563E5228B2572F5CA14F0EC33CA0DEDA3D57).

The main purpose of this utility is to retrieve the RPC configuration of a process that has registered an interface. In order to find that kind of process, it iterates through the TCP table (via the GetTcpTable2 function) until it either finds the PID of the process that has opened a specific port, or retrieves the PID of the process that has opened a specific named pipe. Once this PID is found, this utility reads the remote process’ memory and tries to retrieve the registered RPC interface. The code for this, seen in Figure 9, seems ripped from this Github repository.

Figure 9. Snippet of code searching for the .data section of rpcrt4.dll in a remote process (Hex-Rays screenshot)

At first we were unsure how the retrieved information was used but then another sample, (SHA-1: B948E25D061039D64115CFDE74D2FF4372E83765) helped us understand. As shown in Figure 10, this sample retrieves the RPC interface, unsets the flag to RPC_IF_ALLOW_SECURE_ONLY, and patches the “dispatch table” in memory using the WriteProcessMemory function. Those operations would allow the sample to add its RPC functions to an already existing RPC interface. We believe it is stealthier to re-use an existing RPC interface than to create a custom one.

Figure 10. Snippet of code retrieving the RPC dispatch table of the current process (Hex-Rays screenshot)


PowerStallion is a lightweight PowerShell backdoor using Microsoft OneDrive, a storage service in the cloud, as C&C server. The credentials are hardcoded at the beginning of the script, as shown in Figure 11.

Figure 11. OneDrive credentials in PowerStallion script

It is interesting to note that Turla operators used the free email provider GMX again, as in the Outlook Backdoor and in LightNeuron. They also used the name of a real employee of the targeted organization in the email address.

Then it uses a net use command to connect to the network drive. It then checks, in a loop, as shown in Figure 12, if a command is available. This backdoor can only execute additional PowerShell scripts. It writes the command results in another OneDrive subfolder and encrypts it with the XOR key 0xAA.

Figure 12. Main loop of the PowerStallion backdoor

Another interesting artefact is that the script modifies the modification, access and creation (MAC) times of the local log file to match the times of a legitimate file – desktop.ini in that example, as shown in Figure 13.

Figure 13. Modification of MAC times of the local log file

We believe this backdoor is a recovery access tool in case the main Turla backdoors, such as Carbon or Gazer, are cleaned and operators can no longer access the compromised computers. We have seen operators use this backdoor for the following purposes:

  • Monitoring antimalware logs.
  • Monitoring the Windows process list.
  • Installing ComRAT version 4, one of the Turla second-stage backdoors.


In a 2018 blogpost, we predicted that Turla would use more and more generic tools. This new research confirms our forecast and shows that the Turla group does not hesitate to use open-source pen-testing frameworks to conduct intrusion.

However, it does not prevent attributing such attacks to Turla. Attackers tend to configure or modify those open-source tools to better suit their needs. Thus, it is still possible to separate different clusters of activities.

Finally, the usage of open-source tools does not mean Turla has stopped using its custom tools. The payloads delivered by the PowerShell scripts, the RPC backdoor and PowerStallion, are actually very customized. Our recent analysis of Turla LightNeuron is additional proof that this group is still developing complex, custom malware.

We will continue monitoring new Turla activities and will publish relevant information on our blog. For any inquiries, contact us as threatintel@eset.com. Indicators of Compromise can also be found on our GitHub.

Indicators of Compromise (IoCs)


SHA-1 hashDescriptionESET detection name
50C0BF9479EFC93FA9CF1AA99BDCA923273B71A1PowerShell loader with encrypted payloadPowerShell/Turla.T
EC54EF8D79BF30B63C5249AF7A8A3C652595B923RPC backdoor (client)Win64/Turla.BQ
9CDF6D5878FC3AECF10761FD72371A2877F270D0RPC backdoor (server)Win64/Turla.BQ
D3DF3F32716042404798E3E9D691ACED2F78BDD5File exfiltration RPC pluginWin32/Turla.BZ
B948E25D061039D64115CFDE74D2FF4372E83765RPC interface patcherWin64/Turla.BR


  • RPC components
    • %PUBLIC%\iCore.dat (log file, one-byte XOR 0x55)
    • \\pipe\\atctl (named pipe)
  • PowerStallion
    • msctx.ps1
    • C:\Users\Public\Documents\desktop.db

Registry keys

  • RPC components
    • HKLM\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters\NullSessionPipes contains atctl

MITRE ATT&CK techniques

ExecutionT1086PowerShellThe loaders are written in PowerShell.
Some RPC components can execute PowerShell commands.
PersistenceT1084Windows Management Instrumentation Event SubscriptionThe PowerShell loaders use WMI for persistence.
Defense EvasionT1027Obfuscated Files or InformationThe RPC backdoor and PowerStallion encrypt the log file.
T1140Deobfuscate/Decode Files or InformationThe PowerShell loaders decrypt the embedded payload.
T1055Process InjectionThe PowerShell loaders inject the payload into a remote process.
T1099TimestompPowerStallion modifies the timestamps of its log file.
DiscoveryT1083File and Directory DiscoveryThe RPC plugin gathers file and directory information.
T1120Peripheral Device DiscoveryThe RPC plugin monitors USB drives.
T1012Query RegistryThe server component of the RPC backdoor queries the registry for NullSessionPipes.
T1057Process DiscoveryPowerStallion sent the list of running processes.
CollectionT1005Data from Local SystemThe RPC plugin collects recent files from the local file system.
T1025Data from Removable MediaThe RPC plugin collects files from USB drives.
Command and ControlT1071Standard Application Layer ProtocolThe RPC backdoor uses RPC and PowerStallion uses OneDrive via SMB.
ExfiltrationT1041Exfiltration Over Command and Control ChannelPowerStallion exfiltrates information through the C&C channel.

Sign up to receive an email update whenever a new article is published in our Ukraine Crisis – Digital Security Resource Center