Backdoor no Node.js: por que, por que e como funciona

Recentemente, colegas da Yandex compartilharam conosco uma amostra de um Trojan interessante, que relatamos nesta notícia. Esse malware não é encontrado com frequência, por isso decidimos desmontá-lo com mais detalhes e, ao mesmo tempo, falar sobre por que raramente encontramos esses exemplos.

O Trojan é um backdoor de múltiplos componentes, escrito em JavaScript e usando o Node.js. para executá-lo. Seus principais elementos são trabalhador e atualizador, que são baixados e instalados no sistema pelo gerenciador de inicialização. A carga útil pode ser qualquer, mas, neste caso, o Trojan instala o xmrig miner. Na época do estudo, o desenvolvedor usou o mineiro para minerar a criptomoeda TurtleCoin.

O MonsterInstall é distribuído através de sites com truques para videogames populares. A maioria desses recursos pertence ao desenvolvedor do Trojan, mas encontramos vários outros arquivos infectados em outros sites semelhantes. O proprietário de um deles monitora regularmente as atualizações dos concorrentes e reabastece seus recursos com novos conteúdos. Para fazer isso, ele usa o script parser.php, que, por meio de um proxy, procura por novos truques no 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 


Nos sites dos desenvolvedores, há uma grande variedade de truques, mas o mesmo arquivo será retornado para todos os links. Se você tentar baixar qualquer um dos arquivos do site de malware, o usuário receberá o Trojan.MonsterInstall. Alguns parâmetros do Trojan podem ser adivinhados no link de download:

 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 

  • nome - o nome do arquivo e exe no arquivo;
  • link - um link para o arquivo que o usuário queria baixar (está conectado em data.json);
  • senha - senha do arquivo morto.

Suponha que selecione a fraude desejada e baixe o arquivo 7zip protegido por senha com o nome promissor "ExtrimHack.rar" no site do desenvolvedor do Trojan. Dentro dele, há um arquivo executável, um arquivo de configuração, uma biblioteca 7zip e um arquivo bin com bibliotecas C ++ nativas e scripts lançados usando o binário Node.js.

Exemplo de conteúdo de arquivo:

  • 7z.dll;
  • data.bin;
  • data.json;
  • Fraude do ESP para o COP GO.exe.


Quando o executável é iniciado, o Trojan instala todos os componentes necessários para sua operação e também baixa as dicas necessárias para o usuário, usando as informações do arquivo data.json com parâmetros.

Exemplo de conteúdo 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 várias cópias do processo, o Trojan cria o mutex "cortelMoney-suncMutex" e o instala no diretório "% WINDIR% \ WinKit \". Em seguida, verifica se está no registro ([HKLM \\ Software \\ Microsoft \\ Windows Node]). Nesse caso, ele lê seus parâmetros e compara a versão com a especificada em data.json. Se a versão é atual, ela não faz mais nada e termina.

Depois disso, o Trojan descompacta o conteúdo do data.bin em% WINDIR% \\ WinKit \\ e instala o serviço para iniciar o start.js.

Conteúdo de data.bin:
  • Daemon;
  • node_modules;
  • 7z.dll;
  • msnode.exe;
  • start.js;
  • startDll.dll;
  • update.js;
  • updateDll.dll.

Ao mesmo tempo, msnode.exe é um arquivo executável Node.js com uma assinatura digital válida e o diretório node_modules contém as bibliotecas "ffi", "node-windows" e "ref".

A biblioteca startDll.dll é carregada em start.js e sua exportação mymain é chamada, na qual lê seus parâmetros no registro, inicia "% WINDIR% \\ WinKit \\ msnode% WINDIR% \\ WinKit \\ update.js" e interrompe o serviço "Nó do Windows". O script update.js, por sua vez, carrega a biblioteca updateDll.dll e chama sua exportação mymain. Nada complicado.

No updateDll.dll, o Trojan começará a verificar sua conexão com a Internet. Para fazer isso, ele enviará solicitações para google.com, yahoo.com, facebook.com a cada 10 segundos, até que os três retornem o código 200. Em seguida, ele enviará uma solicitação com os dados de configuração ao servidor POST s44571fu [.] Bget [.] Ru / CortelMoney / enter.php POST:

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


Ao mesmo tempo, um par de "cortel: money" é usado para autorização básica e o USER AGENT é definido como User-Agent. Para autorização básica de solicitações subsequentes, será utilizado o login: senha, que será relatado pelo servidor.

O servidor responde com json assim:

 { "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 você pode ver, a resposta do servidor contém versões dos principais elementos do Trojan. Se a versão atual do atualizador no dispositivo do usuário for mais antiga que a relatada pelo servidor, o Trojan fará o download do arquivo a partir do link especificado e descompacta o arquivo no diretório "% WINDIR% \\ WinKit \\\\", onde será indicado o valor do parâmetro updaterVersion da resposta do servidor .

O Trojan descompacta o arquivo de trabalho no diretório% WINDIR% \\ WinKit \\ SystemNode \\ e inicia "% WINDIR% \\ WinKit \\ SystemNode \\ sysnode% WINDIR% \\ WinKit \\ SystemNode \\ main.js".

O conteúdo do arquivo com o trabalhador:
  • node_modules;
  • 7za.exe;
  • codex;
  • main.js;
  • sysnode.exe.

O cavalo de Tróia remove o serviço Windows Node Guard e o cria novamente, substituindo o arquivo executável pelo arquivo de serviço Nó do Windows. Da mesma maneira, ele recria o serviço Nó do Windows, substituindo o executável pelo daemon \\ service.exe.

Próximos formulários service.xml com 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> 


O Updater é instalado no diretório "C: \ Windows \ Reserve Service", registrado pelo serviço e iniciado pelo binário Node.js. Ele também consiste em vários scripts js e bibliotecas C ++ nativas. O módulo principal é main.js.

O conteúdo do arquivo com o atualizador:
  • main.js;
  • start.js;
  • crypto.dll;
  • network.dll;
  • service.exe.

Primeiro de tudo, o Trojan saberá a data atual enviando uma solicitação para google.com, yandex.ru ou www.i.ua. Ele usa as informações recebidas um pouco mais tarde. Em seguida, descriptografa o conteúdo do arquivo bootList.json usando a biblioteca crypto.dll.

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


Obtém uma lista de servidores de gerenciamento a partir daí:
 [{"node":"http://cortel8x.beget.tech/reserve","weight":10},{"node":"http://reserve-system.ru/work","weight":10}] 


Em seguida, o Trojan lê as informações do 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); } 

Em seguida, adiciona o cabeçalho HTTP da autorização básica correspondente ao par "cortel: money" e envia-o com uma solicitação POST ao servidor de gerenciamento decriptografado anteriormente.
Em resposta, o servidor recebe:

 { "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$”Ôî" } 


E aqui vem a data atual, obtida anteriormente. O Trojan verifica o parâmetro dataTime passado pelo servidor. Se a diferença entre as datas for superior a uma semana (em milissegundos), o Trojan não executará os comandos. O parâmetro dataInfo também contém a assinatura de dados (campo de dados), é verificado usando a chave pública conectada em main.js. E o parâmetro "bootList" contém uma lista de servidores, que o Trojan criptografa e armazena em "bootList.json".

Depois disso, o Trojan verifica sua versão com a especificada no parâmetro updaterVersion. Se a versão instalada não for inferior à versão mais recente, o Trojan lançará “upd \\ upd.exe” passando o parâmetro “main.js”. Se a versão da resposta do servidor for mais recente, o Trojan baixa o arquivo de atualização usando o link do parâmetro updaterLink "upd.7z, verifica sua assinatura e descompacta. Em seguida, ele grava no registro a versão da atualização [HKLM \\ SOFTWARE \\ Microsoft \\ Reserve System] 'updaterVersion', após o qual lança novamente "upd \\ upd.exe", passando-o com o parâmetro "main.js."

O Trojan's Worker verifica se um dos componentes já foi instalado e toma decisões sobre a instalação de aplicativos. Primeiro, ele cria o mutex MoonTitleWorker, depois descriptografa o arquivo codeX com um XOR com a string "xor" e o executa. Depois disso, forma json com informações:
 {"userId": id, "starter": [], "worker": [], "source": [], "osInfo": {"isX64": True, "osString": "Windows 7 Enterprise"}} 

Envia essas informações com uma solicitação POST para http: // <malicious_site> [.] Xyz: 1001 / getApps (por uma questão de decência, não especificamos um nome de domínio, mas pode ser encontrado aqui .) A resposta do servidor pode conter informações sobre os aplicativos que precisam ser instalados.

Exemplo de resposta:
 { "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" } 

Se o dispositivo não tiver esse aplicativo, o Trojan o baixa enviando uma solicitação POST para o URL http: // <malicious_site> [.] Xyz: 1001 /, onde o parâmetro de link para o aplicativo correspondente da resposta do servidor será indicado. Se houver um aplicativo, mas uma versão mais antiga, ele será atualizado para o atual.

O Trojan verifica o tamanho e o hash do arquivo baixado com as informações especificadas pelo servidor nos parâmetros de hash e tamanho. Se os dados convergirem, ele moverá o arquivo ao longo do caminho a partir do parâmetro path e executará o comando especificado no campo runCommand. As informações sobre o aplicativo baixado são armazenadas no registro [HKLM \\ SOFTWARE \\ Microsoft \\ MoonTitle \\ apps \\].

No momento, o minerador xmrig está sendo configurado usando o backdoor. Dependendo da capacidade do sistema, o Trojan baixa um arquivo xmr-1.7z ou xmr-1-64.7z. No start.js, ele carrega a biblioteca xmrig.dll e chama mymain export, onde implementa suas variáveis ​​de ambiente e mata os processos:
  • % sys32_86% \\ xmr;
  • % sys32_86% \\ xmr64;
  • % pf_86% \\ Microsoft JDX \\ 32 \\ windows-update.exe;
  • % pf_86% \\ Microsoft JDX \\ 64 \\ windows-update.exe.

Se o arquivo xmrig.exe estiver localizado próximo, o Trojan o carrega na memória do processo atual, apaga a assinatura MZ, descriptografa-a usando o XOR com 0x39 e salva seu despejo no arquivo de despejo. Se o cavalo de Tróia encontrar o arquivo "dump" no mesmo diretório, descriptografá-lo da mesma maneira, iniciar o windows-update.exe e incorporar a carga descriptografada nele.

O Trojan coleta e envia por solicitação POST para o URL: cherry-pot [.] Top / RemoteApps / xmr / main.php as seguintes informações do sistema: {"action": "enter", "architecture": "INTEL", "cpuAES" : true, "cpuCache": 8192, "cpuSpeed": 3392.0, "cpuThreads": 2, "cpuVendorString": "CPU Intel® Core (TM) i5-4690S a 3,20GHz \ u0000", "hightPages": false ", login ":" nulo "," senha ":" nulo "," ramPhysicalSize ": 3071," xmrigVersion ": [2,10,0]}

Em resposta, o servidor envia a configuração do mineiro:
 {"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}]} 

Depois que o Trojan salva a configuração no config.json, ele inicia e inicia automaticamente a mineração.

MonsterInstall tem outras modificações. Por exemplo, além de truques para jogos, o desenvolvedor do Malvari o distribuiu sob o disfarce de um instalador do navegador Chrome e um programa para verificar arquivos. Nas versões posteriores do cavalo de Troia, o desenvolvedor pensou em segurança e adicionou criptografia de cadeias, bem como a necessidade de inserir uma senha para alguns arquivos. Além disso, o carregador de inicialização de uma das versões do Trojan ainda possui um link para um contrato de licença hospedado no domínio do desenvolvedor do Trojan.

(Perguntas sobre a força legal de tais acordos, infelizmente, estão além do escopo deste artigo, mas se você estiver interessado em ler material sobre este tópico, informe-nos nos comentários).

Conclusões

O Node.js não é a solução mais prática para criadores de vírus. Se o tamanho desse Trojan puder ser pequeno, a ligação do Node.js. (arquivo e bibliotecas executáveis) será significativamente mais "pesada" do que o malvari padrão. O que ditou essa escolha? Como regra, os desenvolvedores escolhem ferramentas com as quais estão familiarizados. Portanto, mesmo no caso dos criadores, a escolha da tecnologia é mais uma questão de preferência pessoal. No entanto, o Node.js tem suas vantagens, uma das quais é uma assinatura válida. No sistema, esse processo será assinado como Node.js, o que raramente levanta suspeitas.

Resumindo, pode-se notar que, apesar da interessante escolha de ferramentas, isso não deu ao desenvolvedor de backdoor nenhuma vantagem significativa. É improvável que, no futuro, veremos mais malware usando o Node.js.

Como sempre, compartilhamos indicadores de compromisso .

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


All Articles