افهم مخاطر السياسات. اطرح أسئلتك حول السياسات بلغة طبيعية. اطلب عرضًا توضيحيًا ←

Published:

تقنيات متقدمة للدفاع عن AWS ExternalID والوصول عبر AssumeRole بين الحسابات

by FireMon

في الشهر الماضي، نشر Kesten Broughton من Praetorian Security بحثًا مهمًا حول منتجات أمن السحابة المقدَّمة من أطراف ثالثة والتي تستخدم أسلوب الاتصال بين الحسابات المفضَّل لدى Amazon - ثغرات AWS IAM Assume Role المكتشفة لدى العديد من كبار المورّدين. وتقدّم الفقرة الافتتاحية نظرة عامة وافية على البحث:

في هذه المدونة الأولى من سلسلتنا حول الثقة بين الحسابات، سنعرض النتائج المستخلصة من 90 مورّدًا والتي تُظهر أن 37% منهم لم يطبّقوا ExternalId بالشكل الصحيح للحماية من هجمات النائب المُرتبك (confused-deputy). كما أن 15% إضافية من المورّدين طبّقوا تكامل حساب AWS في واجهة المستخدم بشكل صحيح، لكن معامل ExternalId لم يخضع للتحقق السليم في الواجهة الخلفية، مما جعل تلك المواقع عرضة للخطر أيضًا. وسنختم بمناقشة أسطح الهجوم الجديدة التي كشفتها ثقة cross-account-assume-role في AWS. ونخلص إلى أنه ينبغي للمورّدين والعملاء أن يفحصوا بعناية ما إذا كانت ثقة الأدوار هي آلية الثقة الأفضل لحلول SaaS متعددة المستأجرين لديهم.

كان ردّ فعلي الأول عند قراءة البحث هو: "لماذا قد يتخذ أحد قرارًا سيئًا كهذا؟"، غير أن الحقيقة أن مفهوم "خبير أمن السحابة" برمّته حديث نسبيًا، وبينما تتناول AWS مشكلة النائب المُرتبك بشكل مقبول، فإنها لا تغطي بعض المسائل العملية المترتبة التي لا تخطر ببالك فعليًا إلا عندما يتصل منتجك بالعميل. وللاتصالات بين الحسابات باستخدام AssumeRole حلّ هندسي مباشر، لكن من دون نمذجة تهديدات سليمة يسهل جدًا الوقوع في الأخطاء الموثّقة في بحث Kesten.

لقد اتخذنا هنا في DisruptOps بعض القرارات الذكية في وقت مبكر استنادًا إلى نمذجة التهديدات الأولية لدينا، وهو ما أبقانا في مأمن. ومع ذلك، استفدنا من بعض المعلومات الواردة في البحث ونعمل على إضافة مزيد من التحصين. كما لدينا مشروع تطويري سري يقضي على جزء كبير من المشكلة على أي حال، مع الاستمرار في تمكين الأتمتة على نطاق واسع دون الحاجة إلى وصول كتابة مباشر إلى بيئات العملاء.

غير أن لديّ نقطة خلاف رئيسية واحدة مع المقال. فأنا أفضّل بيانات الاعتماد ذاتية التدوير في أي وقت على التوصية باستخدام بيانات الاعتماد الثابتة والخزائن. وما زلنا مضطرين لاستخدامها مع مزوّدي السحابة الآخرين، ونبحث دائمًا عن سبل لعدم وجود بيانات اعتماد ثابتة في أي مكان في بيئتنا.

المشكلة

تحتاج مجموعة من أنواع التطبيقات المختلفة إلى الاتصال مباشرة بواجهات برمجة التطبيقات السحابية هذه الأيام. وقد يكون الأمر بسيطًا كالوصول إلى حاوية S3، أو معقدًا كمنصة كشف واستجابة سحابية مؤتمتة بالكامل (أعني، كمثال عشوائي طبعًا). وتتطلب هذه الطلبات نوعًا من بيانات الاعتماد، وهي إما ثابتة (مثل اسم المستخدم وكلمة المرور، أو مفتاح وصول IAM ومفتاح سري) أو ديناميكية. وتتضمن بيانات الاعتماد الديناميكية رمزًا مميزًا أو سمة عابرة أخرى محدودة بزمن.

إن بيانات اعتماد التطبيقات الثابتة التي تتيح وصولًا مباشرًا إلى مستوى إدارة السحابة لديك هي… سيئة. ويمكننا حل ذلك للمستخدمين عبر المصادقة متعددة العوامل، لكن ذلك لا يفيدنا مع التطبيقات المؤتمتة مثل منصة الكشف والاستجابة السحابية غير النظرية تمامًا لدينا. قبل فترة، عالجت Amazon Web Services هذه المشكلة عبر مفهوم دور IAM. والدور في AWS هو في جوهره حاوية للأذونات لها سياستان: ما يمكن للحاوية فعله، ومَن (أو ما) يمكنه تولّي الدور. والأدوار قائمة على الجلسات، فعندما يتولّى كيان مصرَّح له الدور تكون لديه مجموعة من بيانات الاعتماد (مفتاح الوصول والمفتاح السري ورمز الجلسة) يمكنه استخدامها طوال مدة الجلسة (من ساعة إلى 24 ساعة).

يمكن تولّي الأدوار في AWS من خلال اتصال SAML خارجي (للمستخدمين)، أو اتصالات "موثوقة" داخلية (من حسابات AWS أخرى)، أو خدمات AWS (مثل مثيل EC2 أو دالة Lambda). وبذلك يمكنك القيام بأمور مفيدة مثل تشغيل التعليمات البرمجية داخل مثيل من دون أن يخزّن ذلك المثيل بيانات اعتماد ثابتة على الإطلاق. وهذا يزيل الكثير من المتاعب فعلًا.

أما السماح باتصالات من حساب لا تتحكم فيه فهو أمر مختلف بعض الشيء؛ خصوصًا إذا كان ذلك الحساب منصة تخدم عدة عملاء. فمثل هذه المنصات (حسنًا، نحن) تحتاج إلى الوصول إلى مئات أو آلاف حسابات AWS الأخرى. تخيّل لو تمكّن مهاجم من خداع المنصة لتنفيذ إجراء في الحساب الخطأ، مثل إجراء تقييم للتهيئة على حساب لا يملكه المستخدم الحالي. هذه نسخة مختصرة من مشكلة النائب المُرتبك - إذ يحظى النائب بثقة حسابات متعددة، ويخدعه المستخدم لمنحه الوصول إلى حساب ينبغي ألا يمسّه ذلك المستخدم أبدًا.

وأكثر صور الاستغلال عملية لهذا الأمر هي أن تسمح المنصة للمستخدم بإدخال معرّف حساب لا يتحكم فيه، وإضافته إلى ملفه الشخصي، ثم إساءة استخدام الثقة الممنوحة للمنصة.

تتضمن AWS آلية للدفاع ضد ذلك تُسمى ExternalID. وهذا سرّ مشترك اعتباطي يتبادله مزوّد المنصة والعميل خارج القناة الأساسية. ويُمرَّر هذا المعرّف كسمة ضمن أي طلب لتولّي الدور في حساب العميل، وتتضمن سياسة ثقة الدور في ذلك الحساب شرطًا يتحقق من صحة السر المشترك. وعند تطبيق ذلك بشكل سليم، فهذا يعني أنه لا يمكن لأحد أن يضيف ببساطة حسابًا لا يتحكم فيه إلى النائب، لأن المهاجم لا يستطيع تحديد السر المشترك في حساب العميل أو معرفته.

ما لم…

تدرك إلى أين يتجه هذا. فقد حددت Praetorian عددًا كبيرًا من المزوّدين الذين يستخدمون قيم ExternalId افتراضية في AWS، أو يسمحون للعملاء بتعيين قيمة ExternalId غير فريدة لحسابهم بأكمله. كما وجدت منتجات لا تتحقق حتى من أن العميل يفرض External ID في سياسة ثقة الدور لديه. ووجدت Praetorian منصات قابلة للاستغلال فعليًا، بما يتيح هجمات النائب المُرتبك بسبب ضعف الأمان في الأدوار بين الحسابات.

تحصين الاتصالات بين الحسابات

كان هذا كله جزءًا من نمذجة التهديدات لدينا في DisruptOps، لذا فنحن في وضع جيد، وإن كنا قد استفدنا من فكرة أو فكرتين إضافيتين لتحسين الأمور. لنستعرض كل مسألة حددتها Praetorian ولننظر في أفضل الخيارات للتحصين الأمني:

  • استخدام AWS ExternalID للإعدادات الافتراضية: نحن نستخدم ExternalID عشوائيًا.
  • مشاركة AWS ExternalID عبر حسابات عملاء متعددة:نحن نستخدم ExternalID عشوائيًا لكل حساب على حدة، لا لكل عميل.
  • إمكانية تعداد AWS ExternalID أو تخمينه: نحن نستخدم قيم AWS ExternalID عشوائية بالكامل وطويلة. ولست قلقًا بشأن اختيارنا لمولّد الأرقام العشوائية الزائفة بفضل تحديد معدل استدعاءات واجهة برمجة التطبيقات (لمن يهتم منكم بالتشفير).
  • إمكانية تعيين العملاء لقيم ExternalID خاصة بهم مع احتمال تكرارها أو ضعفها: نحن لا ندعم تعيين العملاء لقيم ExternalID خاصة بهم، رغم أننا تلقّينا هذا الطلب بالتأكيد. وهنا أعتقد أن بعض المزوّدين الآخرين وقعوا في مشكلة. فالعملاء يريدون هذه الإمكانية ليتمكنوا من أتمتة تزويد المنتج بأنفسهم؛ لكن للقيام بذلك بأمان سنحتاج إلى التحقق من أن ExternalID يستوفي متطلبات الطول والعشوائية. ومع التحقق الصحيح، يمكن على الأرجح تنفيذ ذلك بأمان.
  • سماح المنصة بتزويد حساب AWS نفسه أكثر من مرة: نحن لا نسمح بذلك.
  • عدم تقييد دور IAM بكيان واحد في حساب المزوّد، بل إتاحته لأي دور في الحساب: لم نناقش هذا في هذا المقال، لكن بإمكانك إما منح الوصول من أي دور في الحساب إلى دور "العامل" في حساب العميل، أو منح الوصول لمورد أو دور واحد. ونحن نقصر وصولنا على الأدوار المحددة التي نستخدمها للوصول بين الحسابات.
  • ثبات اسم دور IAM عبر جميع حسابات العملاء: الخطر هنا يكمن أساسًا في أن اسم المستخدم (اسم الدور) قابل للتخمين. وأنا لا أعتبر هذا خطرًا على الإطلاق ما لم تكن هناك أخطاء أخرى جوهرية جدًا. ومن الأمثلة على ذلك أنه إذا عرف المهاجم اسم الدور وتمكّن من الوصول إلى حساب العميل، فقد يتمكن من إضافة نفسه إلى سياسة ثقة الدور ثم استخدام تلك الامتيازات (أُدرّس شيئًا مشابهًا في دوراتي التدريبية حول الاستجابة للحوادث). وهذا خطر محتمل لكننا نصنّفه منخفضًا إلى حد كبير. فإذا كان المهاجم يملك ذلك المستوى من الوصول، فمن المرجح أن يتمكن من الاستيلاء على أي دور في الحساب.
  • عدم تحقق المزوّد من أن ExternalID قد ضُبط كشرط للوصول: نحن نزوّد العملاء بقالب CloudFormation للتزويد يضمن ضبط ذلك بشكل صحيح. وسنضيف دعمًا للتحقق من بقائه كذلك، خصوصًا مع استمرارنا في إضافة خيارات تزويد أخرى (غير CloudFormation) لتلبية متطلبات العملاء.

يبدو أن Kesten يفضّل نموذج بيانات الاعتماد الثابتة واستخدام خزائن جيدة لدى المزوّد لتأمين الاتصال. أما أنا فأختلف معه شخصيًا، وأرى أن نموذج AWS أكثر أمانًا من البداية، بافتراض اتباع الاحتياطات الأساسية.

ونتخذ حاليًا احتياطين إضافيين يتجاوزان توصيات Praetorian:

  • نخفي ExternalID في CloudFormation: نضبط ExternalID كمعامل في قوالب CloudFormation لدينا مع تفعيل خيار NoEcho. وهذا يخفيه في وحدة التحكم وأدوات سطر الأوامر وواجهة برمجة التطبيقات. ويقلل ذلك من خطر كشفه لشخص يملك أذونات تشغيل CloudFormation دون أن يملك أذونات IAM.
  • نقصر الوصول إلى قالب CloudFormation على الحساب المستهدف فقط: وهذا يقلل من خطر تمكّن أحدهم من التسلل والاستيلاء على ExternalID أثناء عملية التزويد.

وحتى إن انكشف ExternalID فلا ينبغي أن يكون لذلك أثر - إذ يجب أن تضمن منصتك تسجيل الحساب المستهدف مرة واحدة فقط، وبقيمة ExternalID عشوائية فقط. وحتى إن عرف المهاجم اسم الدور وقيمة ExternalID، فلن يتمكن من فعل أي شيء بها لأنه لا يوجد أي مكان في المنصة لإدخال تلك المعلومات، كما أن AWS نفسها تفرض أن ينشأ الاتصال بين الحسابات من الحساب الموثوق. وهذا أمر لا يمكن انتحاله.

آمل أن يمنحك اطلاعك على طريقة تعاملنا مع ذلك بعض الأفكار حول ما ينبغي فعله في أدواتك الخاصة. وأوصي بمتطلبات تسجيل الحساب وقيمة ExternalID العشوائية حتى إن كنت تستخدم AWS Organizations لأن إضافة شرط لقصر الوصول على مؤسستك وحدها قد يظل يعرّضك لهجوم ينطلق من حساب أقل أمانًا نحو حساب أعلى أمانًا.

وترقّبوا ذلك المشروع التطويري السري الجديد! من المفترض أن نتمكن من الحديث عنه خلال بضعة أشهر، وهو يغيّر قواعد اللعبة فعليًا في مثل هذه المشكلات.

تقنيات متقدمة للدفاع عن AWS ExternalID | FireMon