JFrog از Xray Container Contextual Analysis برای اسکن ۲۰۰ تصویر محبوب جامعه در Docker Hub استفاده کرد، سپس نتایج را برای ۱۰ CVE معمولی محاسبه کرد. ۷۸ درصد قابل بهره برداری نبودند.
در طول توسعه تشخیص اسرار JFrog Xray، ما قابلیت های آن را با اسکن بیش از هشت میلیون مصنوع در رجیستری بسته های منبع باز محبوب آزمایش کردیم. به طور مشابه، برای ویژگی جدید Container Contextual Analysis JFrog Xray دوباره تشخیص خود را در یک مورد استفاده در مقیاس بزرگ و در دنیای واقعی آزمایش کردیم، هم برای حذف اشکالات و هم برای ارزیابی قابلیت حیات راه حل فعلی ما در دنیای واقعی.
با این حال، برخلاف نتایج شگفتانگیز که در تحقیقات کشف اسرار به دست آوردیم (ما توکنهای دسترسی فعالتر از آنچه که چانهزنی میکردیم کشف کردیم)، نتایج اسکنهای ما از تصاویر کانتینر Docker Hub در یک راستا بود. با آنچه که ما به عنوان مهندسان امنیتی برای سالیان متمادی شاهد بودیم.
یعنی، وقتی معیار یک سیستم آسیبپذیر به سادگی «بسته X نصب شده است» است، انتظار داریم بیشتر هشدارهای امنیتی مثبت کاذب باشند. و این دقیقاً برای CVE هایی بود که در تصاویر کانتینر در Docker Hub شناسایی کردیم.
در این پست روش تحقیق و یافتههای خود را به تفصیل شرح میدهیم و توصیههایی را برای توسعهدهندگان و متخصصان امنیتی ارائه میکنیم که به دنبال کاهش حجم موارد مثبت کاذب CVE هستند.
Exploitable در مقابل “بسته آسیب پذیر نصب شده است”
قبل از غواصی، اجازه دهید به طور خلاصه به چند نمونه آسیبپذیری نگاه کنیم تا مواردی را که در آن گزارش CVE ممکن است مثبت کاذب در نظر گرفته شود، حتی زمانی که یک مؤلفه آسیبپذیر وجود دارد، به طور خلاصه بررسی کنیم.
این به هیچ وجه فهرست جامعی نیست، اما برجسته ترین علل مثبت کاذب CVE را پوشش می دهد.
آسیب پذیری های کتابخانه
این واقعیت که نسخه آسیب پذیر Lodash نصب شده است، سیستم آسیب پذیر را تضمین می کند؟
خیر. طبق تعریف، ما نمیتوانیم تشخیص دهیم که آیا یک CVE در یک کتابخانه صرفاً با توجه به نصب بودن کتابخانه قابل بهرهبرداری است یا خیر. این به این دلیل است که یک کتابخانه یک موجودیت قابل اجرا نیست. باید کد دیگری در سیستم وجود داشته باشد که از کتابخانه به شکلی آسیب پذیر استفاده کند.
در مثال بالا، حتی اگر Lodash نصب شده باشد، ممکن است سیستم آسیب پذیر نباشد. باید کدی وجود داشته باشد که تابع آسیب پذیر، در این مورد template()
را از کتابخانه آسیب پذیر Lodash فراخوانی کند. در بیشتر موارد، حتی الزامات اضافی نیز وجود دارد، مانند اینکه یکی از آرگومان های ارسال شده به template()
توسط مهاجم کنترل شود.
سایر پیش نیازهای مرتبط با کد ممکن است شامل موارد زیر باشد:
- اینکه آیا یک تابع کاهش دهنده قبل از تابع آسیب پذیر فراخوانی می شود.
- آیا آرگومانهای خاص تابع آسیبپذیر روی مقادیر آسیبپذیر خاصی تنظیم شدهاند.
پیکربندی سرویس
آیا این واقعیت که نسخه آسیبپذیر Cassandra نصب شده است، سیستم آسیبپذیر را تضمین میکند؟
خیر. در اکثر آسیبپذیریهای سرویسهای مدرن (بهویژه آنهایی که تأثیر شدید دارند)، آسیبپذیری فقط در پیکربندیهای غیرپیشفرض سرویس ظاهر میشود. این به این دلیل است که پیکربندی پیش فرض و معقول اغلب توسط خود توسعه دهندگان یا به سادگی توسط کاربران واقعی سرویس مورد آزمایش قرار می گیرد.
در مثال بالا، برای دستیابی به اجرای کد از راه دور (RCE)، سرویس Cassandra باید با سه پرچم پیکربندی غیر پیشفرض پیکربندی شود (یکی از آنها بسیار نادر است).
سایر پیش نیازهای مرتبط با پیکربندی ممکن است شامل موارد زیر باشد:
- این که آیا مؤلفه با آرگومان های خط فرمان خاص یا متغیرهای محیطی اجرا می شود.
- آیا مؤلفه آسیبپذیر با پرچمهای ساخت خاص کامپایل شده است.
محیط در حال اجرا
آیا این واقعیت که نسخه آسیب پذیر Apache Hadoop نصب شده است، سیستم آسیب پذیر را تضمین می کند؟
خیر. در مثال بالا، آسیب پذیری فقط در یک محیط Microsoft Windows ظاهر می شود. بنابراین اگر جزء آسیب پذیر در یک محیط لینوکس نصب شده باشد، نمی توان از آن سوء استفاده کرد.
سایر پیش نیازهای مرتبط با محیط ممکن است عبارتند از:
- آیا مؤلفه آسیبپذیر در یک توزیع خاص (مثلاً دبیان) اجرا میشود
- این که آیا مؤلفه آسیبپذیر برای یک معماری خاص (مثلاً بازوی ۳۲ بیتی) کامپایل شده است.
- آیا فایروال ارتباط با سرویس آسیب پذیر را مسدود می کند.
روش تحقیق ما
در این تحقیق، با در نظر گرفتن دو تکنیک گزارشدهی، تلاش کردیم تا دریابیم چند درصد از گزارشهای آسیبپذیری واقعاً نشان میدهند که آسیبپذیری قابل بهرهبرداری است:
- ساده لوح. هر زمان که یک جزء آسیب پذیر در محدوده نسخه مربوطه (آسیب پذیر) نصب شود، آسیب پذیری گزارش می شود. امروزه تقریباً همه ابزارهای SCA اینگونه کار می کنند.
- حساس به متن. این آسیبپذیری تنها در صورتی گزارش میشود (یا قابل اجرا است) که زمینه تصویر نشاندهنده استفاده آسیبپذیر از مؤلفه باشد. این امر عواملی را که در بخش قبل مورد بحث قرار گرفت (پیش نیازهای کد، پیش نیازهای پیکربندی، محیط در حال اجرا) در نظر می گیرد.
ما علاقه مندیم موارد فوق را در محیط های معمولی در دنیای واقعی آزمایش کنیم، و این آزمایش را تا حد امکان در محیط های بیشتری انجام دهیم.
ما متوجه شدیم که با نگاه کردن به برترین تصاویر “انجمن” Docker Hub به دو دلیل باید هر دو درخواست را برآورده کرد:
- از این تصاویر بسیار مکرر استفاده می شود. به عنوان مثال، ۲۵ تصویر برتر در حال حاضر بیش از ۱ میلیارد دانلود دارند.
- تصاویر انجمن معمولاً حاوی یک مؤلفه جالب و کدی هستند که از مؤلفه تا حدی استفاده می کند که یک زمینه واقعی را فراهم می کند. این برخلاف تصاویر Docker “رسمی” است که معمولاً شامل اجزای مستقل هستند که بدون استفاده و در پیکربندی پیش فرض خود باقی می مانند. به عنوان مثال، یک وب سرور Nginx به خودی خود با پیکربندی پیشفرض احتمالاً در معرض هیچ CVE بزرگی نخواهد بود، اما یک سناریوی واقعی ارائه نمیکند.
بر اساس این عوامل، به روش شناسی زیر رسیدیم:
- ۲۰۰ تصویر برتر انجمن Docker Hub را در برچسب “آخرین” آنها بکشید.
- از بین این تصاویر، ۱۰ CVE “محبوب” برتر (مرتب شده بر اساس وقوع CVE در همه تصاویر) را جمع آوری کنید.
- تحلیل متنی ما را روی همه ۲۰۰ تصویر اجرا کنید.
- درصد نرخ مثبت کاذب روش ساده لوح را با تقسیم «رویدادهای غیرقابل اجرا» بر «کل رخدادها» برای هر یک از ۱۰ CVE برتر محاسبه کنید.
۱۰ CVE برتر چه بودند؟
و بنابراین ما ۲۰۰ تصویر برتر انجمن Docker Hub را اسکن کردیم. جدول زیر CVE هایی را که در بیشترین تعداد تصویر ظاهر شده اند فهرست می کند.
شناسه CVE |
CVSS |
توضیحات کوتاه |
CVE-2022-37434 |
۹.۸ |
zlib تا ۱.۲.۱۲ دارای یک بافر مبتنی بر پشته بیش از حد خوانده شده یا سرریز بافر در inflate(). فقط برنامههایی که inflateGetHeader را فراخوانی میکنند تحت تأثیر قرار میگیرند. |
CVE-2022-29458 |
۷.۱ |
ncurses 6.3 دارای نقض خواندن و تقسیم بندی خارج از محدوده در convert_strings() |
CVE-2021-39537 |
۸.۸ |
ncurses از طریق نسخه ۶.۲ nc_captoinfo() دارای سرریز بافر مبتنی بر پشته است |
CVE-2022-30636 |
نامعمول |
Golang x/crypto/acme/autocert: httpTokenCacheKey امکان پیمایش محدود فهرست را در ویندوز فراهم میکند |
CVE-2022-27664 |
۷.۵ |
Golang net/http قبل از ۱.۱۸.۶ DoS زیرا اتصال HTTP/2 ممکن است قطع شود |
CVE-2022-32189 |
۷.۵ |
Golang ریاضی/بزرگ قبل از ۱.۱۷.۱۳ Float.GobDecode و Rat.GobDecode DoS به دلیل وحشت |
CVE-2022-28131 |
۷.۵ |
Ecoding/xml Golang قبل از رسیور ۱.۱۷.۱۲. به دلیل فرسودگی پشته از DoS صرفنظر کنید |
CVE-2022-30630 |
۷.۵ |
Golang io/fs قبل از ۱.۱۷.۱۲ Glob DoS به دلیل بازگشت کنترل نشده |
CVE-2022-30631 |
۷.۵ |
فشرده سازی/gzip Golang قبل از ۱.۱۷.۱۲ Reader. به دلیل بازگشت کنترل نشده، DoS را بخوانید |
CVE-2022-30632 |
۷.۵ |
مسیر/فایل مسیر گلانگ قبل از ۱.۱۷.۱۲ Glob DoS به دلیل فرسودگی پشته |
شناسه CVE
CVSS
توضیحات کوتاه
CVE-2022-37434
۹.۸
zlib تا ۱.۲.۱۲ دارای یک بافر مبتنی بر پشته بیش از حد خوانده شده یا سرریز بافر در inflate().
فقط برنامههایی که inflateGetHeader را فراخوانی میکنند تحت تأثیر قرار میگیرند.
CVE-2022-29458
۷.۱
ncurses 6.3 دارای نقض خواندن و تقسیم بندی خارج از محدوده در convert_strings()
CVE-2021-39537
۸.۸
ncurses از طریق نسخه ۶.۲ nc_captoinfo() دارای سرریز بافر مبتنی بر پشته است
CVE-2022-30636
نامعمول
Golang x/crypto/acme/autocert: httpTokenCacheKey امکان پیمایش محدود فهرست را در ویندوز فراهم میکند
CVE-2022-27664
۷.۵
Golang net/http قبل از ۱.۱۸.۶ DoS زیرا اتصال HTTP/2 ممکن است قطع شود
CVE-2022-32189
۷.۵
Golang ریاضی/بزرگ قبل از ۱.۱۷.۱۳ Float.GobDecode و Rat.GobDecode DoS به دلیل وحشت
CVE-2022-28131
۷.۵
Ecoding/xml Golang قبل از رسیور ۱.۱۷.۱۲. به دلیل فرسودگی پشته از DoS صرفنظر کنید
CVE-2022-30630
۷.۵
Golang io/fs قبل از ۱.۱۷.۱۲ Glob DoS به دلیل بازگشت کنترل نشده
CVE-2022-30631
۷.۵
فشرده سازی/gzip Golang قبل از ۱.۱۷.۱۲ Reader. به دلیل بازگشت کنترل نشده، DoS را بخوانید
CVE-2022-30632
۷.۵
مسیر/فایل مسیر گلانگ قبل از ۱.۱۷.۱۲ Glob DoS به دلیل فرسودگی پشته
چند CVE واقعاً قابل بهره برداری بودند؟
ما عمداً انتخاب کردیم که اسکنرهای متنی را در محافظهکارانهترین تنظیمات آنها اجرا کنیم — در بخش بعدی بیشتر در مورد آن توضیح خواهیم داد.
اسکنر متنی برای هر CVE همانطور که در جدول زیر توضیح داده شده است.
تعریف شده است
شناسه CVE |
اسکنر متنی |
CVE-2022-37434 |
کد شخص اولی را بررسی کنید که “inflateGetHeader” و “inflate” را فراخوانی می کند |
CVE-2022-29458 |
بررسی فراخوانی های ابزار CLI ncurses “tic” |
CVE-2021-39537 |
بررسی فراخوانی برنامه CLI ncurses “cap2info” |
CVE-2022-30636 |
سیستم عامل Windows + کد شخص اول را بررسی کنید که “autocert.NewListener” یا ارجاع به “autocert.DirCache” را صدا می کند |
CVE-2022-27664 |
کد شخص اولی را بررسی کنید که “ListenAndServeTLS” را صدا می کند (HTTP/2 فقط از طریق TLS در دسترس است) |
CVE-2022-32189 |
کد شخص اولی را بررسی کنید که “Rat.GobDecode” یا “Float.GobDecode” را صدا می کند |
CVE-2022-28131 |
کد شخص اولی را بررسی کنید که “Decoder.Skip” را صدا می کند |
CVE-2022-30630 |
کد شخص اولی را بررسی کنید که “fs.Glob” را با ورودی غیر ثابت فراخوانی میکند |
CVE-2022-30631 |
کد شخص اولی را بررسی کنید که “gzip.Reader.Read” را صدا می کند |
CVE-2022-30632 |
کد شخص اولی را بررسی کنید که “filepath.Glob” را با ورودی غیر ثابت فراخوانی میکند |
شناسه CVE
اسکنر متنی
CVE-2022-37434
کد شخص اولی را بررسی کنید که “inflateGetHeader” و “inflate” را فراخوانی می کند
CVE-2022-29458
بررسی فراخوانی های ابزار CLI ncurses “tic”
CVE-2021-39537
بررسی فراخوانی برنامه CLI ncurses “cap2info”
CVE-2022-30636
سیستم عامل Windows + کد شخص اول را بررسی کنید که “autocert.NewListener” یا ارجاع به “autocert.DirCache” را صدا می کند
CVE-2022-27664
کد شخص اولی را بررسی کنید که “ListenAndServeTLS” را صدا می کند (HTTP/2 فقط از طریق TLS در دسترس است)
CVE-2022-32189
کد شخص اولی را بررسی کنید که “Rat.GobDecode” یا “Float.GobDecode” را صدا می کند
CVE-2022-28131
کد شخص اولی را بررسی کنید که “Decoder.Skip” را صدا می کند
CVE-2022-30630
کد شخص اولی را بررسی کنید که “fs.Glob” را با ورودی غیر ثابت فراخوانی میکند
CVE-2022-30631
کد شخص اولی را بررسی کنید که “gzip.Reader.Read” را صدا می کند
CVE-2022-30632
کد شخص اولی را بررسی کنید که “filepath.Glob” را با ورودی غیر ثابت فراخوانی میکند
–
اجرای اسکنرهای متنی روی هر ۲۰۰ تصویر، نتایج زیر را در هر CVE به ما داد.
و هنگامی که نتایج تمام ۱۰ CVE برتر را با هم جمع کردیم، این چیزی است که کشف کردیم:
۷۸% موارد CVE غیرقابل اجرا بودند!
نگاهی به محدودیت های فعلی تحلیل زمینه
بیایید CVE-2022-30631 را بررسی کنیم، که نرخ کاربرد بسیار بالایی داشت.
CVE-2022-30631 تنها موردی بود که از ۵۰٪ قابلیت اجرا گذشت. به زبان ساده، پیش نیاز برای بهرهبرداری از این CVE این است که “Golang برای استخراج یک آرشیو gzip کنترل شده توسط مهاجمان استفاده میشود.” در واقع، اگر کد Golang شخص اول سعی کند هر بایگانی gzip را استخراج کند، اسکنر هشدار می دهد. این به این دلیل است که تضمین اینکه یک فایل توسط مهاجم کنترل میشود یا نه، به دلیل تعداد زیادی از منابع احتمالی که روی فایل تأثیر میگذارند، کار بسیار سختی است.
هنگام تلاش برای تعیین اینکه آیا یک متغیر از ورودی ثابت می آید یا ورودی خارجی/مهاجم، این را می توان به عنوان مثال از طریق تجزیه و تحلیل جریان داده به دست آورد. تجزیه و تحلیل جریان داده توسط برخی از اسکنرهای ما انجام میشود، برای مثال، CVE-2022-30630 را شناسایی میکند، که نرخ کاربرد بسیار پایینتری داشت.
اما هنگام برخورد با فایلها، حتی اگر آرگومان مسیر فایل تابع ثابت باشد، هیچ تضمینی وجود ندارد که فایل توسط مهاجم کنترل نشود و بالعکس. بنابراین، ما انتظار داریم که کاربرد این CVE در دنیای واقعی حتی کمتر باشد.
چرا ۷۸٪ در واقع یک عدد محافظه کار است
از مثال بالا، میتوانیم ببینیم که برخی از CVEها ممکن است دارای نرخ کاربرد اغراقآمیز باشند، به این معنی که کاربرد در دنیای واقعی ممکن است حتی کمتر باشد. بحث در مورد اینکه چرا (در حالت معمول) هنوز منطقی است که اسکنرهای محافظه کارانه را اجرا کنیم، مهم است. دو دلیل برای این وجود دارد: اول، به این دلیل که ما مثبت کاذب را به منفی کاذب ترجیح می دهیم، و دوم، به دلیل ملاحظات عملکرد.
ترجیح به مثبت کاذب و نه منفی کاذب
هر فناوری محدودیتهای خود را دارد، و این در هنگام تلاش برای حل مشکلات محاسباتی غیرممکن مانند “آیا یک ورودی خاص توسط منابع خارجی قابل کنترل است.” در موارد خاص (موارد ساده تر)، می توانیم مفروضات خاصی داشته باشیم که محاسبه راه حل را با اطمینان بسیار بالا ممکن می کند.
اما، در موارد دیگر (سخت تر)، که اطمینان ۱۰۰٪ تضمین نشده است، باید دو کار انجام دهیم:
- اسکنرهایی را ترجیح دهید که تمایل به نشان دادن مثبت کاذب دارند (در مورد ما، نتایج را به عنوان قابل اجرا نشان می دهند، در حالی که در واقعیت نیستند). این کار به این دلیل انجام می شود که در این حالت، نتیجه توسط یک مهندس بررسی می شود و ارزیابی می شود که آیا واقعاً قابل اجرا است یا خیر. در حالت مخالف، جایی که آسیبپذیری بهعنوان غیرقابل اجرا علامتگذاری میشود، مهندس فرض میکند که میتوان آن را نادیده گرفت و بنابراین آسیبپذیری آسیبپذیر باقی میماند، که سناریوی بسیار شدیدتری است.
- در صورت امکان، نرخ اطمینان و/یا دلیل اعتماد پایین به یک یافته خاص را ارائه دهید، به طوری که حتی نتایج قابل اجرا نیز می توانند توسط مهندسین امنیت/توسعه اولویت بندی شوند.
ملاحظات عملکرد
یک اسکنر زمینهای که مبتنی بر تجزیه و تحلیل جریان داده است (به عنوان مثال، اسکنر که سعی میکند تعیین کند که آیا آرگومان یک تابع خاص از ورودی کنترلشده توسط مهاجم میآید یا خیر) همیشه در اجرای خود گزینهای دارد که آیا دقیقتر ارائه کند. نتایج یا برای دویدن سریعتر. به عنوان مثال، دقیق ترین نوع اسکنر زمینه حداقل باید:
- هنگامی که میخواهید یک نمودار جریان داده درون ماژول بین منبع کنترلشده توسط مهاجم و سینک درخواستی ایجاد کنید، عمق تماس بینهایت را در نظر بگیرید.
- هنگام ساختن نمودار جریان داده، تماس های بین ماژول را در نظر بگیرید.
این عملیات زمان اجرای اسکنر را بسیار افزایش میدهد.
هنگامی که با مقدار زیادی از مصنوعات اسکن شده در دقیقه سروکار داریم (همانطور که ممکن است از یک نمونه JFrog Artifactory/Xray درخواست شود) باید تعادل ظریفی بین دقت و سرعت اسکنر زمینه ایجاد کنیم.
حتی با در نظر گرفتن محدودیتهای مورد بحث، ۷۸% هنوز تعداد انبوه آسیبپذیریهایی است که میتوان آنها را از اولویت خارج کرد یا نادیده گرفت. علاوه بر این، ما انتظار داریم که با پیشرفت فناوری و با کشف کمتر CVE های «قابل اجرا به طور پیش فرض»، این عدد بیشتر شود.
پست های مرتبط
اکثر CVE های گزارش شده برای تصاویر Docker Hub بی ضرر هستند
اکثر CVE های گزارش شده برای تصاویر Docker Hub بی ضرر هستند
اکثر CVE های گزارش شده برای تصاویر Docker Hub بی ضرر هستند