Analizando y detectando el troyano AsyncRAT


Hola a  tod@s !!
Me gustaría ir viendo una serie de malware que suelen estar en el TOP 10 en todos los ranking sobre troyanos, stealers, ransomware, etc . Para que podamos ir viendo su comportamiento y como podríamos detectarlos para que no nos hagan tanto daño.
 Hoy le ha tocado al troyano AsyncRAT, pero antes, hagamos un repaso. 
  AsyncRAT es un RAT que puede monitorizar y controlar remotamente sistemas infectados. Este malware fue introducido en Github como un software legítimo de administración remota de código abierto, pero los hackers lo utilizan por sus muchas funciones poderosas maliciosas.

Siempre me gusta encontrar anomalías, o detecciones de algo que, a priori, no sé de qué se trata como este caso, esto :
 ¿Que será, será? Abrimos ese fichero 7zip y nos encontramos con 2 ficheros:
El primero es un correo en formato MSG (para abrirlo con Microsoft Outlook) y el segundo, es un directorio con una serie de binarios dentro.
Por lo que intuyo que en ese correo vendrá ese zip o bien un enlace para su descarga, vamos a verlo.
No se aprecia bien en la imagen, pero es un enlace para la descarga del fichero:
Una vez descargado solicita la contraseña que aparece en el mismo correo, por lo que si logras hacerte con un fichero como esos, no podrás acceder a su contenido a no ser que conozcas la contraseña, un primer paso para que no pueda ser analizado directamente , no lo iban a poner fácil, no.
Pasamos al fichero que en el zip que veíamos en Any.run ya estaba generado sin la contraseña.
Una prueba que me gusta hacer para identificar si el malware es el EXE o alguna de las DLL es ejecutar primero el EXE quitándoles las DLL de la ruta y veo si se ejecuta bien, vemos como en este caso no lo hace. Para ello, abres Procmon y ves su comportamiento. Puedes jugar con el filtro de “Path ends with .dll” y así puedes comprobar cuáles va a necesitar cargar ya que las irá buscando una a una.
Esto no quiere decir que el malware se esconde en esa DLL sino que es necesaria para su ejecución.
Dicho esto, tenemos 3 DLL y alguna de ellas será el malware, ¿Cuál será? Veamos que nos dice herramientas como PEStudio .
Certificado inválido para Malware El certificado para esa DLL no es válido, entonces la DLL maliciosa sería  asus_wmi.dll .
Pues vamos ajecutarlo todo (el EXE cargará esta DLL, técnica de Mitre DLL Sideloading) y ver qué hace. Para ello, usaremos API Monitor.
Bien, tenemos un buen comienzo, obtiene la ruta del EXE, accede a un fichero llamado  aboriginal.raw , carga una serie de direcciones que obtiene para las API LoadLibraryA y VirtualProtect y las llama para ejecutar el contenido de ese fichero con permisos de ejecución.
Hagamos una pausa, ¿donde está esto dentro de la DLL?
Se identifica todo esto en el código, salvo lo que va necesitando, eso no se ve tan claramente, para eso está el análisis dinámico. A la izquierda de la imagen, dinámico, a la derecha el estático. El dinámico está para ayudar al estático, no siempre se ve tan claro y es necesario, uno y otro.
Si guardáis el resultado de Procmon en CSV y utilizáis ProcDOT , veréis a modo de gráfico el comportamiento del malware, ayuda en muchas ocasiones a detectar cosas que de otra forma no veríais.
Vemos como además del fichero mencionado antes, hace uso del otro,  ataraxia.db . Después de eso aparece un nuevo proceso,  cmd.exe  y después otro,  MSBuild.exe  en donde parece que acaba todo, bueno, eso de que acaba… más bien empieza, me da a mí ;)
El malware se copia a un directorio de %APPDATA%.
Para futuras ejecuciones, y es importante que estén todos los ficheros, para que funcione, si elimináis alguno no lo hará, sobre todo el .raw y .db.
El troyano AsyncRAT se encuentra inyectado en   MSBuild.exe , por lo que se puede extraer con Hollows_hunter:
Miramos que ha extraído, un binario compilado con .Net :
¿Es antiguo?
Según la fecha de compilación lo es, de 2013. Pero no nos lo creemos, ¿verdad? Esta fecha se puede alterar fácilmente con un editor hexadecimal o multitud de utilidades.
Lo abrimos con DnSpy y accedemos al punto de entrada (EntryPoint).
Podemos observar como tiene algo de ofuscación, ya sólo queda ir función a función analizando el comportamiento. 
Vemos los comandos recibidos desde el servidor para ir realizando las diferentes acciones.
$ grep evUbXPfeFYDN NdAbYmwfcczrL/BvbAjsokTpB.cs | grep "==" | awk -F" '{print $2}'| sort -u
anydesk
Avast
backproxy
Block
Chrome
DicordTokens
Dll
Fox
getscreen
gettxt
KillProxy
killps
klget
Net35
passload
plugin
pong
ResetHosts
ResetScale
savePlugin
setxt
uacoff
Wallets
WDExclusion
WebBrowserPass
weburl

Vemos como lee el fichero relacionado con las capturas de teclas realizadas por el usuario  Log.tmp  en el directorio temporal o como desactiva el Antivirus Avast en caso de tenerlo instalado, estos son sólo unos ejemplos de lo que hace esa función. 
Trata de detectar que se ejecuta en entorno de Máquina Virtual.
O en entorno de Sandboxie:
Comprueba que el tamaño del disco no sea menor a ese valor que vemos y que el SSOO no sea un Windows XP.
La persistencia la crea con la clave de Registro en SOFTWAREMicrosoftWindowsCurrentVersionRun, dependiendo de los permisos.
Después de obtener información básica sobre el usuario y el entorno en donde se ejecuta, obtiene información de los navegadores o wallets que exfiltrará posteriormente al  Command and Control .
$ grep -R zIdwWubRehYnG.NbofEcUcoMbVs VyjkTQqEiFxBtz/IUCayWVdAJWWCoh.cs | grep -v False | awk -F" '{print $2}'
Packet
HWID
User
Path
Admin
Performance
Pastebin
Antivirus
Meta_Firefox
Meta_Chrome
Meta_Brave
Meta_Edge
Meta_Opera
Meta_OperaGX
Phantom_Chrome
Phantom_Brave
Binance_Chrome
Binance_Edge
TronLinkChrome
BitKeep_Chrome
Coinbase_Chrome
Ronin_Chrome
Trust_Chrome
BitPay_Chrome
F2a_Chrome
F2a_Brave
F2a_Edge
Ergo_Wallet
Ledger_Live
Atomic
Exodus
Electrum
Coinomi
Binance
Bitcoin_Core
Pong
Group
BoolWallets
LastTime

La configuración se encuentra cifrada dentro del malware.
He visto algún POST en donde descifran esta configuración con Cyberchef . Me decanté por un script que veremos a continuación, pero antes, os pongo una captura de como se vería esto sin ofuscar:
Según esta captura, vemos como se encuentra el puerto, los hosts, versión, clave, etc. En la versión ofuscada sigue el mismo orden, por lo que habría que ir copiando y pegando según están, ¿en donde? En el siguiente script.
# Script by https://eln0ty.github.io/malware%20analysis/asyncRAT/
# 1) use PBKDF2 to derive the decryption key and initialization key used for sha
# 2) calculate sha256 of data[32:] and compare it to the embedded sha256 hash (data[:32]) (We don't care here)
# 3) iv = data[32:48]
# 4) aes_dec(key, iv, data[48:])

# pip install backports.pbkdf2
# pip install malduck

from backports.pbkdf2 import pbkdf2_hmac
from base64 import b64decode
from malduck import aes, unpad

# Salt = Encoding.ASCII.GetBytes("DcRatByqwqdanchun"); grep Rfc2898DeriveBytes

salt = b"xbfxebx1ex56xfbxcdx97x3bxb2x19x02x24x30xa5x78x43x00x3dx56x44xd2x1ex62xb9xd4xf1x80xe7xe6xc3x39x41"
key = b"NHl0bXdDMHJYeVFXdURXTkpLS3NZNXJmcjBzQk9nTGg="

config = {
"Ports": "qgsqILrZwGyelGsL2vBeptcpNvBNTOF+JsgPcvnhUxPJln9whxhVAg1fXXl1eVWI1VXifNJXVZI+QaDOtKFQZA==",
"Hosts": "ttKCei2wakddmH5v5fkeZbFsAbcmhDXNbTRhQlVl5bO2ALb8Y0pjGvj2BRh2mTubuwW+lga3xbnXRsMq5O+En8XRqvF881XmRKShJCidqQY=",
"Version": "3Dmrz3b8n924yMvtBIriKPnY5AeI5XLFDSy54U9QXAiF52cekLDya7rwJaFJMpOzOHuhHOwNbffaaKQ6H33Q3d8t1xVEoDhckJXPSpeF+C4=",
"Install": "mQLkvODFxhIDROCJMN2M3xBk1w57Tve67UTMSQ4tKq+L3sZ+n75ghmugJo17bYpVX/ZEqP5W/KYEoGXeWE3/hw==",
"MTX": "Qg1fflVUG+sZfjWjrP1LvlFXO7FB12DnfCTvCU1GgR6mUdufwTRyAZECtfXKvbzosQnHAsy3sb4KRt+YamodEqOzdZlg+QVlGiV+Tnm685E=",
"Anti": "ANB5Wg7NpGOSoPE9CPwnbTe0NNhYscju0B1jWMAv1670pcVE1iPUxRqLHjsRYO7avPNGz8m+ag2hcXFF2p5nHg==",
"Anti_process": "jp7Yt8T/KJr62V/Vj8WbipMo6UPVYkZNjKYJPiMhEUjwgqvR4Jlogpg7w3pNm5oKAKJxEOsIB3zhZxrHYaz0cg==",
"Pastebin": "Oi9x4/vUoRorHNgF4zofqBMP+H5bwYNM8Zwb2USs8i93No3lE5ySdR+pe7f36fRhzZNrVAr+2RQvDI86Jg5Nkw==",
"BDOS": "KesByLczwA3qZfXKAk61W+FaiA2UYTB/deTkOPHsy84J3BD826X0V00JoeDX9yFozzgvT3Egz54RSpHYS6AXzA==",
"Group": "2IAJvkc+nIX3STcyCydIZwKg4+71FP7JEGgFm0m4BbAkQO9hI9O6cVY2R0BQByL+7f5L3lsyIcYp7BDLoFIIsA==",
}

key = b64decode(key)
dec_key = pbkdf2_hmac("sha1", key, salt, 50000, 32)

for k, v in config.items():
data = b64decode(v)
iv = data[32:48]
decrypted = unpad(aes.cbc.decrypt(dec_key, iv, data[48:]))
#print("{}: {}".format(k, decrypted.decode("utf-8")))
print("{}: {}".format(k, decrypted.decode("utf-8", errors="ignore")))

La única complicación que podemos tener es encontrar el Salt. Para ello realizamos un grep de lo siguiente:
$ grep -R Rfc2898DeriveBytes *
XzgUWcJZDlpjQi/IKYaxvjpzNF.cs: using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(jWUckzASepqH, IKYaxvjpzNF.EmnIqkUAJWA, 50000))

Y tenemos que en este fichero  XzgUWcJZDlpjQi/IKYaxvjpzNF.cs  estaría lo que buscamos.
Lo probamos y obtendremos el  Command and Control:
$ python3 asyncrat_decrypt.py
Ports: 2727
Hosts: mono2024.kozow.com
Version: | Edit 3LOSH RAT
Install: false
MTX: AsyncMutex_6SI8OkPnk
Anti: false
Anti_process: true
Pastebin: null
BDOS: false
Group: Default

Y como siempre, ¿Cómo podemos detectar este troyano?
Con la regla de CAPE se detecta perfectamente
rule AsyncRat
{
meta:
author = "kevoreilly, JPCERT/CC Incident Response Group"
description = "AsyncRat Payload"
cape_type = "AsyncRat Payload"
strings:
$salt = {BF EB 1E 56 FB CD 97 3B B2 19 02 24 30 A5 78 43 00 3D 56 44 D2 1E 62 B9 D4 F1 80 E7 E6 C3 39 41}
$b1 = {00 00 00 0D 53 00 48 00 41 00 32 00 35 00 36 00 00}
$b2 = {09 50 00 6F 00 6E 00 67 00 00}
$string1 = "Pastebin" ascii wide nocase
$string2 = "Pong" wide
$string3 = "Stub.exe" ascii wide
$kitty = "StormKitty" ascii
condition:
uint16(0) == 0x5A4D and not $kitty and ($salt and (2 of ($str*) or 1 of ($b*))) or (all of ($b*) and 2 of ($str*))
}

Lo probamos:
$ yara AsyncRat.yar .
AsyncRat ./400000.MSBuild.exe

Ahora ya conocemos un poco mejor este troyano, espero que os haya gustado y nos vemos en el siguiente post.
¡¡Hasta otra!!

Top News