
Forgejo 16.0.5 - عالي - عن بُعد - قراءة ملف - restore-repo يتبع file:// من جهة dump إلى المرفقات
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · forgejo-restore-file-open
المقال التفصيلي: https://abraxaslabs.tech/research/forgejo-restore-file-open
الفئة: قراءة ملفات النطاق: محلي
Forgejo 16.0.5 (8d24b7d) - Forgejo
يقوم forgejo restore-repo على نسخة احتياطية غير موثوقة بإعادة كتابة روابط أصول الإصدارات باستخدام filepath.Join(baseDir, download_url) الخام وإضافة البادئة file://. لا يزال uri.Open ينفّذ os.Open على ذلك المسار. تعمل --units الفارغة على استعادة الإصدارات. أضاف Gitea 1.27.0 الدالة localFileURL وتخطّى تهريب المدخلات. تلك الدالة المساعدة غير موجودة هنا.
استعادة المشغّل لنسخة احتياطية غير موثوقة تنسخ ملفًا على المضيف يستطيع مستخدم forgejo فتحه إلى مرفق إصدار.
| المعرّف | لا يوجد CVE بعد |
| الفئة | قراءة ملفات |
| النطاق | محلي (أمر المشغّل forgejo restore-repo على نسخة احتياطية غير موثوقة) |
| CWE | CWE-22 / CWE-73 |
| CVSS | مرتفع: 7.3 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N |
| المنتج | Forgejo |
| المتأثر | حتى v16.0.5 (8d24b7d)؛ استعادة المشغّل المحلي |
| المصادقة | استعادة المشغّل المحلي لنسخة احتياطية غير موثوقة |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1 فقط |
تسليم المشغّل مجلد نسخة احتياطية (أو امتلاك INTERNAL_TOKEN مسبقًا ومسار يستطيع الخادم قراءته). تشمل الوحدات releases / release_assets.
| الصلاحية | الطريقة / نقطة الوصول | الاستطلاع / السلامة / التوافر | مُثبت مختبريًا أم مُستنتج |
|---|---|---|---|
قراءة ملف على المضيف يستطيع مستخدم forgejo فتحه، عبر .. للخروج من النسخة الاحتياطية | release.yml download_url: ../FORGEJO-FILE-WITNESS.txt؛ تُدمج الاستعادة، وينفّذ uri.Open الدالة os.Open، وتُخزَّن البايتات باسم witness.txt | استطلاع (سرية ملفات المضيف) | مُثبت مختبريًا. محتوى المرفق هو FORGEJO-RESTORE-FILE-OPEN-WITNESS. لم يُقدَّم الطُعم داخل النسخة الاحتياطية INSIDE-DUMP-NOT-HOST |
| النتيجة نفسها باستخدام رابط رمزي مزروع داخل النسخة الاحتياطية | يبقى المسار المدموج تحت baseDir؛ ويتبع os.Open الرابط | استطلاع | مُستنتج من uri.Open file -> os.Open. استخدم المختبر .. وليس رابطًا رمزيًا |
| نقطة الوصول نفسها على رقع طلبات السحب | يُعاد كتابة PatchURL في pull_request.yml بالطريقة نفسها، ثم uri.Open إلى repo/pulls/<n>.patch | استطلاع | مُستنتج من restore.go GetPullRequests. استعاد المختبر الإصدارات فقط |
| قارئو المستودع المستعاد ينزّلون ملف المضيف | GET /<owner>/<repo>/releases/download/<tag>/<name> | استطلاع | مُثبت مختبريًا باستخدام Basic للمستخدم labadmin على المستودع العام المستعاد |
ملفات المضيف النموذجية: app.ini، INTERNAL_TOKEN، SECRET_KEY، كلمة مرور قاعدة البيانات | يستطيع مستخدم forgejo قراءة شجرة الإعدادات | استطلاع | مُستنتج. كان شاهد المختبر ملفًا مزروعًا بجوار النسخة الاحتياطية، وليس أسرارًا حية |
مغلق هنا: LFI الحي عبر POST /repos/migrate بـ file:// (تم تعيين DownloadFunc؛ ويُفحص بادئة PatchURL لطلبات السحب مقابل قاعدة HTTP الخاصة بالاستنساخ). الهروب من دمج جذر النسخة الاحتياطية عبر DownloadURL المطلق (يبقى filepath.Join("/dump", "/etc/passwd") في Go عند /dump/etc/passwd). الاستعادة عبر HTTP دون مصادقة (عبر CLI / الرمز الداخلي فقط). حزم dump للنسخ الاحتياطي لـ app.ini (أسرار بحكم التصميم، وضع الأرشيف 0600). ليس تصعيدًا محليًا للصلاحيات على مستوى نظام التشغيل. ليس LFI عن بُعد.
كانت لديّ فكرتان للاستعادة. اختبرت فكرة الدمج المطلق في Gitea ذهنيًا أولًا. لا تُسقط دالة filepath.Join في Go وسيطًا ثانيًا مطلقًا كما تفعل os.path.join في Python. المدخل الفعّال هو .. النسبي. دالة localFileURL في Gitea غير موجودة في هذه الشجرة.
مسارات خاطئة سُجّلت بالفعل: هروب من الانضمام إلى جذر التفريغ عبر DownloadURL مطلق؛ ترحيل حيّ لـ file:// LFI؛ X-Forgejo-Internal-Auth (الاستعادة تتم عبر CLI بمعرّف مستخدم forgejo، وليس /api/internal)؛ التعامل مع استعادة HTTP كأنها غير مصادَق عليها عن بُعد؛ صدفة عكسية. مسرح.
python3 forgejo-restore-file-open-Abraxas-Labs.py
أو:
cd lab
./run.sh
استهدف فقط http://127.0.0.1:19340. الصورة codeberg.org/forgejo/forgejo:16.0.5. الشاهد FORGEJO-RESTORE-FILE-OPEN-WITNESS.
IOC asset name='witness.txt' ...
IOC download status=200 bytes=34 snippet=b'FORGEJO-RESTORE-FILE-OPEN-WITNESS\n'
SUCCESS forgejo-restore-file-open how=live ..-join file:// os.Open FORGEJO-RESTORE-FILE-OPEN-WITNESS
احتوِ المسارات المدمجة ضمن baseDir بعد EvalSymlinks (Gitea PR 38215 localFileURL). ارفض ... لا تتبع الروابط الرمزية من جهة التفريغ خارج التفريغ. أزل file:// من uri.Open باستثناء مساعد مُجذّر في التفريغ.
restore.go · uri.goGNU Affero GPL v3.0. انظر LICENSE. مختبر loopback فقط. دون أي ضمان.