
Jellyfin Server 12.2 - عالية الخطورة - عن بُعد بعد زرع .strm - حقن وسيط FFmpeg - EncodingUtils -i متبقٍ من GHSA-wwwm
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · jellyfin-ffmpeg-colonslash
الفئة: حقن وسائط FFmpeg
الوصول: عن بُعد بعد زرع ملف .strm في المكتبة (كاتب مجلد وسائط مفحوص، ثم بث غير مُصادَق)
Jellyfin Server v12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6) - Jellyfin. الصورة jellyfin/jellyfin:12.2.
GHSA-wwwm-px48-fpvq / PR 17685 أضاف EscapeProcessArgument على وسائط التحويل argv وفرع -i الخاص بـ file:. لا يزال البروتوكول غير File يلفّ المسار الخام بين علامتي اقتباس دون هذا التهريب (EncodingUtils.cs:14-71). قيمة ManagedFileSystem.IsPathFile هي false بالنسبة لـ :// التي ليست file://. لا يزال TranscodeManager يبني ProcessStartInfo.Arguments كسلسلة واحدة.
ملف .strm في مكتبة مفحوصة يكون سطره الأول عنوان URL من نوع http يحتوي على " يُصنَّف كـ Http. يقبل Uri.TryCreate ذلك العنوان. يبدأ GET /Videos/{id}/stream غير المُصادَق (بدون static) تشغيل ffmpeg. سجل المختبر هو:
-i "http://127.0.0.1/a" JELLYFIN-FFMPEG-COLONSLASH-WITNESS "x"
يبقى عنصر التحكم LabControl.mkv وسيطًا واحدًا: -i file:"/media/movies/LabControl.mkv".
اسم ملف POSIX يحتوي على :// لا يصل إلى هذا المصب. لا يمكن أن تكون الشرطة المائلة جزءًا من اسم ملف. نبات المختبر a://b"…"x.mkv يُخزَّن باسم /media/movies/a:/b"…"x.mkv ويأخذ فرع File المُهرَّب. لا تُقدِّم بلاغًا عن متغيّر اسم ملف يحتوي على نقطتين وشرطة مائلة. أنا لا أدّعي وجود RCE عبر plugin-DLL. المختبر يُثبت فقط تقسيم argv.
البقية #4 من سلسلة Jellyfin 12.2 leftovers.
| ID | لا يوجد CVE بعد |
| Class | حقن وسائط FFmpeg (CWE-88) |
| Reach | عن بُعد بعد زرع .strm في المكتبة، ثم بث بدون مصادقة |
| CWE | CWE-88 |
| CVSS | عالٍ: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N |
| Product | Jellyfin Server |
| Affected | v12.2 (ca0f16eb) صورة jellyfin/jellyfin:12.2 |
| Auth | كاتب المكتبة للزرع؛ البث بدون مصادقة |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 فقط |
نفس نموذج الزرع كما في GHSA-wwwm: كتابة ملف .strm داخل مجلد وسائط مفحوص (NAS / Samba / مشاركة ضيف). بعد ذلك يمكن لأي شخص يستطيع فتح TCP إلى الخادم أن ينفّذ GET /Videos/{id}/stream بدون Authorization وبدون static. هذه هي مجموعة الصلاحيات الكاملة. لا شيء في هذه القائمة يمثّل RCE عبر shell أو plugin-DLL.
| Axis | Method + path | Grants | Provenance |
|---|---|---|---|
| Integrity / argv | GET /Videos/{id}/stream بدون مصادقة بعد زرع .strm في المكتبة | وسائط ffmpeg إضافية خارج علامات اقتباس -i | مُثبَت في المختبر. سجل TranscodeManager |
| Recon | نفسه مع -vf drawtext=textfile= | بايتات ملف المضيف في الترميز | أداة مُستنتَجة؛ لم تُشغَّل |
| Integrity | -attach / -dump_attachment | كتابة بصلاحية jellyfin-UID | مُستنتَج؛ تحميل plugin غير مُثبَت |
| RCE | غير مُدَّعى | - | - |
ProcessBuilder. لا RCE عبر plugin-DLL. سلسلة GHSA-866x القديمة تاريخية وغير معروضة هنا.:// يصبح مجلدًا (a:) بالإضافة إلى ملف. المسار Canonical لا يحتوي على ://، لذا يصل إلى فرع -i المُهرَّب file:.level TryParse في GHSA-jh22 مُغلق..strm المحلية / file:// تُسقَط (ProbeProvider يحتفظ بـ http / https / rtsp / rtp فقط).EncoderAppPath عبر واجهة برمجة إعدادات الترميز..strm (GHSA-j2hf) يبقى مُغلقًا.ثبّتُ jellyfin/jellyfin v12.2. عشرون عملية بحث في المصدر، ثم أربعة مختبرات loopback مستقلة. PR 17685 هرّب argv التحويل وfile: -i. تُركت أغلفة Http / rtsp كـ "%s". أول زرع جرّبته كان اسم ملف POSIX يحتوي على ://. ذلك الزرع مجلد. البقية التي تُفعَّل هي .strm يحتوي URL الخاص به بالفعل على :// و".
منعطف خاطئ، بهذا الترتيب: التعامل مع اختصار path.Contains("://") في GetFileInputArgument كخطأ في اسم الملف. الشرطة المائلة فاصل. فرع File يُهرِّب بالفعل. فرع non-File لا يفعل.
أشقاء على هذا التثبيت: jellyfin-suggestions-idor، jellyfin-svg-gzip، jellyfin-playlist-itemids.
عميل loopback: jellyfin-ffmpeg-colonslash-Abraxas-Labs.py. الحزمة: lab/ (docker-compose.yml، poc.py، run.sh). مختبر مُصرَّح به فقط. يتواصل مع loopback.
python3 jellyfin-ffmpeg-colonslash-Abraxas-Labs.py
أو:
cd lab
./run.sh
استهدف فقط http://127.0.0.1:18810. الصورة jellyfin/jellyfin:12.2. مشروع Compose jellyfin-ffmpeg-colonslash. الشاهد JELLYFIN-FFMPEG-COLONSLASH-WITNESS.
يكتب poc.py الملف LabControl.mkv (التحكم، باستخدام -i file:"..." واحد) والملف LabPlant.strm الذي يكون عنوان URL الخاص به http://127.0.0.1/a" JELLYFIN-FFMPEG-COLONSLASH-WITNESS "x. يسجّل طلب GET /Videos/{id}/stream غير الموثّق (بدون static) كسر علامة الاقتباس. السطر الأخير:
SUCCESS jellyfin-ffmpeg-colonslash argv-split=yes plant-i=quote-break control-id=f603a52f649bcf822b333c4d5f21cc86 plant-id=d7aabf0935bb524e1667b1ff9bb945d9 JELLYFIN-FFMPEG-COLONSLASH-WITNESS
استدعِ EscapeProcessArgument على كل فرع من فروع GetInputArgument، بما في ذلك Http وrtsp. أبقِ التغليف، لكن اهرب السلسلة الداخلية بعلامات الاقتباس بالطريقة التي يفعلها فرع file: بالفعل.
MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs:14-71Emby.Server.Implementations/IO/ManagedFileSystem.cs:533-541MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs:417-431Jellyfin.Api/Controllers/VideosController.cs:314-318, 483-486