Decodificación de scripts maliciosos de PowerShell

Potencia Shell. Está en todas partes. Empecé a encontrar más y más scripts maliciosos de PowerShell.

¿Por qué a los atacantes les encanta usar PowerShell? Debido a que es nativo de muchas versiones de Windows, proporciona acceso completo a WMI y .Net Framework y puede ejecutar código malicioso en la memoria, evitando así AV. Oh sí, ¿mencioné también la falta de registro?

Durante el análisis de este tipo de casos, he encontrado varias indicaciones de que un atacante ha utilizado PowerShell. Estos incluyen servicios instalados, entradas de registro y scripts de PowerShell en el disco. Si el registro está habilitado, eso también puede proporcionar algunos artefactos agradables. La perspectiva de mi publicación será la de un analista que quizás no esté muy familiarizado con PowerShell. Voy a discutir cómo localizo los artefactos maliciosos de PowerShell durante mi análisis, así como algunos métodos que uso para descifrar los scripts de PowerShell confusos. Esta será la Parte 1 en una serie de 3 partes escrita en las próximas semanas. 

Parte 1: Scripts de PowerShell instalados como servicios
Lo primero es batear mi favorito: los scripts de PowerShell que encuentro como servicios instalados en el registro de eventos del sistema. Para encontrar esto, una de las primeras cosas que hago es buscar el Id. De evento 7045. Este evento ocurre cuando se instala un servicio en un sistema. A continuación se muestra un ejemplo de un script de PowerShell instalado como un servicio:

 

Son de destacar las siguientes banderas rojas: 

1) Nombre de servicio aleatorio 
2) El Nombre de archivo de servicio tiene «% COMSPEC%», que es la variable de entorno para cmd.exe 
3) Una referencia al ejecutable powershell 
4) Datos codificados en base 64 

Así ¿Cómo podría una entrada como esta abrirse camino en un registro de eventos? Si bien hay varias formas de hacerlo, un método sería utilizar el Administrador de control de servicios de Windows integrado para crear un servicio:

sc.exe cree MyService binPath =% COMSPEC% powershell.exe -nop -w oculto -comoded command <inserciónbase64> </inserciónbase64>

sc start MyService

Los comandos anteriores crean un servicio llamado «MyService» y usan la opción binPath = para iniciar cmd.exe, que a su vez ejecuta el código de PowerShell.   

Una cosa interesante a tener en cuenta: puede haber algunos errores fallidos registrados después de que el servicio se haya creado de esta manera. Los errores no significanque no tuvo éxito Windows esperaba que se instalara un binario «real» de servicio y que «se agote el tiempo de espera» para que el «servicio» le informe. ¿Cómo puedo saber esto? En mis pruebas pude configurar una shell inversa exitosa utilizando la metodología anterior, que generó un error de servicio fallido en la máquina con Windows. A la izquierda hay una sesión de Metaspolit que comencé en una máquina virtual de ataque. A la derecha hay una máquina virtual host de Windows 7. Aunque la máquina con Windows 7 dice «El servicio no respondió a la solicitud de inicio o control de manera oportuna», todavía se abrió un shell inverso en la sesión de Metatsploit:

 

 

A continuación se muestran las dos entradas correspondientes del registro de eventos, 7000 y 7009, realizadas en el registro de eventos del sistema. Aunque el mensaje 7009 dice «El servicio FakeDriver no se pudo iniciar …» no significa que el comando dentro de la variable binPath no se ejecutó correctamente. Así que cuidado, interpretar esto como una indicación de que PowerShell no se ejecutó puede ser falso:

 

 

El comando PoweShell del registro de eventos del sistema 7045 está codificado en base64 y se puede usar python para decodificarlo. Nota interesante: este código base64 está en Unicode, por lo que habrá un parámetro adicional especificado al decodificarlo. (Por razones de visualización, he truncado el texto base64; necesitarías incluir el texto base64 completo para decodificarlo):

import 
código base64 = «JABjACAAPQAgAEAAIgAKAFsARABsAGwASQBtAHAA ….» 
base64.b64decode (código) .decode (‘UTF16’)

Aquí es cómo se ve el comando descodificado de PowerShell. Un barrido rápido del código revela algunos signos reveladores: referencias a la creación de un Net Socket con el protocolo TCP y una dirección IP:

Esto es similar al tipo de código que Meterpreter utiliza para configurar un shell inverso. El código de PowerShell anterior fue bastante fácil de decodificar, sin embargo, generalmente es más complicado. 

El siguiente es otro ejemplo: esta vez es solo base64 «regular». Observe nuevamente la variable% COMSPEC% y haga referencia a powershell.exe:

De nuevo, Python se puede usar para decodificar el PowerShell codificado en base64:

Esta vez, la salida descodificada es menos útil. Si volvemos y observamos más de cerca la entrada del registro de eventos del sistema, podemos ver que hay referencias a «Gzip» y «Descomprimir»:

 

Ahh … así que pensando a la inversa, estos datos pueden haber sido comprimidos con Gzip y luego codificados usando base64. Usando python, escribiré la base64 descodificada en un archivo para poder descomprimirlo:

importar 
código de base64 = «H4sICCSPh1kCADEAT …» 
decodificado = código de base64.b64 (código) 
f = abierto («decoded.gzip», ‘wb’) 
f.write ( 
decoded ) f.close

¡Usando 7zip puedo desempaquetar el archivo gzip! Como no recibí ningún error, puedo estar en el camino correcto:

Ahora si abro el archivo descomprimido con un editor de texto, con suerte veré un código de PowerShell:

Ahh..qué? Ok, es hora de echar un vistazo en un editor hexadecimal:

Tampoco ayuda mucho. Estoy pensando que esto puede ser shellcode. Como próximo paso, lo ejecutaré a través de la herramienta de análisis de código de shell de PDF Stream Dumper , scdbg.exe:

Ta-Da! scdbg.exe fue capaz de extraer algunos IOC del shellcode.

Para resumir, aquí están los pasos que tomé para descodificar esta entrada de PowerShell:

  • Decodificó la cadena PowerShell base64
  • Escribió el decodificador base64 a un archivo zip
  • Descomprimido el archivo Gzip usando 7zip
  • Corrió la salida binaria a través de scdbg.exe

Como se demostró anteriormente, puede haber varias capas antes de que llegue el oro. 

Un último ejemplo:

Esto parece familiar. El primer paso, descodificar el Unicode base64 da el siguiente resultado, que contiene más código base64 dentro del código base64 . :

 

Ofuscado, luego ofuscado de nuevo con compresión. Esto es muy típico de lo que he visto en los casos. Esta vez, ya que no hay ninguna referencia a «gzip» en el texto de compresión, solo guardaré la segunda ronda de base64 en un archivo zip normal e intentaré abrir de nuevo con 7zip:

decoded2 = «nVPvT9swEP2ev + IUR ….» 
f = open («decoded2.zip,» wb «) 
f.write (base64.b64decode (decoded2) 
f.close ()

Cuando intento abrir el archivo comprimido con 7Zip, aparece un error:

Y lo mismo con la utilidad incorporada de Windows:

También probé varias bibliotecas de Python para descomprimir el archivo comprimido. Después de algunas investigaciones, descubrí que la compresión utilizada está relacionada con algunas bibliotecas .Net. Ahora, como soy una chica de Python, quería descubrir cómo descomprimir esto usando Python para poder implementarlo fácilmente en mis scripts. Como Python es compatible con Linux, Windows y Mac, .Net no es nativo a su núcleo. Como tal, utilicé Iron Python para hacer mi oferta. (Ahora sí, puedes usar PowerShell para descifrarlo, pero ¿qué puedo decir? Quería hacerlo con Python) 

Según el sitio web de Iron Python«IronPython es una implementación de código abierto del lenguaje de programación Python que está estrechamente integrado con .NET Framework. IronPython puede usar las bibliotecas .NET Framework y Python, y otros lenguajes .NET pueden usar el código Python con la misma facilidad». Ordenado. Instalarlo en Windows es muy fácil, solo un MSI. Una vez instalado, simplemente ejecute los scripts que llaman a ipy.exe (le mostraré un ejemplo más adelante). 

Armado con esto, pude escribir un código Python (io_decompress.py) que descomprimió el archivo zip usando la biblioteca de compresión IO de python:

#importación requiere. Las bibliotecas .Net de System.IO importan BinaryReader, StreamReader, MemoryStream 
de System.IO.Compression import CompressionMode, DeflateStream 
de System import Array, Byte 
de System.IO import FileStream, FileMode 
de System.Text import Codificación 
de System.IO importar 

# funciones para descomprimir los datos 
def descomprimir (datos): 
    io_zip = DeflateStream (MemoryStream (data), CompressionMode.Decompress) 
    str = StreamReader (io_zip) .ReadToEnd () 
    io_zip.Close () 
    return str 

print «Decompressing stream .. . » 
comprimidoBytes = File.ReadAllBytes (» decoded2.zip «) 
decompressedString = descomprimir (comprimidoBytes)

f = abrir («decompressed.txt», «wb») 
f.write (decompressedString) 
f.close ()

Ejecutar el script usando IronPython fue fácil: ipy.exe io_decompress.py:

Pude abrir el archivo decompressed.txt creado por el script y fui recompensado con el siguiente script de PowerShell de texto sin formato. Una vez más, tenga en cuenta la dirección IP:

Para resumir los pasos tomados para esta entrada de registro de eventos:

  • Decodificado Unicode base64
  • Codificado codificado en base64
  • Descomprimido resultante descodificado codigo base64

Como hemos visto en los tres ejemplos anteriores, hay varias técnicas que los atacantes pueden usar para ofuscar sus entradas de PowerShell. Estos se pueden usar en varias combinaciones, algunas de las cuales he demostrado anteriormente. Los pasos tomados varían para cada caso, y dentro de cada caso en sí. Por lo general, veo 2-3 variaciones en cada caso que se eliminan en cientos de sistemas en el transcurso de varios meses. A veces, los pasos pueden ser: base64, base64, descomprimir, shellcode. También podría ser: base64, descomprimir, base64, código, base64, shellcode. ¿Ves lo rápido que esto se vuelve como una muñeca Matryoshka? Cuando termine la serie, hablaré sobre las formas de automatizar el proceso. Si está utilizando algo como los scripts de las líneas de tiempo de Harlan Carvy para obtener resultados de texto, se vuelve bastante fácil.

Entonces, ¿cómo encontrarlos y decodificarlos en tus exámenes? 

  • Busque el ID de registro de eventos 7045 con «% COMSPEC%, powershell.exe, -comoded-command, -w oculto,» From Base64String «, etc.
  • Busque «Gzipstream» o «[IO.Compression.CompressionMode] :: Descomprimir» para obtener sugerencias sobre qué tipo de compresión se usó
  • Intente ejecutar los archivos binarios resultantes a través de sdbg.exe, shellcode2exe u otras herramientas de análisis de malware.

 

Mari degrazia.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: