
CobaltWhispers is an aggressor script that utilizes a collection of Beacon Object Files (BOF) for Cobalt Strike to perform process injection, persistence and more, leveraging direct syscalls (SysWhispers2) to bypass EDR/AV
Autore: @Cerbersec
CobaltWhispers è uno script aggressor che utilizza una collezione di Beacon Object Files per Cobalt Strike per eseguire process injection, persistenza e altro, sfruttando syscall dirette per bypassare EDR/AV.
CobaltWhispers è alimentato da SysWhispers2 e InlineWhispers2
CobaltWhispers si basa su StayKit e sui lavori di Hasherezade e Forrest Orr.
CobaltWhispers è stato realizzato durante uno stage presso il Red Team di NVISO Security. I relativi articoli del blog possono essere trovati qui (process-injection) e qui (kernel karnage).
CobaltWhispers richiede diversi strumenti per la compilazione:
apt install mingw-w64apt install makeOgni progetto richiede 3 file generati da SysWhispers2 / InlineWhispers2 per funzionare:
Questi file possono essere generati secondo la documentazione di InlineWhispers2, tuttavia questo non è il metodo ottimale perché verrà incluso molto codice non utilizzato:
git clone https://github.com/Sh0ckFR/InlineWhispers2 && cd InlineWhispers2
cd SysWhispers2/ && python3 syswhispers.py --preset all -o syscalls_all && cd ..
python3 InlineWhispers2.py
In alternativa, utilizza SysWhispers2 per generare i file di output solo per le API necessarie, quindi fornisci manualmente (o tramite script) i file a InlineWhispers2, che li convertirà nel formato corretto. Consulta il makefile incluso per ulteriori informazioni oppure utilizza i file inclusi a tuo rischio.
| Tipo di payload | Target | Affidabilità (0-5) | Elevato | Note |
|---|---|---|---|---|
| - | - | 5 | No | Eredita i permessi dal processo padre |
Crea un nuovo processo sospeso con Code Integrity Guard (CIG) abilitato per bloccare i binari firmati non Microsoft. Spoofa il processo padre specificato. Viene restituito il PID.
Processo padre: Il nome del processo da impostare come padre
Percorso dell'eseguibile: Percorso completo dell'eseguibile su disco utilizzato per creare il nuovo processo
| Tipo di payload | Target | Affidabilità (0-5) | Elevato | Note |
|---|---|---|---|---|
| Shellcode/Raw | PID | 5 | No | - |
Inietta un payload in un processo remoto utilizzando NtCreateThreadEx
PID del processo: L'ID del processo remoto
Posizione del payload: Posizione del payload in formato binario su disco (Condizionale | Opzionale)
Payload b64: Shellcode raw in formato stringa codificata base64 (Condizionale | Opzionale)
Listener: Listener per cui generare il payload (Condizionale)
È necessario specificare un listener per generare un payload Beacon. Se si desidera un payload manuale, deve essere fornito tramite un percorso al binario raw su disco o shellcode codificato in Base64.
| Tipo di payload | Target | Affidabilità (0-5) | Elevato | Note |
|---|---|---|---|---|
| Shellcode/Raw | PID | 2 | No | Può potenzialmente causare il crash del processo target |
Inietta un payload in un processo remoto utilizzando NtQueueApcThread
PID del processo: L'ID del processo remoto
Thread: Numero di thread a cui aggiungere una chiamata APC
Posizione del payload: Posizione del payload in formato binario su disco (Condizionale | Opzionale)
Payload b64: Shellcode raw in formato stringa codificata base64 (Condizionale | Opzionale)
Listener: Listener per cui generare il payload (Condizionale)
È necessario specificare un listener per generare un payload Beacon. Se si desidera un payload manuale, deve essere fornito tramite un percorso al binario raw su disco o shellcode codificato in Base64.
| Tipo di payload | Target | Affidabilità (0-5) | Elevato | Note |
|---|---|---|---|---|
| Shellcode/Raw | Processo surrogate | 5 | No | - |
Inietta un payload in un processo surrogate utilizzando NtMapViewOfSection
Processo padre: Il nome del processo da impostare come padre
Percorso dell'eseguibile: Il percorso dell'eseguibile su disco da utilizzare per creare un nuovo processo
Posizione del payload: Posizione del payload in formato binario su disco (Condizionale | Opzionale)
Payload b64: Shellcode raw in formato stringa codificata base64 (Condizionale | Opzionale)
Listener: Listener per cui generare il payload (Condizionale)
È necessario specificare un listener per generare un payload Beacon. Se si desidera un payload manuale, deve essere fornito tramite un percorso al binario raw su disco o shellcode codificato in Base64.
| Tipo di payload | Target | Affidabilità (0-5) | Elevato | Note |
|---|---|---|---|---|
| PE | Processo surrogate | 5 | No | Richiede payload PE x64 |
Inietta un payload in un processo surrogate utilizzando sezioni transazionali e viste mappate. Il punto di ingresso remoto e il PEB vengono aggiornati, senza sezioni di memoria anomale o permessi di memoria anomali. Vedi qui per maggiori informazioni.
Processo padre: Il nome del processo da impostare come padre
Percorso dell'eseguibile: Il percorso dell'eseguibile su disco da utilizzare per creare un nuovo processo
Posizione del payload: Posizione del payload PE x64 su disco (Condizionale | Opzionale)
Payload b64: Payload PE x64 in formato stringa codificata base64 (Condizionale | Opzionale)
Listener: Listener per cui generare il payload (Condizionale)
È necessario specificare un listener per generare un payload Beacon. Se si desidera un payload manuale, deve essere fornito tramite un percorso al PE x64 su disco o a un PE x64 codificato in Base64.
ATTUALMENTE NON IMPLEMENTATO
| Tipo di payload | Target | Affidabilità (0-5) | Elevato | Note |
|---|---|---|---|---|
| Position Independent Shellcode (PIC) | Processo surrogate | 5 | Sì | Sono richiesti privilegi elevati per aprire le DLL di sistema con permessi di scrittura |
Inietta un payload in un processo surrogate utilizzando sezioni transazionali in combinazione con DLL hollowing. Vedi qui per maggiori informazioni.
Processo padre: Il nome del processo da impostare come padre
Percorso dell'eseguibile: Il percorso dell'eseguibile su disco da utilizzare per creare un nuovo processo
Posizione del payload: Posizione del payload in formato binario su disco (Condizionale | Opzionale)
Payload b64: Shellcode raw in formato stringa codificata base64 (Condizionale | Opzionale)
Listener: Listener per cui generare il payload (Condizionale)
È necessario specificare un listener per generare un payload Beacon. Se si desidera un payload manuale, deve essere fornito tramite un percorso al binario raw su disco o shellcode codificato in Base64.
Crea o modifica una chiave di registro nella posizione specificata.
Nome chiave: Nome del valore
Comando: Comando da eseguire quando il registro viene utilizzato
Chiave di registro: Posizione in cui verrà creata la chiave di registro
Nascosto: Antepone un byte null al nome della chiave; genera errori in regedit
Pulizia: Rimuove la chiave creata
La pulizia richiede il nome della chiave e la chiave di registro (posizione).
Crea o modifica una chiave di registro nella posizione specificata.
Nome chiave: Nome del valore
Comando: Comando da eseguire quando il registro viene utilizzato
Chiave di registro: Posizione in cui verrà creata la chiave di registro
Nascosto: Antepone un byte null al nome della chiave; genera errori in regedit
Pulizia: Rimuove la chiave creata
La pulizia richiede il nome della chiave e la chiave di registro (posizione).
UserInit: imposta automaticamente 'Nome chiave' e 'Chiave di registro'.
Crea o modifica una chiave di registro nella posizione specificata.
Nome chiave: Nome del valore
Comando: Comando da eseguire quando il registro viene utilizzato
Chiave di registro: Posizione in cui verrà creata la chiave di registro
Nascosto: Antepone un byte null al nome della chiave; genera errori in regedit
Pulizia: Rimuove la chiave creata
La pulizia richiede il nome della chiave e la chiave di registro (posizione).
Crea o modifica una chiave di registro nella posizione specificata.
Nome chiave: Nome del valore
Comando: Comando da eseguire quando il registro viene utilizzato
Chiave di registro: Posizione in cui verrà creata la chiave di registro
Nascosto: Antepone un byte null al nome della chiave; genera errori in regedit
Pulizia: Rimuove la chiave creata
La pulizia richiede il nome della chiave e la chiave di registro (posizione).
UserInitMprLogonScript: imposta automaticamente 'Nome chiave' e 'Chiave di registro'.
Esegue l'hijacking del gestore COM di un'attività pianificata. Crea una chiave di registro in HKCU:\Software\Classes\CLSID\\InprocServer32 che punta a una DLL.
ID classe: Il CLSID che corrisponde al CLSID del gestore COM dell'attività
Percorso DLL: Percorso della DLL da caricare
Pulizia: Rimuove la chiave creata
| Affidabilità (0-5) | Elevato | Note |
|---|---|---|
| 4 | Sì | Può potenzialmente causare un BSOD sul sistema target |
Carica un driver firmato vulnerabile con lettura/scrittura arbitraria della memoria del kernel (NalDrv/iqvm64.sys). Modifica il flag g_CiEnabled di ntoskrnl.exe o g_CiOptions di CI.dll per disabilitare l'applicazione della firma dei driver (DSE).
Carica un driver non firmato (Interceptor/Interceptor.sys), quindi ripristina i valori dei flag DSE. Sia il driver firmato che quello non firmato vengono scritti su disco.
| Driver | MD5 checksum |
|---|---|
| iqvm64.sys | 1898ceda3247213c084f43637ef163b3 |
| Interceptor.sys | 508c8943359717cfa0c77b61ebea2118 |
Posizione del driver vulnerabile: Posizione del driver firmato vulnerabile in formato binario su disco
Posizione del driver dannoso: Posizione del driver non firmato dannoso in formato binario su disco
Nome del driver vulnerabile: nome utilizzato per creare la chiave di registro '\Registry\Machine\System\CurrentControlSet\Services\'
Nome del dispositivo del driver vulnerabile: nome utilizzato per contattare il driver '\DosDevices\'
Nome del driver dannoso: nome utilizzato per creare la chiave di registro '\Registry\Machine\System\CurrentControlSet\Services\'
Nome del dispositivo del driver dannoso: nome utilizzato per contattare il driver '\DosDevices\'
Percorso di destinazione: percorso temporaneo in cui scrivere i file del driver vulnerabile e dannoso
| Affidabilità (0-5) | Elevato | Note |
|---|---|---|
| 5 | Sì | - |
Rimuove un driver sul target utilizzando la chiave di registro fornita ed elimina il binario dal disco nel percorso specificato.
Chiave di registro del driver: chiave di registro utilizzata per rimuovere il driver '\Registry\Machine\System\CurrentControlSet\Services\'
Percorso di installazione del driver: posizione del driver su disco
| Affidabilità (0-5) | Elevato | Note |
|---|---|---|
| 4 | No | Può potenzialmente causare un BSOD sul sistema target |
Informazioni: Interroga il driver Interceptor
Hook: Aggancia le funzioni principali (IRP) del driver target
Unhook: Ripristina le funzioni principali del driver target
Patch: Applica patch ai callback del kernel target
Restore: Ripristina i callback del kernel target
Vendor: mostra i vendor supportati
Moduli: interroga tutti i driver caricati
Moduli agganciati: mostra tutti i driver agganciati
Callback: interroga tutti i callback registrati
Indice: aggancia un driver tramite indice (vedi: informazioni - moduli)
Nome: aggancia un driver tramite nome del dispositivo (\Device\Name)
Valori: elenco di indici separati da virgola (condizionale)
Nome: nome del dispositivo del driver target (condizionale)
I valori sono obbligatori quando viene selezionato 'Indice'. Il nome è obbligatorio quando viene selezionato 'Nome'.
Indice: rimuovi l'aggancio di un driver tramite indice (vedi: informazioni - moduli agganciati)
Tutti: rimuovi l'aggancio di tutti i driver agganciati
Valori: elenco di indici separati da virgola (condizionale)
I valori sono obbligatori quando viene selezionato 'Indice'.
Vendor: applica la patch a tutti i callback associati ai moduli del vendor
Modulo: applica la patch a tutti i callback associati ai moduli
Processo: applica la patch ai callback di processo
Thread: applica la patch ai callback di thread
Immagine: applica la patch ai callback di immagine
Registro: applica la patch ai callback di registro
Oggetto processo: applica la patch ai callback dell'oggetto processo
Oggetto thread: applica la patch ai callback dell'oggetto thread
Valori: elenco di indici separati da virgola (vedi: informazioni - callback) (condizionale)
Nome: elenco di nomi di moduli separati da virgola o nome di un singolo vendor (vedi: informazioni - vendor) (condizionale)
I valori sono obbligatori quando viene selezionato 'processo', 'thread', 'immagine', 'registro', 'oggetto processo' o 'oggetto thread'. Il nome è obbligatorio quando viene selezionato 'vendor' o 'modulo'.
Vendor: ripristina tutti i callback associati ai moduli del vendor
Modulo: ripristina tutti i callback associati ai moduli
Processo: ripristina i callback di processo
Thread: ripristina i callback di thread
Immagine: ripristina i callback di immagine
Registro: ripristina i callback di registro
Oggetto processo: ripristina i callback dell'oggetto processo
Oggetto thread: ripristina i callback dell'oggetto thread
Tutti: ripristina tutti i callback
Valori: elenco di indici separati da virgola (vedi: informazioni - callback) (condizionale)
Nome: elenco di nomi di moduli separati da virgola o nome di un singolo vendor (vedi: informazioni - vendor) (condizionale)
I valori sono obbligatori quando viene selezionato 'processo', 'thread', 'immagine', 'registro', 'oggetto processo' o 'oggetto thread'. Il nome è obbligatorio quando viene selezionato 'vendor' o 'modulo'.