Cómo automatizar la extracción del shellcode de Cobalt Strike

Hola a tod@s!

En mi anterior artículo , vimos cómo extraer la shellcode de los “artefact” generados por Cobalt Strike. En este, veremos cómo con esa shellcode podemos sacar los datos de forma automatizada.

Recordemos que la información que nos interesa es:

  • ¿ Es una shellcode de Cobalt Strike ?
  • ¿ Hacia qué dirección ip o dominio se conecta ?
  • ¿ A qué puerto ?
  • ¿ Qué cabeceras añade, user-agent y otras ?
  • ¿ La url ?

Dicho esto, pasemos a la acción.

¿ Os acordáis de aquel listado interminable de artefactos del artículo anterior ? Cojo uno al azar:

Son el mismo fichero. En el que, según habíamos visto, nos interesa esta parte:

Artefactos de Cobalt

Para nuestro propósito, extraer esa zona, podría traducirse a algo como esto:

f = open(filename, "rb")
f.seek(0x2200)
shellcode = f.read(0x2600 - 0x2200)
f.close()

Abre el fichero “Artifact.exe”, posiciónate en 0x2200 y extrae esa zona que ocupa 1K. Algunas ser más grandes, ojo.

[0x004014b0]> ? 0x2600 - 0x2200
int32 1024
uint32 1024
hex 0x400
octal 02000
unit 1K

Ahora lo tengo que tratar, como binario y como un array de byte y pásale el algoritmo para descifrarlo.

data = bytearray(shellcode)
decoded = decode(data)

Supongamos que ya tenemos esa shellcode descifrada como sigue:

Shellcode descifrado

Al principio hice todo esto que veréis a continuación de otra forma pero daban resultados erróneos en shellcode con ciertos datos, ahora veis un user-agent, por ej. pero en otros casos la cabecera es mayor, se le añade el campo Host u otros campos, mirad un ejemplo:

Host: stackoverflow[.]com
Accept: */*
Accept-Language: en-US,en;q=0.5
X-Requested-With: XMLHTTPRequest
Etag: 4aeebe4a839401711e5daeaaa0fe85d5
Connection: close
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/41.0

Así que me centraré en explicar lo más importante del script. Que por cierto, va dirigido para shellcode que realizan peticiones http(s).

Aunque el script funciona con shellcodes de 64 bits, en el artículo explico las de 32, que son las más peculiares. Hay que comprobar paso a paso si se trata de este tipo del shellcode ya que en caso contrario no tiene sentido sacar ip, dominios, user-agents, etc. Así que vamos comprobando paso a paso.

Lo primero si pertenecen a Cobalt Strike. Deberían comenzar siempre de la misma forma, ¿verdad?

Shellcode x32:

Shellcode x32

Shellcode x64:

Shellcode x64

Esa debería ser nuestra primera comprobación. Pero… nos pasaría esto, así que no seamos tan estrictos.

La siguiente comprobación que debemos realizar es esta:

Siguiente comprobación

Si recordáis el uso de Scdbg, muy útil para estos casos, veíais algo como esto:

Scdbg busqueda

Busco esas cadenas:

Busqueda de cadena

Busco el User-Agent:

Búsqueda de agente

Busco el puerto:

Búsqueda de puerta

Está en little endian, así que lo necesito al revés.

Calculo la ip o dominio (dominio en este caso):

Calculo de ip

Sólo nos queda la url:

Búsqueda de url

Ya estaría todo lo necesario para obtener los datos de forma automática. Primero vamos a los de la shellcode, a dejarlo bonito:

Shellcode bonito

Script en Python para obtener los datos de las shellcode de Cobalt Strike:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *