Dal C al C2: costruire un dropper per un laboratorio di Red Teaming
Intro
Ho deciso di fare questo post in italiano, dato che non ho visto molti articoli inerenti agli argomenti che tratterò. Ultimamente mi sono imbattuto in diversi temi legati al red teaming, in particolare ai C2 (Command and Control). In parallelo, ho deciso di studiare a fondo il linguaggio C, con l’obiettivo di rendere il reverse engineering una delle mie principali competenze.
Progetto
Ho voluto approfittare del fatto che stessi imparando il linguaggio C per poter creare qualcosa di mio, un dropper, che evade sia AV che HIDS (Host-based intrusion detection system) /IPS (Intrusion prevention system), che una volta nel sistema della vittima, scaricherà un demone generato da Havoc C2 Framework.
Per far si che il tutto fosse il più anonimo possibile e proteggero l’OPSec , ho inoltre offuscato il codice con un paio di tecniche particolari, risultando non vulnerabile a virustotal e difficile da leggere una volta compilato ma anche non.
Strumenti
Per creare l’ambiente, ho usato:
- Oracle Free tier VPS ( Macchina di command and control )
- Havoc C2 Framework
- C per la creazione del dropper
Workflow
L’attacco non sfrutta una vulnerabilità nel sistema, ben si sfrutta un attacco a catena ( Phishing ad esempio).
- La vittima viene ingannata a scaricare il file,magari spacciandolo per qualcosa di sicuro (molto semplice)
- Una volta nel sistema, l’AV non dovrebbe rilevare il file come Malware
- il Portable Executable , una volta eseguito, installerà in una cartella scrivibile il demone generato da Havoc-C2
- Il demone verrà eseguito e il client vittima farà parte del del nostro server C2
Inizio
Ho iniziato creando una VPS su oracle, da poter usare come server di controllo. https://www.oracle.com/it/cloud/sign-in.html
Passi importanti da seguire sono:
- Creazione di una VNIC per poter raggiungere dall’esterno la macchina
- Disabilitazione delle misure di sicurezza restrittive O aggiunta di porte esposte (Ovvero quella che useremo per connetterci al TeamServer)
Dopo aver ottenuto l’istanza, ho quindi creato e modificato la VNIC
Virtual cloud networks –> Subnets –> la tua VNIC –> Security –> Security list –> security rules
Ho impostato la porta 4000 per le connessioni inbound e ICMP raggiungibile per una questione di debug.
Un consiglio che do , non mantenere la porta ICMP con reply to all, bensì cambiarla con type code : 3, a quel punto quando la macchina verrà pingata, verrà contrassegnata come irraggiungibile, ottimo per non essere rilevato dalla maggior parte dei bot sulla rete
Configurazione server C2
Una volta sul server, ho installato e configurato Havoc team server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
git clone https://github.com/HavocFramework/Havoc.git
cd Havoc
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.10 python3.10-dev
apt-get install golang-go
cd teamserver
go mod download golang.org/x/sys
go mod download github.com/ugorji/go
cd ..
make ts-build
Prima di avviarlo dobbiamo sistemare il nostro config file
nano /Havoc/profiles/havoc.yaotl
Qui possiamo creare user, configurare password e la porta che verrà esposta sulla rete.
Avviamo il team server con
1
sudo ./havoc server --profile ./profiles/havoc.yaotl -v --debug
Configurazione client
Vi sono due modi, compilare tutto o installare da repository, la via più veloce: yay -S havoc-c2-git
Adesso siamo pronti per avviare il nostro client e verificare che il tutto funzioni.
Qui ho però apportato una modifica, dato che il VPS è comunque molto restrittivo, per evitare falle di sicurezza, ho deciso di fare un forwarding della porta 4000 sulla mia macchina, così da poter raggiungere il team server dirittamente in localhost.
1
❯ ssh -i ssh.key ubuntu@server -L 4000:127.0.0.1:4000
Con un breve network scan sul nostro sistema, vediamo che abbiamo la porta aperta. proviamo a raggiungerla con il client havoc
Creiamo un profilo e inseriamo tutti i dati
Abbiamo con successo ottenuto l’accesso al team server.
Generazione del demone
Dobbiamo generare un demone, ovvero l’agente che verrà scaricato nel sistema vittima.
Impostiamo il jitter:
In questo tipo di post exploitation attack, rilevare molte connessioni può dare nell’occhio, settando un jitter di 15 secondi, faremo si che vi sia una variazione casuale aggiunta all’intervallo di tempo con cui l’agent (beacon) contatta il server C2.
Esempio:
- Senza jitter → beacon ogni 60 secondi precisi
- Con jitter 30% → beacon tra 42 e 78 secondi
Inoltre è ottimo per evasione da IDS / SIEM
Molti sistemi di detection cercano pattern come:
- traffico periodico
- intervalli regolari
- stesso endpoint a tempo fisso
Il jitter rompe la periodicità, rendendo il beaconing simile a traffico legittimo.
Prima di tutto
Creiamo un listener.
Generiamo un payload:
In questo caso,potremmo generare un payload solo per windows, motivo per la quale il testing potrebbe avvenire solo su una macchina windows, ma il nostro obbiettivo non è questo, è iniettare l’agente , facendo si che venga eseguito tramite un dropper a prova di reverse engineering,
Creazione del progamma
Inizialmente ho scritto qualche riga di codice per vedere cosa si vedesse con hexdump o strings
Insieme a tanti pezzi di codice, che serviranno a rendere l’applicazione compilata ancora più difficile da leggere, grabberà il nostro agent. Ma sorge un problema. Se proviamo a fare un po’ di analisi sul PE generato, notiamo delle cose CRITICHE.
IP esposto –> OpSec fallito
Quindi, dato che dobbiamo mantenere un buon anonimato, riscriviamo il codice in modo tale che sia il meno leggibile possibile.
Creazione e offuscamento del codice: ELF
- Verrà effettuato un piccolo health check del server e successivamente verrà scaricato il file. (Ovviamente ICMP dovrà essere type code 0 per far si che questa linea funzioni)
Il tutto sembra andare
Ora dobbiamo trovare una cartella scrivibile:
Su Linux:
~/.local/bin/shared/clib/ Su Windows:
C:\Users\<user>\AppData\Local\
Con questa modifica:
- Il codice verrà inserito in una directory scrivibile.
Adesso bisognerà eseguirlo e avere un PoC (Proof of Concept) del risultato:
Come PoC abbiamo fatto si che una volta che l’agente sarebbe stato eseguito, ricevessimo una notifica
Adesso: Purtroppo non possiamo testare l’agent su linux, in quanto ancora non è supportato al 100%, per tanto, scriveremo del codice per farlo esegure su windows:
il codice finale per Linux è il seguente:
Scrittura codice Windows: PE
- Rimpiazziamo il path linux con un path adatto a windows
- Al posto di wget useremo certutil
- Modifichiamo il comando ping per poter essere eseguito da windows
Adesso sembrerebbe finito, ma manca il punto principale! L’offuscamento.
In fine , ho fatto si che ogni singola funzione, testo per debug e tutto ciò che si potesse offuscare al meglio, venisse reso completamente illegibile.
Risultato:
- Bypass di AV
- Inserimento di macchina target nel server C2
- Offuscamento del codice
Tutti i file sono presenti qui! Github