یک زنجیره آسیبپذیری در GitLab به کاربران عادی اجازه میدهد بدون نیاز به دسترسی مدیر، دستورات دلخواه را روی سرور هدف اجرا کنند.
به گزارش افتانا، پژوهشگران امنیتی شرکت depthfirst در ۲۴ ژوئیه کد اثبات مفهوم (PoC) یک آسیبپذیری در GitLab را منتشر کردند؛ نقصی که GitLab حدود شش هفته قبل، در ۱۰ ژوئن، آن را بیسروصدا برطرف کرده بود. این آسیبپذیری به مهاجمی که تنها یک حساب کاربری عادی داشته و امکان Push کردن کد به یک پروژه را دارد، اجازه میدهد روی سرورهای خودمیزبان GitLab نسخه 18.11.3 که هنوز بهروزرسانی نشدهاند، دستورات دلخواه را با سطح دسترسی کاربر git اجرا کند.
برای سوءاستفاده از این نقص، کافی است مهاجم یک فایل Jupyter Notebook دستکاریشده را در مخزن ثبت کرده و سپس صفحه نمایش تغییرات (Commit Diff) همان فایل را باز کند. این فرآیند باعث افشای یک اشارهگر از حافظه (Heap Pointer) میشود و با تکرار این کار، اسکریپت مهاجم میتواند محل قرارگیری کتابخانههای سیستم در حافظه را پیدا کند. پس از آن، تنها با ارسال دو فایل Notebook دیگر، اجرای کد از راه دور انجام میشود. این حمله نیازی به دسترسی مدیر سیستم، CI/CD، GitLab Runner، تعامل کاربر یا حتی دسترسی به پروژههای سایر کاربران ندارد.
نکته قابل توجه این است که GitLab هنگام انتشار وصله امنیتی، آن را بهعنوان یک اصلاح امنیتی معرفی نکرد. بررسیهای رسانهای نشان میدهد که ارتقای کتابخانه Oj به نسخه 3.17.3 فقط در بخش رفع باگهای عادی نسخه ۱۰ ژوئن ثبت شده بود و هیچ اشارهای به این زنجیره حمله، شناسه CVE یا امتیاز CVSS در جدول اصلاحات امنیتی دیده نمیشد. به همین دلیل، بسیاری از مدیران سیستم که صرفاً اصلاحات امنیتی را بررسی میکردند، دلیلی برای نصب فوری این بهروزرسانی نداشتند. ریشه این زنجیره حمله، دو آسیبپذیری فساد حافظه در کتابخانه Oj است؛ یک مفسر JSON برای زبان Ruby که بخش عمده آن با زبان C توسعه یافته است. پژوهشگران depthfirst اعلام کردند سامانه خودکار آنها این دو نقص را شناسایی کرده و سپس بهصورت دستی آنها را به یک زنجیره بهرهبرداری تبدیل کردهاند. در GitLab، بخشی به نام ipynbdiff که وظیفه نمایش تفاوت فایلهای Jupyter Notebook را بر عهده دارد، محتوای فایلهای .ipynb را با استفاده از Oj::Parser.usual.parse پردازش میکند. از آنجا که این پردازش داخل فرآیند طولانیمدت Puma انجام میشود، دادههای کنترلشده توسط مهاجم مستقیماً وارد حافظهای میشوند که کتابخانه Oj بهصورت دستی مدیریت میکند. یکی از این دو نقص باعث میشود دادهها از یک پشته ثابت ۱۰۲۴ بایتی عبور کرده و در نهایت کنترل تابع آغازگر Parser را در اختیار مهاجم قرار دهند. نقص دوم نیز هنگام پردازش یک کلید بسیار بزرگ در JSON، طول آن را به اشتباه در یک فیلد ۱۶ بیتی ذخیره کرده و در نتیجه یک اشارهگر معتبر از حافظه را بازمیگرداند؛ اشارهگری که GitLab آن را در صفحه نمایش تغییرات فایل نشان میدهد. همین نشتی حافظه محل قرارگیری کتابخانه libc را مشخص میکند و در ادامه، نقص اول مسیر اجرای تابع system() را برای اجرای دستورات دلخواه فراهم میسازد.
تمام نسخههای GitLab Community Edition و Enterprise Edition از نسخه 15.2.0 تا 18.10.7، همچنین نسخههای 18.11.0 تا 18.11.4 و 19.0.0 تا 19.0.1 تحت تأثیر این آسیبپذیری قرار دارند. این مشکل در نسخههای 18.10.8، 18.11.5 و 19.0.2 برطرف شده است. همچنین کتابخانه Oj از نسخه 3.13.0 تا 3.17.1 آسیبپذیر بوده و رفع کامل آن در نسخه 3.17.3 انجام شده است. این نقص ارتباطی با خود زبان Ruby ندارد و تمامی نسخههای GitLab، از Free تا Ultimate، را تحت تأثیر قرار میدهد.
تنها راهکار رسمی، ارتقای GitLab به یکی از نسخههای اصلاحشده است. نه GitLab و نه depthfirst هیچ راهکار پیکربندی معتبری برای غیرفعال کردن کامل مسیر آسیبپذیر مربوط به نمایش تفاوت فایلهای Notebook ارائه نکردهاند. یوهانگ وو، پژوهشگر depthfirst، میگوید اگر بتوان دسترسی کاربران غیرقابل اعتماد به قابلیت نمایش تفاوت فایلهای Notebook را محدود کرد، این مسیر حمله از بین میرود، اما تاکنون هیچ راهکار رسمی و تأییدشدهای برای این کار وجود ندارد و مدیران سیستم باید برای راهنمایی بیشتر با GitLab مشورت کنند. پژوهشگران همچنین هشدار دادهاند که مدیران نباید تنها به نسخه Helm Chart یا GitLab Operator توجه کنند، بلکه باید نسخه واقعی GitLab را در تصویر Webservice که فرآیند Puma را اجرا میکند بررسی کنند. علاوه بر این، شاخههای قدیمیتر از نسخه 18.10 دیگر تحت پشتیبانی امنیتی GitLab نیستند و هیچ وصلهای برای آنها منتشر نخواهد شد؛ بنابراین این سامانهها باید به نسخههای پشتیبانیشده ارتقا پیدا کنند.
دستورات مخرب در نهایت با سطح دسترسی کاربر git اجرا میشوند؛ همان حساب کاربری که فرآیند Puma از آن استفاده میکند. میزان خسارت به نحوه ایزولهسازی محیط بستگی دارد، اما مهاجم ممکن است به کدهای منبع، کلیدها و اسرار Rails، اطلاعات سرویسها، دادههای CI/CD و حتی سرویسهای داخلی قابل دسترس از سمت برنامه دسترسی پیدا کند. اثبات مفهوم منتشرشده بهطور خاص برای GitLab 18.11.3 روی معماری x86-64 طراحی شده است و آدرسهای حافظه، گجتها و رفتار تخصیصدهنده حافظه آن بر اساس همین نسخه تنظیم شدهاند. با این حال، یوهانگ وو تأکید کرده است که اصل روش بهرهبرداری محدود به این نسخه نیست و انتقال آن به نسخههای نزدیک GitLab روی همان معماری معمولاً تنها به تغییر چند آدرس و Offset نیاز دارد، زیرا بیشتر گجتها متعلق به Ruby و کتابخانههای سیستم هستند، نه خود GitLab. البته انتقال این حمله به معماری ARM64 به دلیل تفاوت در نحوه فراخوانی توابع، گجتها، ثباتها و رفتار حافظه، به تلاش بیشتری نیاز خواهد داشت. پژوهشگران اعلام کردهاند جستوجوی فضای حافظه روی یک نصب تازه GitLab با دو Worker حدود ۵ تا ۱۰ دقیقه زمان میبرد و در سامانههایی که مدت طولانیتری فعال بودهاند، این زمان ممکن است به یک تا دو ساعت برسد.
بررسی این آسیبپذیری از ۲۱ می آغاز شد؛ زمانی که depthfirst مشکلات موجود در کتابخانه Oj را به توسعهدهنده آن گزارش کرد. اصلاحات در ۲۷ مه پذیرفته شد و نسخه 3.17.3 کتابخانه در ۴ ژوئن منتشر شد. زنجیره حمله مخصوص GitLab نیز در ۵ ژوئن به این شرکت گزارش شد، سه روز بعد تأیید شد و در ۱۰ ژوئن وصله آن منتشر شد. به گفته یوهانگ وو، برای هیچیک از این آسیبپذیریها شناسه CVE درخواست نشده و برنامه HackerOne نیز شناسه جداگانهای برای این زنجیره حمله اختصاص نداده است. او تأکید میکند که نبود CVE به هیچ عنوان به معنای کماهمیت بودن این نقص نیست و صرفاً نتیجه نحوه هماهنگی فرآیند افشا بوده است.
پژوهشگران depthfirst اعلام کردهاند تاکنون هیچ مدرکی از سوءاستفاده این آسیبپذیری در حملات واقعی مشاهده نشده است و GitLab نیز این آسیبپذیری را بهصورت مستقل بازتولید کرده است. با این حال، آنها تأکید میکنند که این نتیجه تنها بر اساس نبود گزارشهای عمومی و مشاهدات خودشان است و چون به دادههای مشتریان GitLab یا سامانههای داخلی این شرکت دسترسی ندارند، تنها GitLab میتواند درباره وجود یا نبود حملات واقعی اظهار نظر قطعی کند. همچنین بررسی گستردهتر آنها روی کتابخانه Oj به شناسایی ۹ آسیبپذیری دیگر منجر شده که همگی دارای شناسه CVE هستند، اما این زنجیره حمله GitLab در میان آنها قرار ندارد.