دورة معهد ماساتشوستس للتكنولوجيا "أمن أنظمة الكمبيوتر". المحاضرة 3: تجاوزات العازلة: المآثر والحماية ، الجزء الأول

معهد ماساتشوستس للتكنولوجيا. محاضرة رقم 6.858. "أمن أنظمة الكمبيوتر." نيكولاي زيلدوفيتش ، جيمس ميكنز. 2014 سنة


أمان أنظمة الكمبيوتر هي دورة حول تطوير وتنفيذ أنظمة الكمبيوتر الآمنة. تغطي المحاضرات نماذج التهديد ، والهجمات التي تهدد الأمن ، وتقنيات الأمان بناءً على العمل العلمي الحديث. تشمل الموضوعات أمان نظام التشغيل (OS) ، والميزات ، وإدارة تدفق المعلومات ، وأمان اللغة ، وبروتوكولات الشبكة ، وأمان الأجهزة ، وأمان تطبيقات الويب.

المحاضرة 1: "مقدمة: نماذج التهديد" الجزء 1 / الجزء 2 / الجزء 3
المحاضرة 2: "السيطرة على هجمات القراصنة" الجزء 1 / الجزء 2 / الجزء 3
المحاضرة 3: "تجاوزات العازلة: المآثر والحماية" الجزء 1 / الجزء 2 / الجزء 3

مرحبًا بك في المحاضرة حول مآثر تجاوزات العازلة. اليوم سننهي مناقشة حدود باغي ثم ننتقل إلى طرق حماية تجاوز سعة المخزن المؤقت الأخرى.



بعد ذلك ، سنتحدث عن المواد المطبوعة لمحاضرة اليوم ، والمكرسة للبرمجة الموجهة نحو العودة العمياء (BROP) - البرمجة الموجهة عمياء. هذه تقنية استغلال يمكن تنفيذها حتى إذا لم يكن لدى المهاجم ثنائي الهدف. تهدف هذه المآثر إلى تدمير "الكناري" في أكوام أنظمة 64 بت. لذلك إذا كنت مثلي عندما قرأت هذه المواد لأول مرة ، كان يجب أن تشعر برغبة في مشاهدة فيلم كريستوفر نولان. لقد كان مجرد انفجار دماغي!

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

افترض أننا سنقوم بتعيين مؤشر p وتخصيص حجم 44 بايت له. افترض أيضًا أن حجم الفتحة هو 16 بايت.

ماذا يحدث عند تعيين وظيفة malloc ؟ أنت تعرف بالفعل أنه في هذه الحالة سيحاول نظام الحدود الفضفاضة استكمال هذا التوزيع باستخدام لوغاريتم 2n . لذلك بالنسبة لمؤشرنا الذي يبلغ 44 بايت ، سيتم تخصيص 64 بايت من الذاكرة. لكن حجم الفتحة هو 16 بايت ، لذلك سننشئ 64/16 = 4 جداول حد كل منها 16 بايت. سيتم وضع كل من هذه الإدخالات في سجل توزيع الحجم.

بعد ذلك ، قم بتعيين حرف مؤشر آخر * q = p + 60 . نرى أن هذه القيمة خارج الحدود لأن حجم p 44 بايت ، وهنا 60 بايت. لكن باغي باوندز يعمل بحيث لا يحدث شيء سيئ في هذه الحالة ، على الرغم من أن المبرمج لم يكن يجب أن يفعل ذلك.

لنفترض الآن أن الشيء التالي الذي نقوم به هو تعيين مؤشر آخر ، والذي سيكون مساوياً لـ char * r = q + 16 . الآن سيؤدي هذا في الواقع إلى حدوث خطأ ، لأن حجم الإزاحة سيكون 60 + 16 = 76 ، وهو أكبر بـ 12 بايت من الفتحات الأربعة (4x16 = 64 بايت) التي خصصها نظام حدود Baggy . وهذا الفائض هو بالفعل أكثر من نصف الفتحة.



إذا كنت تتذكر ، في هذه الحالة ، سيستجيب نظام باغي باوندز على الفور إلى خطأ مزامنة فادح ، مما سيؤدي إلى تعطل البرنامج وإيقافه بالفعل.

لذلك دعونا نتخيل أن لدينا خطين فقط:

char * p = malloc (44)
char * q = p + 60

وليس هناك سطر ثالث مع الشفرة. بدلاً من ذلك ، سنفعل ذلك:

char * s = q + 8

في هذه الحالة ، سيكون للمؤشر قيمة 60 + 8 = 68 بت ، والتي ستكون 4 بايت أكثر من الحدود المعينة بواسطة حدود باغي . في الواقع ، لن يتسبب هذا في حدوث خطأ فادح ، على الرغم من أن القيمة تتجاوز الحدود. ما فعلناه هنا هو تعيين طلب مرتفع للمؤشر. لذا ، إذا حاول شخص ما لاحقًا عدم الإشارة إليه ، فسيؤدي ذلك إلى خطأ فادح في هذه المرحلة.



وآخر شيء سنفعله هو تعيين مؤشر آخر:

char * t = s - 32

في الواقع ، لقد فعلنا ذلك - أعدنا المؤشر إلى الحدود. لذلك إذا تجاوزت s في البداية ، فقد عدنا الآن إلى الحجم المخصص أصلاً الذي أنشأناه للمؤشر. لذلك ، لن يحتوي t الآن على بت عالي الترتيب في تكوينه ، ويمكن إلغاء تحديده بسهولة.



الجمهور: كيف يعرف البرنامج أن r لديه فائض أكبر من نصف المكدس؟

البروفيسور ميكنز: لاحظ أنه عندما أنشأنا r ، حصلنا على رمز الأداة الذي سيعمل في كل هذه العمليات باستخدام المؤشرات. حتى نتمكن من معرفة مكان q ، ونعلم أنه داخل حدود Baggy . لذلك ، عندما نقوم بهذه العملية q + 16 ، فإن أدوات الحدود الفضفاضة تعرف من أين جاءت هذه القيمة الأولية. وبعد ذلك ، في حالة حدوث إزاحة من هذا الحجم الأصلي ، ستحدد الحدود الفضفاضة بسهولة أن الإزاحة أكبر من ½ من حجم الفتحة.

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

آمل أن يكون هذا مفهوما. لقد كانت نظرة عامة موجزة للغاية عن الواجبات المنزلية ، ولكن آمل أن تتمكن من فهمها بسهولة.

لذا ، لدينا مؤشر يبدو كالتالي:

char * p = malloc (256) ، ثم نضيف المؤشر char * q = p + 256 ، وبعد ذلك سنحاول الإشارة إلى هذا المؤشر.

إذن ماذا سيحدث؟ حسنًا ، لاحظ أن 256 عبارة عن تسلسل 2n ، لذلك سيكون ضمن حدود Baggy . لذلك ، عندما نضيف 256 بتة أخرى ، هذا يعني أننا نقوم بتمرير آخر إلى نهاية حدود الحدود الفضفاضة . كما في المثال السابق ، هذا الخط جيد بما فيه الكفاية ، لكنه يؤدي إلى حقيقة أنه سيتم تعيين بت ترتيب أعلى لـ q . لذلك ، عندما نحاول إلغاء الإشارة إليه ، سينفجر كل شيء ويجب أن يتصل بوكيل التأمين لدينا. هل هذا واضح؟



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

سؤال آخر مذكور في Piazza: كيفية ضمان توافق حدود Baggy مع مكتبات سابقة غير أداة. الفكرة هي أنه عندما تقوم حدود باغي بتهيئة جداول الحدود ، فإنها تثبت أن جميع السجلات يجب أن تكون في حدود 31 بت. لذلك ، عندما نقرأ جدول الحدود ، يمثل كل سجل فيه قيمة النموذج 2n + 31 . وبالتالي ، عند تهيئة الحدود الأولية للحجم 31 بت ، نفترض أن كل مؤشر سيكون له أقصى حجم ممكن 2n + 31 . دعني أعطيك مثالاً بسيطًا للغاية يوضح هذا الأمر.

افترض أن لدينا مساحة ذاكرة نستخدمها في كومة الذاكرة المؤقتة. تتكون مساحة الذاكرة هذه من مكونين. في الجزء العلوي ، لدينا كومة تم تخصيصها باستخدام رمز غير أداة ، وفيما يلي كومة تم تخصيصها برمز الأداة. فماذا ستفعل حدود باغي ؟ كما تتذكر ، هذا النظام لديه مفهوم فتحة ، حجمها 16 بت. لذلك ، سيتألف جدول الحدود من قسمين ، يبدأ من 31 بتة.

ومع ذلك ، عند تشغيل رمز الأداة ، سيستخدم في الواقع خوارزمية الحدود الفضفاضة لتعيين القيم المناسبة لهذا الصف من الجدول.



عندما يأتي مؤشر من أعلى مساحة الذاكرة ، يتم تعيينه دائمًا على الحد الأقصى الممكن 2n + 31 . هذا يعني أن حدود Baggy لن تعتبر أبدًا أن عملية المؤشر "التي جاءت" من مكتبة غير أداة يمكن أن تتجاوز الحدود.

الفكرة هي أنه في رمز الأداة ، سنقوم دائمًا بإجراء هذه المقارنات للمؤشرات ، ولكن إذا قمنا بتعيين حدود كتابة المؤشر لرمز غير أداة للنموذج 2n + 31 ، فلن يكون لدينا خطأ في الإشارة. بمعنى ، لدينا تفاعل جيد بين إدخالات كود الحدود الفضفاضة والسجلات غير الآلية للمكتبات السابقة.

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

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

الجمهور: إذا كان لدينا رمز أداة لتخصيص الذاكرة ، فهل تستخدم نفس وظيفة malloc التي يستخدمها رمز السمة؟

البروفيسور: هذا سؤال دقيق. إذا نظرنا في الحالة هنا ، فإن هذا يتم ملاحظته بدقة ، حيث لدينا منطقتان من الذاكرة ، كل منهما يخضع للقواعد الموضوعة له. ولكن من حيث المبدأ ، سيعتمد على الكود الذي يستخدم لغة البرمجة المحددة. تخيل أنه في C ++ ، على سبيل المثال ، يمكنك تعيين المؤهل الخاص بك. لذلك يعتمد على تفاصيل معينة من التعليمات البرمجية.

الجمهور: كيف يمكن للمؤهل التحقق مما إذا تم تعيين الحد إلى 31 بت أم لا؟

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

لذلك ، كل ما فحصناه أعلاه يتعلق بتشغيل حدود باغي في أنظمة 32 بت. ضع في اعتبارك ما يحدث عند استخدام أنظمة 64 بت. في مثل هذه الأنظمة ، يمكنك في الواقع التخلص من جدول الحدود ، لأنه يمكننا تخزين بعض المعلومات حول الحدود في المؤشر نفسه.

ضع في اعتبارك شكل المؤشر المنتظم في حدود باغي. يتكون من 3 أجزاء. يتم تخصيص 21 بت للجزء الأول ، والجزء صفر ، ويتم تخصيص 5 بتات أخرى للحجم ، وهذا هو الحجم الرئيسي للسجل ، و 38 بت هي بتات العنوان المعتاد.



السبب في أن هذا لا يحد بشكل كبير من حجم عنوان البرنامج الذي تستخدمه هو أن معظم البتات عالية الترتيب لنظام التشغيل و / أو المعدات الموجودة في أول جزأين من المؤشر لا تسمح باستخدام التطبيق لأسباب مختلفة. لذا ، كما اتضح ، فإننا لا نخفض بشكل كبير عدد التطبيقات المستخدمة في النظام. هذا ما يبدو عليه المؤشر العادي.

ماذا يحدث عندما يكون لدينا واحدة فقط من هذه المؤشرات؟ حسنًا ، في نظام 32 بت ، كل ما يمكننا القيام به هو مجرد تعيين بت عالي الترتيب وتأمل ألا يحصل هذا الشيء على أكثر من نصف حجم الفتحة. ولكن الآن بعد أن أصبح لدينا كل مساحة العنوان الإضافية هذه ، يمكنك وضع الإزاحة خارج حدود OOB (خارج الحدود) مباشرة في هذا المؤشر. لذا يمكننا القيام بشيء مثل ذلك الموضح في الشكل ، وتقسيم المؤشر إلى 4 أجزاء وإعادة توزيع حجمه.

وبالتالي ، يمكننا الحصول على 13 بتًا لحدود الإزاحة ، أي اكتب إلى أي مدى سيكون مؤشر OOB من حيث يجب أن يكون. ثم مرة أخرى ، يمكنك تعيين الحجم الفعلي للكائن المشار إليه هنا ليكون 5 ، والجزء المتبقي من الجزء صفر ، والذي سيكون الآن 21-13 = 8 بت. ثم يتبع جزء عنواننا من 38 بت. في هذا المثال ، ترى مزايا استخدام أنظمة 64 بت.



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

الحضور: لماذا في الحالة الثانية يقع الإزاحة أمام الحجم وليس كما في الحالة السابقة ، وماذا سيحدث إذا كان حجم الإزاحة كبيرًا؟

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

لذلك ، لا يزال بإمكانك الشروع في تجاوز سعة المخزن المؤقت في نظام حدود باغي ، حيث إن تطبيق الأساليب المذكورة أعلاه لا يحل جميع المشاكل ، أليس كذلك؟ قد تواجه مشكلة أخرى إذا كان لديك رمز غير مفيد ، لأننا لن نتمكن من اكتشاف أي مشاكل في الرمز غير الآلي. قد تواجه أيضًا ثغرات في الذاكرة تنشأ عن نظام تخصيص الذاكرة الديناميكي. إذا كنت تتذكر ، في محاضرة سابقة ، نظرنا في هذا المؤشر الغريب لتحرير malloc ، ولم تتمكن حدود Baggy من منع حدوث مثل هذه الأشياء.

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

لذا ، ما هو سعر استخدام حدود باغي ؟ في الواقع ، لدينا 4 مكونات فقط من هذا السعر.



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

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

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

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

كما أنه يؤدي إلى نفقات غير منتجة تحتاج إلى دعم مترجم. لأنه يجب عليك إضافة جميع الأدوات إلى النظام ، وتجاوز فحص المؤشر ، وهكذا دواليك.

لذا ، لاستخدام نظام باغي باوندز ، علينا أن ندفع ثمنًا ، والذي يتكون من الاستخدام المفرط للمساحة ، وزيادة حمل وحدة المعالجة المركزية ، والإنذارات الكاذبة والحاجة إلى استخدام مترجم.

بهذا نختتم مناقشة حدود باغي .

يمكننا الآن التفكير في استراتيجيتين أخريين للتخفيف من تجاوز سعة المخزن المؤقت. في الواقع ، من الأسهل شرحها وفهمها.

يسمى أحد هذه الأساليب الذاكرة غير القابلة للتنفيذ . فكرته الرئيسية هي أن جهاز المبادلة سيشير إلى 3 بت من R و W و X - قراءة وكتابة وتنفيذ - لكل صفحة لديك في الذاكرة. , , . 2 , , , , .

, . , , , , - . , . « W X » , , , , , . , , . . , , . ?

- , . , . , , .

, , , , . , , . .

, . – just-in-time , .

-, JavaScript . JavaScript, , - - «» , - «» , x86 . , .
. , , just-in-time W , X . , , .

— . , , , .



, , . GDB, , . , . , . .

, . , , , , , .

: , , — . , , , , , , , - . , , .

, , , GDB , , , , . .
, , , , . - , - , . , . , , .

, ? , . , , . , , , , - , .

27:10

:

دورة معهد ماساتشوستس للتكنولوجيا "أمن أنظمة الكمبيوتر". 3: « : », 2


.

شكرا لك على البقاء معنا. هل تحب مقالاتنا؟ هل تريد رؤية مواد أكثر إثارة للاهتمام؟ ادعمنا عن طريق تقديم طلب أو التوصية به لأصدقائك ، خصم 30 ٪ لمستخدمي Habr على نظير فريد من خوادم مستوى الدخول التي اخترعناها لك: الحقيقة الكاملة حول VPS (KVM) E5-2650 v4 (6 نوى) 10GB DDR4 240GB SSD 1Gbps من 20 $ أو كيفية تقسيم الخادم؟ (تتوفر الخيارات مع RAID1 و RAID10 ، حتى 24 مركزًا وحتى 40 جيجابايت DDR4).

ديل R730xd أرخص مرتين؟ فقط لدينا 2 x Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100 TV من 249 دولارًا في هولندا والولايات المتحدة! اقرأ عن كيفية بناء مبنى البنية التحتية الطبقة باستخدام خوادم Dell R730xd E5-2650 v4 بتكلفة 9000 يورو مقابل سنت واحد؟

Source: https://habr.com/ru/post/ar416839/


All Articles