
Jellyfin Server 12.2 - Alta - Remoto dopo piantagione .strm - Iniezione di argomenti FFmpeg - EncodingUtils -i residuo di GHSA-wwwm
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · jellyfin-ffmpeg-colonslash
Classe: Iniezione di argomenti in FFmpeg
Portata: Remota dopo il posizionamento di un .strm nella libreria (chi scrive in una cartella multimediale scansionata, poi stream non autenticato)
Jellyfin Server v12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6) - Jellyfin. Immagine jellyfin/jellyfin:12.2.
GHSA-wwwm-px48-fpvq / PR 17685 hanno aggiunto EscapeProcessArgument sugli argv di conversione e sul ramo -i di file:. Il protocollo non-File continua a racchiudere il percorso grezzo tra virgolette senza tale escape (EncodingUtils.cs:14-71). ManagedFileSystem.IsPathFile è falso per :// che non sia file://. TranscodeManager costruisce ancora ProcessStartInfo.Arguments come un'unica stringa.
Un .strm in una libreria scansionata la cui prima riga è un URL http contenente " viene classificato come Http. Uri.TryCreate accetta quell'URL. Una GET /Videos/{id}/stream non autenticata (senza static) avvia ffmpeg. Il log del laboratorio è:
-i "http://127.0.0.1/a" JELLYFIN-FFMPEG-COLONSLASH-WITNESS "x"
Il controllo LabControl.mkv resta un unico argomento: -i file:"/media/movies/LabControl.mkv".
Un nome file POSIX con :// non raggiunge questo sink. La barra non può far parte di un nome file. Il plant di laboratorio a://b"…"x.mkv viene memorizzato come /media/movies/a:/b"…"x.mkv e segue il ramo File con escape. Non segnalare una variante di nome file con due punti e barra. Non sto affermando un RCE tramite DLL di plugin. Il laboratorio dimostra solo la suddivisione degli argv.
Residuo #4 della serie Jellyfin 12.2 leftovers.
| ID | nessuna CVE al momento |
| Classe | Iniezione di argomenti FFmpeg (CWE-88) |
| Raggiungibilità | Remota dopo un plant .strm nella libreria, poi stream non autenticato |
| CWE | CWE-88 |
| CVSS | Alto: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N |
| Prodotto | Jellyfin Server |
| Affetto | v12.2 (ca0f16eb) immagine jellyfin/jellyfin:12.2 |
| Auth | scrittore della libreria per il plant; lo stream non è autenticato |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
Stesso modello di plant di GHSA-wwwm: scrivere un .strm in una cartella multimediale scansionata (NAS / Samba / condivisione guest). Poi chiunque possa aprire una connessione TCP verso il server può eseguire GET /Videos/{id}/stream senza Authorization e senza static. Questo è l'intero insieme di privilegi. Nulla in questo elenco è un RCE tramite shell o DLL di plugin.
| Asse | Metodo + percorso | Concede | Provenienza |
|---|---|---|---|
| Integrità / argv | GET /Videos/{id}/stream non autenticato dopo un plant .strm nella libreria | Argomenti ffmpeg aggiuntivi al di fuori delle virgolette di -i | Dimostrato in laboratorio. Log di TranscodeManager |
| Ricognizione | lo stesso più -vf drawtext=textfile= | Byte di file dell'host nel transcode | Gadget dedotto; non eseguito |
| Integrità | -attach / -dump_attachment | Scrittura con UID jellyfin | Dedotto; caricamento del plugin non mostrato |
| RCE | non affermato | - | - |
ProcessBuilder. Nessun RCE tramite DLL di plugin. La vecchia catena GHSA-866x è storica e non è mostrata qui.:// diventa una directory (a:) più un file. Il Path canonico non ha ://, quindi segue il ramo -i file: con escape.level di GHSA-jh22 è chiuso..strm locali / file:// vengono scartati (ProbeProvider mantiene solo http / https / rtsp / rtp).EncoderAppPath non può essere impostato tramite l'API di configurazione dell'encoding..strm di caricamento sottotitoli (GHSA-j2hf) resta chiuso.Ho fissato jellyfin/jellyfin v12.2. Venti ricerche nel codice sorgente, poi quattro laboratori indipendenti su loopback. La PR 17685 ha messo in escape gli argv di conversione e -i file:. I wrapper Http / rtsp sono stati lasciati come "%s". Il primo plant che ho provato era un nome file POSIX contenente ://. Quel plant è una directory. Il residuo che scatta è un .strm il cui URL contiene già :// e ".
Passo falso, in quest'ordine: aver trattato la scorciatoia path.Contains("://") di GetFileInputArgument come un bug del nome file. La barra è un separatore. Il ramo File esegue già l'escape. Il ramo non-File no.
Correlati su questo pin: jellyfin-suggestions-idor, jellyfin-svg-gzip, jellyfin-playlist-itemids.
Client loopback: jellyfin-ffmpeg-colonslash-Abraxas-Labs.py. Stack: lab/ (docker-compose.yml, poc.py, run.sh). Solo laboratorio autorizzato. Comunica con il loopback.
python3 jellyfin-ffmpeg-colonslash-Abraxas-Labs.py
O:
cd lab
./run.sh
Destinazione solo http://127.0.0.1:18810. Immagine jellyfin/jellyfin:12.2. Progetto Compose jellyfin-ffmpeg-colonslash. Witness JELLYFIN-FFMPEG-COLONSLASH-WITNESS.
poc.py scrive LabControl.mkv (controllo, un -i file:"...") e LabPlant.strm il cui URL è http://127.0.0.1/a" JELLYFIN-FFMPEG-COLONSLASH-WITNESS "x. Una GET /Videos/{id}/stream non autenticata (senza static) registra la rottura delle virgolette. Ultima riga:
SUCCESS jellyfin-ffmpeg-colonslash argv-split=yes plant-i=quote-break control-id=f603a52f649bcf822b333c4d5f21cc86 plant-id=d7aabf0935bb524e1667b1ff9bb945d9 JELLYFIN-FFMPEG-COLONSLASH-WITNESS
Chiamare EscapeProcessArgument su ogni ramo di GetInputArgument, inclusi Http e rtsp. Mantenere il wrapping, ma effettuare l'escape tra virgolette della stringa interna come già fa il ramo file:.