Backdoor on Node.js: por qué, por qué y cómo funciona

Recientemente, colegas de Yandex compartieron con nosotros una muestra de un troyano interesante, que informamos en esta noticia. Tal malware no aparece con frecuencia, por lo que decidimos desarmarlo con más detalle y, al mismo tiempo, hablar sobre por qué raramente encontramos tales muestras.

El troyano es una puerta trasera de múltiples componentes escrita en JavaScript y que utiliza Node.js. para ejecutarla. Sus elementos principales son el trabajador y el actualizador, que el gestor de arranque descarga e instala en el sistema. La carga útil puede ser cualquiera, pero en este caso, el troyano instala el minero xmrig. En el momento del estudio, el desarrollador utilizó el minero para extraer la criptomoneda TurtleCoin.

MonsterInstall se distribuye a través de sitios con trucos para videojuegos populares. La mayoría de estos recursos pertenecen al desarrollador del troyano, pero encontramos varios archivos infectados más en otros sitios similares. El propietario de uno de ellos monitorea regularmente las actualizaciones de los competidores y repone su recurso con contenido nuevo. Para hacer esto, usa el script parser.php, que a través de un proxy busca nuevos trucos en cheathappens.com.

Proxy parse done, total: 1 Use sox 84.228.64.133:1080 Error: CURL error(#52), attempts left: 10 Use sox 84.228.64.133:1080 Posts found: 30! [33mPage Satisfactory: ўЂµ№ЅµЂ +8 vCL#96731 {CheatHappens.com} already in base[0m [33mPage Borderlands: The Pre-Sequel - ўЂµ№ЅµЂ +28 v1.2019 {LinGon} already in base[0m [33mPage Borderlands - Game of the Year Enhanced: ўЂµ№ЅµЂ +19 v1.0.1 {LinGon} already in base[0m [33mPage Star Wars: Battlefront 2 (2017): ўЂµ№ЅµЂ +4 v01.04.2019 {MrAntiFun} already in base[0m [36mPage Far Cry 5: ўЂµ№ЅµЂ +23 v1.012 (+LOST ON MARS/DEAD LIVING ZOMBIES) {CheatHappens.com} added 2019-Apr-09[0m [36mPage Fate/Extella Link: ўЂµ№ЅµЂ +13 v04.09.2019 {CheatHappens.com} added 2019-Apr-09[0m [36mPage Superhot: ўЂµ№ЅµЂ +3 v2.1.01p { MrAntiFun} added 2019-Apr-09[0m [36mPage Dawn of Man: ўЂµ№ЅµЂ +7 v1.0.6 {CheatHappens.com} added 2019-Apr-08[0m [36mPage Borderlands 2: ўЂµ№ЅµЂ +14 v06.04.2019 {MrAntiFun} added 2019-Apr-08[0m [36mPage Borderlands: The Pre-Sequel - ўЂµ№ЅµЂ +17 v06.04.2019 {MrAntiFun} added 2019-Apr-08[0m [36mPage Tropico 6: ўЂµ№ЅµЂ +9 v1.01 {MrAntiFun} added 2019-Apr-08[0m [36mPage Operencia: The Stolen Sun - ўЂµ№ЅµЂ +20 v1.2.2 {CheatHappens.com} added 2019-Apr-08[0m [36mPage Enter the Gungeon: ўЂµ№ЅµЂ +6 v2.1.3 {MrAntiFun} added 2019-Apr-07[0m [36mPage The Guild 3: ўЂµ№ЅµЂ +2 v0.7.5 {MrAntiFun} added 2019-Apr-07[0m [36mPage Dead Effect 2: ўЂµ№ЅµЂ +8 v190401 {MrAntiFun} added 2019-Apr-07[0m [36mPage Assassin's Creed: Odyssey - ўЂµ№ЅµЂ +26 v1.2.0 {FLiNG} added 2019-Apr-07[0m [36mPage Assassin's Creed: Odyssey - ўЂµ№ЅµЂ +12 v1.2.0 {MrAntiFun} added 2019-Apr-06[0m [36mPage Super Dragon Ball Heroes: World Mission - ўЂµ№ЅµЂ +11 v1.0 {FLiNG} added 2019-Apr-05[0m [36mPage Tropico 6: ўЂµ№ЅµЂ +7 v1.02 97490 {CheatHappens.com} added 2019-Apr-05[0m [36mPage Risk of Rain 2: ўЂµ№ЅµЂ +10 Build 3703355 {CheatHappens.com} added 2019-Apr-05[0m [36mPage Sid Meier's Civilization 6 - Rise and Fall: ўЂµ№ЅµЂ +12 v1.0.0.314 {MrAntiFun} added 2019-Apr-05[0m [36mPage Sid Meier's Civilization 6 - Gathering Storm: ўЂµ№ЅµЂ +12 v1.0.0.314 {MrAntiFun} added 2019-Apr-05[0m [36mPage Sid Meier's Civilization 6: ўЂµ№ЅµЂ +12 v1.0.0.314 {MrAntiFun} added 2019-Apr-05[0m [36mPage Borderlands GOTY Enhanced: ўЂµ№ЅµЂ +16 v1.0 {CheatHappens.com} added 2019-Apr-05[0m [36mPage Borderlands Game of the Year Enhanced: ўЂµ№ЅµЂ +13 v1.00 {MrAntiFun} added 2019-Apr-04[0m [36mPage Assassin's Creed: Odyssey: ўЂµ№ЅµЂ +24 v1.2.0 (04.04.2019) {CheatHappens.com} added 2019-Apr-04[0m [36mPage Sekiro: Shadows Die Twice - ўЂµ№ЅµЂ +24 v1.02 {FLiNG} added 2019-Apr-04[0m [36mPage Hearts of Iron 4: ўЂµ№ЅµЂ +24 v1.6.2 {MrAntiFun} added 2019-Apr-04[0m [36mPage Wolcen: Lords of Mayhem - ўЂµ№ЅµЂ +5 v1.0.2.1 {MrAntiFun} added 2019-Apr-04[0m [36mPage Devil May Cry 5: ўЂµ№ЅµЂ +18 v1.0 (04.03.2019) {CheatHappens.com} added 2019-Apr-04[0m Parse done 


En los sitios del desarrollador hay una gran selección de trucos, pero se devolverá el mismo archivo para todos los enlaces. Si intenta descargar cualquiera de los archivos del sitio de malware, el usuario recibirá Trojan.MonsterInstall. Algunos parámetros del troyano se pueden adivinar desde el enlace de descarga:

 https://<malicious_site>/fc/download.php?name=Borderlands%20GOTY%20Enhanced:%20%D0%A2%D1%80%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%20+16%20v1.0%20{CheatHappens.com}&link=https://<malicious_site>//r.php?site=http://gtrainers.com/load/0-0-1-7081-20&password=<malicious_site>/&uid=101&sid1=1&sid2=1&charset=utf-8 

  • nombre: el nombre del archivo y exe en el archivo;
  • enlace: un enlace al archivo que el usuario quería descargar (está conectado en data.json);
  • contraseña: contraseña para el archivo.

Supongamos que seleccionamos el truco deseado y descargamos el archivo 7zip protegido con contraseña con el prometedor nombre "ExtrimHack.rar" del sitio del desarrollador del troyano. En su interior hay un archivo ejecutable, un archivo de configuración, una biblioteca 7zip, así como un archivo bin con bibliotecas y scripts nativos de C ++ lanzados utilizando el binario Node.js.

Ejemplo de contenido de archivo:

  • 7z.dll;
  • data.bin;
  • data.json;
  • Truco ESP para COP GO.exe.


Cuando se inicia el ejecutable, el troyano instalará todos los componentes necesarios para su funcionamiento, y también descargará el truco necesario para el usuario, utilizando la información del archivo data.json con parámetros.

Contenido de ejemplo de data.json:
 {"source":[5,10,11,43],"dataVersion":[0,0,0,115],"link":"http:\/\/clearcheats.ru\/images\/dl\/csgo\/ESP_csgo.dll"} 


Para excluir el funcionamiento de varias copias de su proceso, el troyano crea el mutex "cortelMoney-suncMutex" y lo instala en el directorio "% WINDIR% \ WinKit \". Luego verifica si está en el registro ([HKLM \\ Software \\ Microsoft \\ Windows Node]). Si es así, lee sus parámetros y compara la versión con la especificada en data.json. Si la versión es actual, no hace nada más y termina.

Después de eso, el troyano desempaqueta el contenido de data.bin en% WINDIR% \\ WinKit \\ e instala el servicio para iniciar start.js.

Contenido de data.bin:
  • Demonio;
  • nodo_módulos;
  • 7z.dll;
  • msnode.exe;
  • start.js;
  • startDll.dll;
  • update.js;
  • updateDll.dll.

Al mismo tiempo, msnode.exe es un archivo ejecutable Node.js con una firma digital válida, y el directorio node_modules contiene las bibliotecas "ffi", "node-windows" y "ref".

La biblioteca startDll.dll se carga en start.js y se llama a su exportación principal, en la que lee sus parámetros del registro, inicia "% WINDIR% \\ WinKit \\ msnode% WINDIR% \\ WinKit \\ update.js" y detiene el servicio "Nodo de Windows". El script update.js, a su vez, carga la biblioteca updateDll.dll y llama a su exportación mymain. Nada complicado

En updateDll.dll, el troyano comenzará a verificar su conexión a Internet. Para hacer esto, enviará solicitudes a google.com, yahoo.com, facebook.com cada 10 segundos, hasta que los tres devuelvan el código 200. Luego enviará una solicitud con datos de configuración al servidor POST s44571fu [.] Bget [.] Ru / CortelMoney / enter.php:

 {"login":"NULL","mainId":"PPrn1DXeGvUtzXC7jna2oqdO2m?WUMzHAoM8hHQF","password":"NULL","source":[0,0,0,0],"updaterVersion":[0,0,0,0],"workerVersion":[0,0,0,0]} 


En este caso, para la autorización básica, se utiliza un par de "cortel: money" y el User-Agent se establece en "USER AGENT". Para la autorización básica de solicitudes posteriores, se utilizará login: contraseña, que será informada por el servidor.

El servidor responde con json así:

 { "login": "240797", "password": "tdzjIF?JgEG5NOofJO6YrEPQcw2TJ7y4xPxqcz?X", "updaterVersion": [0, 0, 0, 115], "updaterLink": "http:\/\/s44571fu.bget.ru\/CortelMoney\/version\/0-0-0-115-upd.7z", "workerVersion": [0, 0, 3, 0], "workerLink": "http:\/\/s44571fu.bget.ru\/CortelMoney\/version\/0-0-3-0-work.7z" } 


Como puede ver, la respuesta del servidor contiene versiones de los elementos principales del troyano. Si la versión actual del actualizador en el dispositivo del usuario es anterior a la informada por el servidor, el troyano descarga el archivo desde el enlace especificado y desempaqueta el archivo en el directorio "% WINDIR% \\ WinKit \\\\", donde se indicará el valor del parámetro UpdaterVersion de la respuesta del servidor .

El troyano desempaqueta el archivo de trabajo en el directorio% WINDIR% \\ WinKit \\ SystemNode \\, y luego lanza "% WINDIR% \\ WinKit \\ SystemNode \\ sysnode% WINDIR% \\ WinKit \\ SystemNode \\ main.js".

El contenido del archivo con el trabajador:
  • nodo_módulos;
  • 7za.exe;
  • códice
  • main.js;
  • sysnode.exe.

Luego, el troyano elimina el servicio de protección de nodo de Windows y luego lo crea nuevamente, reemplazando el archivo ejecutable con el archivo de servicio de nodo de Windows. Del mismo modo, vuelve a crear el servicio Nodo de Windows, reemplazando el ejecutable con daemon \\ service.exe.

A continuación se forman service.xml con parámetros:
 <service><id>service.exe</id><executable>C:\Windows\\WinKit\0.0.0.115\msnode.exe</executable><arguments>"C:\Windows\\WinKit\0.0.0.115\start.js"</arguments></service> 


Updater se instala en el directorio "C: \ Windows \ Reserve Service", registrado por el servicio e iniciado por el binario Node.js. También consta de varios scripts js y bibliotecas nativas de C ++. El módulo principal es main.js.

El contenido del archivo con el actualizador:
  • main.js;
  • start.js;
  • crypto.dll;
  • network.dll;
  • service.exe.

En primer lugar, el troyano sabrá la fecha actual enviando una solicitud a google.com, yandex.ru o www.i.ua. Utiliza la información recibida un poco más tarde. Luego descifra el contenido del archivo bootList.json usando la biblioteca crypto.dll.

Algoritmo de descifrado:
 key = '123' s = '' for i in range(len(d)): s += chr((ord(d[i]) - ord(key[i % len(key)])) & 0xff) 


Obtiene una lista de servidores de administración desde allí:
 [{"node":"http://cortel8x.beget.tech/reserve","weight":10},{"node":"http://reserve-system.ru/work","weight":10}] 


Luego, el troyano lee información del registro:
 function getInfo() { var WindowsNodeInfo = new Object(); WindowsNodeInfo.mainId = windowsLib.getStringRegKey("HLM\\SOFTWARE\\Microsoft\\Windows Node", "mainId"); WindowsNodeInfo.login = windowsLib.getStringRegKey("HLM\\SOFTWARE\\Microsoft\\Windows Node", "log"); WindowsNodeInfo.password = windowsLib.getStringRegKey("HLM\\SOFTWARE\\Microsoft\\Windows Node", "pass"); WindowsNodeInfo.source = windowsLib.getStringRegKey("HLM\\SOFTWARE\\Microsoft\\Windows Node", "source"); WindowsNodeInfo.updaterVersion = windowsLib.getStringRegKey("HLM\\SOFTWARE\\Microsoft\\Windows Node", "updaterVersion"); WindowsNodeInfo.workerVersion = windowsLib.getStringRegKey("HLM\\SOFTWARE\\Microsoft\\Windows Node", "workerVersion"); var ReserveSystemInfo = new Object(); ReserveSystemInfo.workerVersion = windowsLib.getStringRegKey("HLM\\SOFTWARE\\Microsoft\\Reserve System", "updaterVersion"); var myInfo = new Object(); myInfo.windowsNode = WindowsNodeInfo; myInfo.reserveSystem = ReserveSystemInfo; return JSON.stringify(myInfo); } 

Luego agrega el encabezado HTTP de la autorización básica correspondiente al par "cortel: money", y lo envía con una solicitud POST al servidor de administración previamente descifrado.
En respuesta, el servidor recibe:

 { "data": { "updaterVersion": [0, 0, 0, 1], "updaterLink": "/upd.7z", "updaterVerify": "£ñß(\u0012Ä\ti¾$ë5ž»\u001c²\u001c\fÙ=±÷ö‚´èUnŽÐÂBÔ\n\u001dW6?u½\u0005Œn\u000fp:üÍ\u0019\u0000\u000bSý«\u00137÷\u0013”'ì¥û§s7F\u0016ó\\\u000f%6ñê\"7î<ýo䃃0Æ%t ñÅv‚S¡\r\u001e•ÅÆ¡¿N)v\\f8\u0004F\fUS¯‰³§ oIõŒiÆîGݪ\u0017êH/8Ö1-°™[P 5E7X‡Fø%S ŠXÕ6Oþ=Vô‰…ˆ:.3Œ‚i\u000eÁù9Ã&¾ŒM\u001eÛªé$\u0006#IèÞÛ\u0018À\u001b^è,ÁòÑCTXb\u001d$ç\u0004„ð¶0UVÕ»e\u001f\b\u001e¡Ä¼è+Fjúÿoâz\r !çô3xØs—_\u000b\u0017\u001fY]\u0001¥j^û\\W", "dateTime": 1534868028000, "bootList": [{ "node": "http://cortel8x.beget.tech/reserve/", "weight": 10 }, { "node": "http://reserve-system.ru/work/", "weight": 10 }] }, "dataInfo": "I`ù@ÀP'ÈcÊÛ´#iè Ò~\u0007<\u0001Ýìûl«ÔÆq\u0013àÛ\u0003\b\u0017ÑLÁ}ÿÚ˜DS']\u0003bf\u0003!¿Cð¸q¸ÖÜ'B¢CÄAMˆÀA¤d\u001c5¨d -\u0013‰\u0011ѼF'|SB[¬°(ܹÈÒÜ £L\u00071¾:`\u001bŒìýKõ\"²Ÿ¸$´3™UºÅ¨J†¨cƒf¿}r;Öeì¶x‰ØKt¥‹„47a\u001e¸Ô‡ˆy\u0006•\u001b\u0004‚‹„„•ó\u001a\u0019\nu>¨)bkæ…'\u00127@é‹7µæy3ÈNrS'Mð‡\u0018\u0019¾òÓ[Žå5H‡ƒ·¦k'¿ÉŠ&PÂÈîåÚ~M\u0010ðnáH擪xÃv cד\u0013…T…ïÑÝ\tœŽ\u0018†Æ\u00148$”Ôî" } 


Y aquí viene la fecha actual, obtenida anteriormente. El troyano lo compara con el parámetro dataTime pasado por el servidor. Si la diferencia entre las fechas es más de una semana (en términos de milisegundos), el troyano no ejecutará los comandos. El parámetro dataInfo también contiene la firma de datos (campo de datos), se verifica utilizando la clave pública cableada en main.js. Y el parámetro "bootList" contiene una lista de servidores, que el troyano cifra y almacena en "bootList.json".

Después de eso, el troyano compara su versión con la especificada en el parámetro UpdaterVersion. Si la versión instalada no es inferior a la última, el troyano lanza "upd \\ upd.exe" pasando el parámetro "main.js". Si la versión de la respuesta del servidor es más reciente, el troyano descarga el archivo de actualización desde el enlace "UpdaterLink" upd.7z, comprueba su firma y lo desempaqueta. Luego escribe en el registro la versión de la actualización [HKLM \\ SOFTWARE \\ Microsoft \\ Reserve System] 'UpdaterVersion', después de lo cual lanza nuevamente "upd \\ upd.exe", pasándolo con el parámetro "main.js".

El trabajador del troyano comprueba que uno de los componentes ya se ha instalado y toma decisiones sobre si instalar aplicaciones. Primero, crea el mutex MoonTitleWorker, luego descifra el archivo codeX con un XOR con la cadena "xor" y lo ejecuta. Después de eso se forma json con información:
 {"userId": id, "starter": [], "worker": [], "source": [], "osInfo": {"isX64": True, "osString": "Windows 7 Enterprise"}} 

Envía esta información con una solicitud POST a http: // <malicious_site> [.] Xyz: 1001 / getApps (en aras de la decencia, no especificamos un nombre de dominio, pero se puede encontrar aquí ). La respuesta del servidor puede contener información sobre las aplicaciones que deben instalarse.

Ejemplo de respuesta:
 { "body": { "apps": [{ "hash": "452f8e156c5c3206b46ea0fe61a47b247251f24d60bdba31c41298cd5e8eba9a", "size": 8137466, "version": [2, 0, 0, 2], "link": "xmr-1-64.7z", "path": "%pf%\\Microsoft JDX\\64", "runComand": "%path%\\moonlight.exe start.js", "name": "xmr64" }] }, "head": "O~¨^Óå+ßzIçsG¬üS„ʶ$êL–LùθZ\f\u0019ÐÐ\u000e \u0004\u001cÀU¯\u0011š)áUÚ\u001flß²A\u001fôÝÔ숱y%\"DP» ^¯«FUâ\u001cÔû\u001dµ´Jï#¬ÌȹÎÚª?\r—]Yj·÷õ³—\u001e°ÖÒ\\鉤d'BT\u0019·¦FõVQ°Aç')\u001cõªµ¦ýûHlb͸þ}éŒ\u0000jvÔ%S;Ã×þA\u0011ß'I[´\u0004ýÚ\u0007Z:ZÂ\n–ñz#ÈBö›²2\u0007ÎJw±èTVoŸå\bÖR3½ù;ƒó\u0011ÉÌ€ÅÖàð06ÓeÕþˆ”7Ùš\u0011•»”˜¢5µgôÛc˜&L\u000fê.?!Çæ}¨\u001eÕ—J#A¼_Ì\u0015càñb" } 

Si el dispositivo no tiene dicha aplicación, el troyano la descarga enviando una solicitud POST a la URL http: // <malicious_site> [.] Xyz: 1001 /, donde se indicará el parámetro de enlace para la aplicación correspondiente desde la respuesta del servidor. Si existe tal aplicación, pero una versión anterior, se actualiza a la actual.

El troyano verifica el tamaño y el hash del archivo descargado con la información especificada por el servidor en los parámetros de hash y tamaño. Si los datos convergen, mueve el archivo a lo largo de la ruta desde el parámetro de ruta y ejecuta el comando especificado en el campo runCommand. La información sobre la aplicación descargada se almacena en el registro [HKLM \\ SOFTWARE \\ Microsoft \\ MoonTitle \\ apps \\].

En este momento, el minero xmrig se está configurando utilizando la puerta trasera. Dependiendo de la capacidad del sistema, el troyano descarga un archivo xmr-1.7z o xmr-1-64.7z. En start.js, carga la biblioteca xmrig.dll y llama a mymain export, donde implementa sus variables de entorno y elimina los procesos:
  • % sys32_86% \\ xmr;
  • % sys32_86% \\ xmr64;
  • % pf_86% \\ Microsoft JDX \\ 32 \\ windows-update.exe;
  • % pf_86% \\ Microsoft JDX \\ 64 \\ windows-update.exe.

Si el archivo xmrig.exe se encuentra cerca, el troyano lo carga en la memoria del proceso actual, borra la firma MZ, lo descifra usando XOR con 0x39 y luego guarda su volcado en el archivo de volcado. Si el troyano encuentra el archivo "volcado" en el mismo directorio, lo descifra de la misma manera, inicia windows-update.exe e incrusta la carga útil descifrada en él.

El troyano recopila y envía por solicitud POST a la URL: cherry-pot [.] Top / RemoteApps / xmr / main.php la siguiente información del sistema: {"action": "enter", "architecture": "INTEL", "cpuAES" : verdadero, "cpuCache": 8192, "cpuSpeed": 3392.0, "cpuThreads": 2, "cpuVendorString": "Intel® Core (TM) i5-4690S CPU @ 3.20GHz \ u0000", "hightPages": falso, " login ":" nulo "," contraseña ":" nulo "," ramPhysicalSize ": 3071," xmrigVersion ": [2,10,0]}

En respuesta, el servidor envía la configuración del minero:
 {"maxCpuLoad":1000,"minCpuLoad ":0,"algo":"cryptonight-pico/trtl","av":0,"background":false,"donate-level":1,"max-cpu-usage":75,"retries":5,"retry-pause":5,"cpu-priority":1,"pools":[{"url":"185.224.133.91:5511","keepalive":true,"nicehash":true}]} 

Después de que el troyano guarda la configuración en config.json, se iniciará automáticamente y comenzará a minar.

MonsterInstall tiene otras modificaciones. Por ejemplo, además de los trucos para juegos, el desarrollador de Malvari lo distribuyó bajo la apariencia de un instalador de navegador Chrome y un programa para verificar archivos. En versiones posteriores del troyano, el desarrollador pensó en la seguridad y agregó el cifrado de cadenas, así como la necesidad de ingresar una contraseña para algunos archivos. Además, el gestor de arranque de una de las versiones del troyano incluso tiene un enlace a un acuerdo de licencia alojado en el dominio del desarrollador del troyano.

(Desafortunadamente, las preguntas sobre la fuerza legal de tales acuerdos están más allá del alcance de este artículo, pero si le interesa leer material sobre este tema, háganoslo saber en los comentarios).

Conclusiones

Node.js no es la solución más práctica para los creadores de virus. Si el tamaño de dicho troyano puede ser pequeño, entonces el enlace Node.js (archivo ejecutable y bibliotecas) será significativamente "más pesado" que el malvari estándar. ¿Qué dicta esta elección? Como regla general, los desarrolladores eligen herramientas con las que están familiarizados. Por lo tanto, incluso en el caso de los criadores, la elección de la tecnología es más una cuestión de preferencia personal. Sin embargo, Node.js tiene sus ventajas, una de las cuales es una firma válida. En el sistema, dicho proceso se firmará como Node.js, lo que rara vez genera sospechas.

En resumen, se puede observar que, a pesar de la interesante elección de herramientas, esto no le dio al desarrollador de puerta trasera ninguna ventaja significativa. Es poco probable que en el futuro veamos más malware utilizando Node.js.

Como de costumbre, compartimos indicadores de compromiso .

Source: https://habr.com/ru/post/460255/


All Articles