
تنفيذ استغلال CVE-2018-16858
في هذا المقال سنرى كيفية استخدام خلل بسيط في برنامج لفتح باب خلفي (backdoor) في النظام الذي يستخدم هذا البرنامج.
الخلل المعني هو CVE-2018-16858 الخاص بحزمة LibreOffice المكتبية. يحقق هذا الخلل، في ملف مصمم خصيصًا، تصعيدًا للمسارات (directory traversal)، مما يسمح بتنفيذ كود Python. يتم ربط هذا التنفيذ أو تشغيله عند تفاعل المستخدم مع المستند، ويتم دون إعطاء أي تحذير للمستخدم بشأن تنفيذ الماكرو.
ينقسم هذا المستند إلى خمسة أجزاء. في الجزء الأول، سنشرح الخلل نفسه، وكيفية فك حزمة مستند OpenDocument، وكيفية تغيير هيكله لتنفيذ السكريبت المحلي المطلوب، وكيفية إعادة تجميع المستند مرة أخرى لتنفيذه واختباره.
في الجزء الثاني سنرى كيفية استخدام التنفيذ المحلي لتشغيل أي أمر على النظام الذي يفتح فيه المستند، وسننشئ بابًا خلفيًا يسمح بتنفيذ الأوامر عن بعد.
في الجزء الثالث سنقوم بأتمتة العملية لإنشاء مستندات تنشئ أبوابًا خلفية باتصال مباشر أو عكسي، مع تحديد عنوان IP والمنفذ الذي يجب الاتصال به.
سيتناول الجزء الرابع دمج الخلل في نظام metasploit بحيث يمكن من خلال msfconsole إنشاء مستندات متوافقة مع طريقة استغلال metasploit. بهذا يمكن اختيار أي payload محدد في حزمة metasploit لتنفيذه.
الجزء الخامس والأخير سيوضح كيفية دمج عملية الكشف في نظام مضاد الفيروسات للتعرف على ملفات LibreOffice المصابة بالإجراء السابق. سيتم استخدام تنسيق الكشف لمضاد الفيروسات ClamAV، مما يساعد على فهم أفضل لعملية الكشف لدى مضادات الفيروسات وبالتالي تسهيل حمايتنا من التهديدات من هذا النوع.
سيتم تنفيذ العملية بأكملها لأنظمة Linux المبنية على Debian، ولكن ما يُشرح هنا يمكن تطبيقه على أنظمة أخرى لأنه موصوف بالتفصيل. تم تنفيذ الخلل وإثباتات المفهوم (PoC) لـ CVE الأصلي على إصدار LibreOffice لنظام Windows، لذلك يمكن دائمًا الرجوع إلى هذا المصدر لاستخدام ما هو موصوف في هذا المستند بشكل مشابه لإصدارات Windows.
LibreOffice (وبسبب الأسباب الجينية، Apache OpenOffice) يحتوي على خلل في الإصدارات التي تسبق أحدث إصدار (6.1.5) يسمح بتنفيذ كود Python موجود في أي مكان على الحاسوب دون تنبيه المستخدم من تنفيذ ماكرو.
لمشاهدة الخلل المعني، يمكننا إنشاء مستند جديد في محرر النصوص، نكتب فيه شيئًا، نحدده، وننشئ رابطًا تشعبيًا. لإنشاء رابط تشعبي في النص، نختار قائمة Insert ثم الخيار Hyperlink (يمكن أيضًا بالضغط على Ctrl+K بعد تحديد النص).
سيظهر الحوار التالي:

لتعريف رابط تشعبي، يجب إدخال URL والنقر على Apply. بالإضافة إلى خيار URL في الجزء السفلي من مربع الحوار، حيث يمكن قراءة Further Settings، سيكون لدينا زر مع أيقونة Play يتيح لنا أيضًا ربط الأحداث بإجراءات معينة. هنا نحدد أننا نريد تنفيذ كود Python كإجراء.
عند الضغط على هذا الزر، سيتم فتح حوار جديد:

فيه يمكننا الاختيار من بين ثلاثة أحداث أساسية والسكريبت الذي نريد استخدامه. سنختار Mouse Over Object كحدث وكسكريبت من سكريبتات عائلة LibreOffice Macros سنختار Python Samples. ضمن هذا الخيار يوجد سكريبت افتراضي واحد فقط يسمى TableSample، وهو الذي سنختاره.
بعد القيام بذلك، إذا مررنا الماوس فوق النص الذي حولناه إلى رابط تشعبي، سنرى أن نافذة تفتح بمستند يحتوي على جدول. هذا يعني أننا ربطنا حدث تمرير الماوس فوق الرابط التشعبي بسكريبت Python. ما نهدف إليه هو استبدال هذا الإجراء بآخر نريده.
للقيام بذلك، سنحفظ المستند الذي أنشأناه ونخرج من LibreOffice لتنفيذ سلسلة من الأوامر في وحدة التحكم.
تنسيق المستند ODT ليس أكثر من ملف zip يحتوي على سلسلة من الملفات بداخله (تنسيق DOCX من Microsoft Office مشابه جدًا). لذلك، أول ما سنفعله هو فك ضغط الملف باستخدام برنامج فك ضغط zip.
في حالتنا، سنستخدم أداة سطر الأوامر المسماة unzip، لذا سننفذ ببساطة العبارة التالية:
user@host:~/Documents/prueba$ unzip ~/Documents/blog/exploitlibreoffice/doc/CV.odt
بهذا سنرى الملفات التي يحتويها فعليًا ملف من نوع OpenDocument. الأكثر أهمية بالنسبة لنا هي ملف mimetypes وملف content.xml وملف styles.xml.
ملف mimetype هو أول ملف يجب أن يظهر في قائمة ملفات zip، لذلك عندما نعيد تجميع الملفات، يجب أن نجبر أداة التجميع على ذلك وإلا لن يتم تفسير الملف على أنه OpenDocument.
ملف content.xml يحتوي على نص المستند الذي كتبناه، حيث يوجد نص ممزوج بعلامات معينة تخبرنا بالشكل الذي يجب أن يظهر به النص.
على سبيل المثال، في السطر التالي:
<text:p text:style-name="_5f_ECV_5f_SectionDetails">Indicar lista de documentos adjuntos a su CV. Ejemplos:</text:p>
يمكن ملاحظة مثال على فقرة نصية مكتوبة بنمط معين محدد بواسطة السمة text:style-name. فقرة النص موجودة بين علامة الفتح text:p وعلامة الإغلاق </text:p>.
يمكن أيضًا رؤية السكريبت المرتبط بالرابط التشعبي الذي أنشأناه بسهولة. إذا بحثنا في نص content.xml عن كلمة python أو اسم سكريبت python الذي حملناه، في حالتنا TableSample.py، يمكن بسهولة اكتشاف السطر الذي يجب تغيير محتواه:
<script:event-listener script:language="ooo:script" script:event-name="dom:mouseover" xlink:href="vnd.sun.star.script:pythonSamples|TableSample.py$createTable?language=Python&location=share" xlink:type="simple"/>
في هذا السطر يوجد مسار سكريبت python الذي سيتم تحميله عند وضع الماوس فوق الرابط التشعبي المسمى TableSample.py والدالة التي سيتم تنفيذها من كود python، في هذه الحالة createTable.
المشكلة الكامنة في LibreOffice هي أنه عند قراءة المستندات لا يتم تنظيف قيمة كود python المراد تحميله بشكل صحيح. البرنامج لا ينظف الأحرف ../ من مسار الملف، لذلك يمكن الوصول إلى أي ملف على النظام الذي يفتح فيه المستند النصي. بالإضافة إلى ذلك، إذا كان الملف الذي يتم الوصول إليه هو ملف يحتوي على كود python، يمكننا تنفيذ أي دالة معرفة في ذلك الملف.
كأول إثبات للمفهوم، سنجعل عند المرور فوق الرابط التشعبي يتم تشغيل الآلة الحاسبة، في حالتنا برنامج galculator يفتح الآلة الحاسبة. يجب إنشاء برنامج python يسمح بتنفيذ أمر داخل دالة، على غرار ما يتوقعه LibreOffice. للقيام بذلك، سننشئ الكود التالي في المسار /tmp/prueba.py:
import os;
def ejecuta():
os.system("galculator");
بهذا الكود الصغير سنحقق هدفنا، الآن فقط نحتاج إلى إضافة كل من ملف python /tmp/prueba.py واسم الدالة ejecuta داخل الاستدعاء الموجود في ملف odt. لذلك سيكون السطر الذي كان يستدعي python على النحو التالي:
<script:event-listener script:language="ooo:script" script:event-name="dom:mouseover" xlink:href="vnd.sun.star.script:pythonSamples|../../../../../../../../../../../tmp/prueba.py$ejecuta?language=Python&location=share" xlink:type="simple"/>
كما ترون، ما قمنا به هو إضافة عدد كبير من ../ للتأكد من أننا نصعد إلى جذر نظام الملفات لدينا. ومن هناك نضيف المسار المحدد إلى ملف python الخاص بنا (prueba.py). بعد $ أضفنا كلمة ejecuta وهي الدالة التي تقوم بتشغيل الآلة الحاسبة.
بعد القيام بذلك، سنقوم بتجميع ملف odt مرة أخرى مع تذكر وضع ملف mimetype كأول ملف. إذا استخدمنا أداة zip، سننفذ الأمر التالي في الدليل الذي فككنا فيه ملف odt ويحتوي على content.xml الخبيث:
user@host:~/Documents/prueba$ zip -r exploit.odt mimetype .
بعد القيام بذلك، سنفتح الملف باستخدام LibreOffice وسنلاحظ أنه يتم تشغيل برنامج الآلة الحاسبة عندما نمرر الماوس فوق الرابط التشعبي.
هذه الخطوة الأولى تحتاج إلى كود python تم إنشاؤه بدالة يمكننا تنفيذها بدون معاملات. إنه سهل التنفيذ ولكن قد يكون من الصعب استخدامه في بيئة قابلة للتصديق أو التكرار لاختبار اختراق حقيقي.
منذ الإصدار 6.1 من LibreOffice، توجد إمكانية تمرير معاملات إلى دوال python عند استدعائها. هذا يسمح بحرية أكبر في كتابة السكريبتات لمن يرغبون في الاستخدام المشروع للماكرو في هذا البرنامج، ولكنه يوفر لنا أيضًا فرصة ذهبية لمن يرغبون في البحث عن زوايا البرنامج.