
CVE-2017-8291 CTF مع Docker وأمثلة
تتأثر وحدة PIL (Pillow) لمعالجة الصور في Python بثغرة GhostButt (CVE-2017-8291) لأنها تستدعي GhostScript داخليًا، مما يؤدي إلى ثغرة تنفيذ أوامر عن بُعد.
تحدد PIL داخليًا نوع الصورة بناءً على رأس الصورة (البايتات السحرية). إذا تبين أنها ملف EPS (الرأس هو %!PS)، يتم توجيهها إلى PIL/EpsImagePlugin.py للمعالجة.
في هذه الوحدة، تستدعي PIL أمر gs الخاص بالنظام، وهو GhostScript، لمعالجة ملفات الصور:
command = ["gs",
"-q", # وضع هادئ
"-g%dx%d" % size, # تعيين هندسة الإخراج (بكسل)
"-r%fx%f" % res, # تعيين نقطة الإدخال لكل بوصة
"-dBATCH", # الخروج بعد المعالجة
"-dNOPAUSE", # لا تتوقف بين الصفحات
"-dSAFER", # الوضع الآمن
"-sDEVICE=ppmraw", # مشغل ppm
"-sOutputFile=%s" % outfile, # ملف الإخراج
"-c", "%d %d translate" % (-bbox[0], -bbox[1]),
# ضبط أصل الصورة
"-f", infile, # ملف الإدخال
]
# تم حذف الكود الخاص بتحديد ما إذا كان GhostScript مثبتًا
try:
with open(os.devnull, 'w+b') as devnull:
subprocess.check_call(command, stdin=devnull, stdout=devnull)
im = Image.open(outfile)
على الرغم من تعيين -dSAFER، أي الوضع الآمن، بسبب ثغرة تجاوز وضع الحماية في GhostScript (GhostButt CVE-2017-8291)، يتم تجاوز هذا الوضع الآمن ويمكن تنفيذ أوامر عشوائية.
بالإضافة إلى ذلك، حتى الآن، لا يزال الإصدار الرسمي الأحدث من GhostScript 9.21 متأثرًا بهذه الثغرة، لذا يمكن القول أنه طالما تم تثبيت GhostScript على نظام التشغيل، فإن PIL لدينا لديها ثغرة تنفيذ أوامر.
بيئة التشغيل:
docker-compose up -d
بعد التشغيل، قم بزيارة http://your-ip:8000/ لرؤية صفحة رفع. الوظيفة العادية هي أن نرفع ملف PNG، ويستدعي الخلفية PIL لتحميل الصورة، ويخرج الطول والعرض. ولكن يمكننا تغيير لاحقة ملف EPS القابل لتنفيذ الأوامر إلى PNG للرفع، لأن الخلفية تحدد نوع الصورة بناءً على رأس الملف، لذلك يتم تجاهل فحص اللاحقة.
على سبيل المثال، إذا قمنا برفع poc.png، يمكننا تنفيذ touch /tmp/youhavebeenpwned. قم بتغيير الأمر في POC إلى أمر ارتدادي للحصول على شيل: