box.js – Uma ferramenta para estudar o malware JavaScript

Um utilitário para analisar JavaScript malicioso. 

Instalação
Simplesmente instale o box-js a partir do npm:

npm install box-js --global

Uso
 Olhando para usar box-js com Cuckoo? Use 

cuckoo-package.pycomo um pacote de 

análise .Digamos que você tenha uma amostra chamada sample.js: para analisá-la, basta executar

box-js sample.js

Provavelmente, você também desejará fazer o download de quaisquer cargas úteis; use a bandeira --downloadpara ativar o download. Caso contrário, o mecanismo simulará um erro 404, para que o script seja levado a pensar que o site de distribuição está inoperante e entrar em contato com os sites de fallback. 
O Box.js emulará um ambiente Windows JScript, imprimirá um resumo da emulação no console e criará uma pasta chamada sample.js.results(se ela já existir, será criada sample.js.1.resultse assim por diante). Esta pasta conterá:

  • analysis.log, um log da análise impressa na tela;
  • uma série de arquivos identificados por UUIDs;
  • snippets.json, uma lista de trechos de código executados pela amostra (JavaScript, comandos de shell etc.);
  • urls.json, uma lista de URLs contatados;
  • active_urls.json, uma lista de URLs que parecem eliminar malware ativo;
  • resources.json, os fluxos ADODB (ou seja, os arquivos que o script gravou no disco) com tipos e hashes de arquivo;
  • IOC.json, uma lista de comportamentos identificados como COI (indicadores de compromisso). Isso inclui acessos ao registro, arquivos gravados, solicitações HTTP e assim por diante.

Você pode analisá-las sozinho ou enviá-las automaticamente para o Malwr, VirusTotal ou uma caixa de proteção Cuckoo: para obter mais informações, execute box-export --help.
 Para um isolamento adicional, é recomendável executar a análise em um contêiner temporário do Docker. Consulte 

integrations/README.mdpara mais informações. Se você deseja automatizar a análise, pode usar os códigos de retorno – documentados em 

integrations/README.md– para distinguir entre diferentes tipos de erros.
Uso em lote
Embora o box.js seja normalmente usado em arquivos únicos, ele também pode executar análises em lote. Você pode simplesmente passar uma lista de arquivos ou pastas para analisar:

box-js sample1.js sample2.js /var/data/mySamples ...

Por padrão, o box.js processa amostras em paralelo, executando uma análise por núcleo. Você pode usar uma configuração diferente especificando um valor para --threads: em particular, 0 removerá o limite, fazendo o box-js gerar o maior número possível de threads de análise e resultando em uma análise muito rápida, mas possivelmente sobrecarregando o sistema (observe que as análises geralmente são de CPU -bound , não RAM-bound). 
Você pode usar --loglevel=warnpara silenciar mensagens relacionadas à análise e exibir apenas informações de progresso. 
Após a conclusão da análise, você pode extrair os URLs ativos assim:

cat ./*.results/active_urls.json | sort | uniq

Bandeiras

NAME                   DESCRIPTION                                                                     
-h, --help             Show the help text and quit                                                     
-v, --version          Show the package version and quit                                               
--license              Show the license and quit                                                       
--debug                Die when an emulation error occurs, even in "batch mode", and pass on the exit  
                       code.                                                                           
--loglevel             Logging level (debug, verbose, info, warning, error - default "info")           
--threads              When running in batch mode, how many analyses to run at the same time (0 =      
                       unlimited, default: as many as the number of CPU cores)                         
--download                Actually download the payloads                                                  
--encoding             Encoding of the input sample (will be automatically detected by default)        
--timeout              The script will timeout after this many seconds (default 10)                    
--output-dir           The location on disk to write the results files and folders to (defaults to the 
                       current directory)                                                              
--preprocess           Preprocess the original source code (makes reverse engineering easier, but takes
                       a few seconds)                                                                  
--unsafe-preprocess    More aggressive preprocessing. Often results in better code, but can break on   
                       some ed   ge cases (eg. redefining prototypes)                                     
--no-kill              Do not kill the application when runtime errors occur                           
--no-echo              When the script prints data, do not print it to the console                     
--no-rewrite           Do not rewrite the source code at all, other than for `@cc_on` support          
--no-catch-rewrite     Do not rewrite try..catch clauses to make the exception global-scoped           
--no-cc_on-rewrite     Do not rewrite `/*@cc_on <...>@*/` to `<...>`                                   
--no-eval-rewrite      Do not rewrite `eval` so that its argument is rewritten                         
--no-file-exists       Return `false` for Scripting.FileSystemObject.FileExists(x)                     
--no-folder-exists     Return `false` for Scripting.FileSystemObject.FileExists(x)                     
--function-rewrite     Rewrite function cal   ls in order to catch eval calls                             
--no-rewrite-prototype Do not rewrite expressions like `function A.prototype.B()` as `A.prototype.B =  
                       function()`                                                                     
--no-hoist-prototype   Do not hoist expressions like `function A.prototype.B()` (implied by            
                       no-rewrite-prototype)                                                           
--no-shell-error       Do not throw a fake error when executing `WScriptShell.Run` (it throws a fake   
                       error by default to pretend that the distribution sites are down, so that the   
                       script will attempt to poll every site)                                         
--no-typeof-rewrite    Do not rewrite `typeof` (e.g. `typeof ActiveXObject`, which must return         
                       'unknown' in the JScript standard and not 'ob   ject')                             
--proxy                [experimental] Use the specified proxy for downloads. This is not relevant if   
                       the --download flag is not present.                                             
--windows-xp           Emulate Windows XP (influences the value of environment variables)              
--dangerous-vm         Use the `vm` module, rather than `vm2`. This sandbox can be broken, so **don't  
                       use this** unless you're 100% sure of what you're doing. Helps with debugging by
                       giving correct stack traces.                                                    

Analisando a saída Saída do 

console
A primeira fonte de informação é a saída do console. Em uma análise bem-sucedida, normalmente será impresso algo como isto:

Using a 10 seconds timeout, pass --timeout to specify another timeout in seconds
Analyzing sample.js
Header set for http://foo.bar/baz: User-Agent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Emulating a GET request to http://foo.bar/baz
Downloaded 301054 bytes.
Saved sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66a (301054 bytes)
sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66a has been detected as data.
Saved sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8 (303128 bytes)
sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8 has been detected as PE32 executable (GUI) Intel 80386, for MS Windows.
http://foo.bar/baz is an active URL.
Executing sample.js.results/d241e130-346f-4c0c-a698-f925dbd68f0c in the WScript shell
Header set for http://somethingelse.com/: User-Agent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Emulating a GET request to http://somethingelse.com/
...

Nesse caso, estamos vendo um conta-gotas que baixa um arquivo http://foo.bar/baz, configurando o cabeçalho HTTP User-Agentpara Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0). Em seguida, ele decodifica e grava o resultado no disco (um executável do PE32). Por fim, ele executa algum comando no shell do Windows.

  • sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66aconterá a carga como foi baixada em http://foo.bar/baz ;
  • sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8 conterá a carga útil real (executável PE);
  • sample.js.results/d241e130-346f-4c0c-a698-f925dbd68f0c conterá o comando que foi executado no shell do Windows.

Registros JSON
Toda solicitação HTTP é impressa no terminal e efetuada loginurls.json. URLs duplicados não são inseridos (ou seja, solicitar o mesmo URL duas vezes resultará em apenas uma linhaurls.json). 
active_urls.jsoncontém a lista de URLs que acabaram resultando em uma carga executável. Esse arquivo é o mais interessante, se você deseja derrubar sites de distribuição. 
snippets.jsoncontém todos os trechos de códigobox-jsencontrados, JavaScript, um comando cmd.exe ou umscript doPowerShell . 
resources.jsoncontém todos os arquivos gravados em disco pela amostra. Por exemplo, se o aplicativo tentasse salvarHello world!em$PATH/foo.txt, o conteúdo deresources.jsonseria:

{
 "9a24...": {
  "path": "(path)\\foo.txt",
  "type": "ASCII text, with no line terminators",
  "md5": "86fb269d190d2c85f6e0468ceca42a20",
  "sha1": "d3486ae9136e7856bc42212385ea797094475802",
  "sha256": "c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51a"
 }
}

resources.jsonarquivo também é importante: cuidado com qualquer recurso executável (por exemplo, com "type": "PE32 executable (GUI) Intel 80386, for MS Windows"). 

Correção
Alguns scripts em estado selvagem foram observados para usar new Date().getYear()onde new Date().getFullYear(). Se uma amostra não mostrar nenhum comportamento suspeito, preste atenção nas Dateverificações. 

Se você tiver arquivos .JSE, compile o decodificador e execute-o assim:

cc decoder.c -o decoder
./decoder foo.jse bar.js
node run bar.js

Expansão
Ocasionalmente, você pode encontrar componentes não suportados. Nesse caso, você pode registrar um problema no GitHub ou emular o componente se souber JavaScript. 
O erro normalmente terá esta aparência (os números de linha podem ser diferentes):

1 Jan 00:00:00 - Unknown ActiveXObject WinHttp.WinHttpRequest.5.1
Trace
    at kill (/home/CapacitorSet/box-js/run.js:24:10)
    at Proxy.ActiveXObject (/home/CapacitorSet/box-js/run.js:75:4)
    at evalmachine.<anonymous>:1:6471
    at ContextifyScript.Script.runInNewContext (vm.js:18:15)
    at ...

Você pode ver que a exceção foi levantada Proxy.ActiveXObject, assim:

function ActiveXObject(name) {
 name = name.toLowerCase();
 /* ... */
 switch (name) {
  case "wscript.shell":
   return require("./emulator/WScriptShell");
  /* ... */
  default:
   kill(`Unknown ActiveXObject ${name}`);
   break;
 }
}

Adicione um novo case "winhttp.winhttprequest.5.1"(observe as minúsculas!) E faça com que ele retorne um Proxyobjeto ES6 (por exemplo ProxiedWinHttpRequest). Isso é usado para capturar recursos não implementados assim que solicitados pela amostra maliciosa:

/* emulator/WinHttpRequest.exe */
const lib = require("../lib");

module.exports = function ProxiedWinHttpRequest() {
 return new Proxy(new WinHttpRequest(), {
  get: function(target, name, receiver) {
   switch (name) {
    /* Add here "special" traps with case statements */
    default:
     if (name in target) return target[name];
     else lib.kill(`WinHttpRequest.${name} not implemented!`)
   }
  }
 })
}

function WinHttpRequest() {
 
}

Execute novamente a análise: ela falhará novamente, informando o que exatamente não foi implementado.

1 Jan 00:00:00 - WinHttpRequest.open not implemented!
Trace
    at kill (/home/CapacitorSet/box-js/run.js:24:10)
    at Object.ProxiedWinHttpRequest.Proxy.get (/home/CapacitorSet/box-js/run.js:89:7)

Emule WinHttpRequest.openconforme necessário:

function WinHttpRequest() {
 this.open = function(method, url) {
  URLLogger(method, url);
  this.url = url;
 }
}

e itere até o código emular sem erros. 

Contribuidores
@CapacitorSet : desenvolvedor principal 
@daviesjamie :

  • embalagem npm
  • ajuda da linha de comando
  • --output-directory
  • correções de bugs

@ALange :

  • suporte para codificações não UTF8
  • relatório de erros

@alexlamsl , @kzc

  • conselhos sobre como integrar o UglifyJS no box-js
  • aprimorando os recursos do UglifyJS usados ​​na desofuscação

@psrok :

  • correções de bugs

@gaelmuller :

  • correções de bugs

Baixar Box-Js

Seja o primeiro a comentar

Deixe uma resposta

O seu endereço de email não será publicado.


*