• 0
majed316

التشريح الكامل لثغرة Stack-based Overflow

سؤال

[ بسم الله الرحمن الرحيم ]

السلام عليكم ورحمة الله وبركاته

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

ومن الجدير بالذكر بأنني بهذه الطريقة أضرب ثلاثة عصافير بحجر وهي :

1- الاستفادة الشخصية برسوخ المعلومات في ذهني .

2- الفائدة المتعدية بمشاركة هذه المعلومات مع أشخاص آخرين يهتمون بنفس المجال .

3- إثراء المكتبة العربية بكتب ومقالات قد لا تكون موجودة من السابق خصوصاً عندما تكون هذه المعلومات مترجمة .

ولكم أن تتخيلوا لو أن كل دارس اتخذ هذه الطريقة كأسلوب له كم سيكون حجم المعلومات المكتوبة بالعربية والمتاحة للجميع .

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

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

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

بقي أمر واحد مهم وألخصه في جملة صغيرة قالها الصحابي الجليل أنس بن مالك رضي الله عنه حيث قال :

" إن العلم يؤتى ولا يأتي " فلا تنتظر أن يأتيك أحد إلى بيتك ليلقنك العلم ولكن ابحث عنه وستجده .

وقد ترجمت هذا الدرس من عدة مصادر ولكن أعتمدت الإعتماد الأكبر من كتاب " The Art of Exploit " وأنا في طريقي لترجمة كامل الكتاب إن شاء الله ولكن نظراً لما رأيته في هذه القسم من كثرة الطلب على ثغرة buffer Overflow فآثرت أن أقوم بتنزيل ما ترجمته على أجزاء حتى يكتمل العمل .

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

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

والآن لم يبقى لدينا سوى أمر واحد و هو البدء في قراءة الدروس .

فلنبدأ على بركة الله

أخوكم ماجد علي .

الصلاحيات متعددة المستخدمين :

ملاحظة : قد تستغرب وجود مثل هذا الدرس هنا وتتوقع أن ترى دروساً مباشرة تشرح تفاصيل الثغرات ولكن فهم هذا الدرس مطلب أساسي لمعرفة ما تلحق به من دروس ( إلا إن كانت وحش من وحوش اللينوكس فتخطاه بكل ثقة ) :

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

هذه الصلاحيات تعرض بواسطة ثلاثة أحرف هي ( r , w , x ) في ثلاثة حقول متعاقبة وهي المستخدم والمجموعة والآخرين كما أشرنا سابقاً ، سنعرض في المثال التالي نموذج لصلاحيات ممنوحة لملف يسمى ( tmp ) فالمستخدم ( مالك الملف ) لديه صلاحيات القراءة والكتابة ( الحقل الأول الموضح بخط عريض ) ، أما المجموعة فلديها صلاحيات القراءة والتنفيذ ( الحقل الأوسط ) , بينما أي مستخدمين آخرين فلديهم صلاحيات الكتابة والتنفيذ ( الحقل العريض الأخير ) .

-rw-r-x-wx   1 guest   visitors   149 Jul 15 23:59 tmp

في بعض الحالات قد تحتاج إلى السماح لمستخدم غير مصرح له بتنفيذ بعض مهام النظام التي تحتاج إلى صلاحيات المستخدم الجذر ( root ) ، مثل تغيير كلمة المرور . وهناك حل واحد لهذه المشكلة وهو إعطاء هذا المستخدم صلاحيات المستخدم الجذر ؛ ولكن المشكلة الأكبر التي ستنشأ هي حصول هذه المستخدم على تحكم كامل بالنظام مما يجعل هذا الحل سيء من منظور أمني . وبدلاً من ذلك ، يُعطى البرنامج المراد تشغيله القابلية للعمل كما لو كان هو نفسه المستخدم الجذر , وبالتالي تُنجز المهمة المطلوبة دون أن يحصل المستخدم غير الجذر على الصلاحيات الكاملة . هذا النوع من الصلاحيات يدعى suid ( set user ID ) ، فعندما يتم تنفيذ برنامج يحمل هذا النوع من الصلاحيات من قبل أي مستخدم يتم تغيير بت ( bit ) خاص بالمستخدم يدعى euid ( effective user ID ) إلى نفس المعرف ( uid ) الخاص بمالك البرنامج ، ويتم تنفيذ البرنامج . بعد أن ينتهي البرنامج من العمل ، يتم تغيير قيمة euid إلى قيمته الأصلية . وهذا البت ( bit ) هو رمز يشار إليه بحرف ( s ) عريض . وهناك أيضاً صلاحية خاصة بالمجموعة تدعى sgid ( set group ID ) والتي تقوم بنفس الشيء ولكن مع المجموعة حيث تقوم بتغيير الـ egid ( effective group ID ) إلى المعرف الخاص بالمجموعة التي ينتمي إليها المستخدم مالك الملف المراد تشغيله . وفي المثال التالي نوضح صلاحية ملف يحمل البت المشار إليه :

-rwsr-xr-x   1 root   root   29592 Aug 8 13:37 /usr/bin/passwd

على سبيل المثال , إذا أراد مستخدم تغيير كلمة المرور الخاصة به , لا بد من تشغيل البرنامج :

/usr/bin/passwd

وهذا البرنامج مملوك للمستخدم الجذر root لذلك البت suid لهذا البرنامج موضوع على الوضع on ، عندها سيتم تغيير معرف المستخدم uid إلى نفس المعرف الخاص بالمستخدم الجذر root ( والذي يحمل الرقم صفر ) ليتم تنفيذ البرنامج passwd , ومن ثم سيعود المعرف إلى قيمته السابقة بعد إكتمال التنفيذ والخروج من البرنامج .

البرامج المملوكة من قبل المستخدم الجذر والتي تحمل البت suid في وضع on تدعى ( suid root programs ) .

وإن استعطت تغيير مسار تنفيذ برامج من هذا النوع عن طريق حقنها بكود آخر ، عندها يستطيع كودك الخاص أن يفعل أي شيء وكأنه مستخدم جذر ، فإذا أراد المخترق أن يجعل هذا البرناج يُنشأ مستخدم جديد يحمل صلاحيات الجذر ، عندها يستطيع الدخول بهذا المستخدم للنظام وعمل أي شيء يريده

ولكن السؤال هنا هو ( كيف نستطيع تغيير مسار البرنامج ؟؟؟ ) ، وأقول لكم هو سؤال صغير ولكن إجابته طويلة ومن يتحلى بالصبر على القراءة الطويلة والتركيز هو فقط من سيعرف الإجابة .

دعونا نختم هذا الدرس بهذا المقطع الأخير البسيط لنتهيأ بإذن الله للإنتقال للدروس القادمة الأكثر تشويقاً .

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

الذاكرة ( Memory ) :

قد تبدو الذاكرة مرعبة في أول الأمر ، ولكن تذكر أن الكمبيوتر ليس سحري ، وهو في الأساس ليس سوى آلة حاسبة ضخمة .

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

معالجات إنتل الحالية تستخدم مخطط عنونة من 32 بت ، مما يعني أن هناك 4,294,967,296 عنوان يمكن الوصول إليه ، و متغيرات البرامج ليست سوى أماكن محددة في الذاكرة يتم إستخدامها لتخزين المعلومات فيها .

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

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

إعلان المتغيرات في الذاكرة :

عندما تبرمج تحت لغة عالية المستوى مثل الـ C ، يتم إعلان المتغيرات باستخدام أنواع البيانات وهذه الأنواع تتنوع من الأرقام integers إلى الأحرف characters إلى أنواع أخرى قد تكون معرفة في لغة البرمجة نفسها أو يعرفها المستخدم بنفسه ، وأحد الأسباب التي وجدت من أجله المتغيرات هو تحديد مساحة محددة في الذاكرة لأي نوع من المتغيرات ، فمثلاً الرقم integer يحتاج إلى مساحة في الذاكرة بحجم أربعة بايت ، بينما يحتاج الحرف الواحد إلى بايت واحد فقط .

بالإضافة لذلك ، تستطيع إعلان المتغيرات في مصفوفات . والمصفوفة هي قائمة عناصر من نوع معين ، فعندما نقول مصفوفة من عشرة أحرف نعني بكل بساطة عشرة أحرف متجاورة في الذاكرة . والمصفوفات أيضاً تعرف بـ buffer والبفر هو مخزن مؤقت في الذاكرة يعرفه المستخدم لإنتظار نقل بيانات معينة فيه ، ومصفوفة الأحرف تعرف أيضاً بالسلسلة string ، ولأن عملية نقل الـ buffer هي عملية مكلفة معالجياً ، لذا يتم دائماً تخزين أول عنوان من الـ buffer في مؤشر ، ومن المعروف أن المؤشرات يتم الإعلان عنها عن طريق إضافة النجمة ( * ) قبل إسم المتغير . وإليك أمثلة لإعلان المتغيرات والمؤشرات في السي :

int integer_variable;
char character_variable;
char character_array[10];
char *buffer_pointer;

بقي أمر مهم جداً لا بد من معرفته جيداً وهو أنه في معالجات 86 يتم تخزين البايتات ذات 4 بايت في الذاكرة بطريقة تسمى little endian ، والتي تعني أن البايت الأدنى أهمية يأتي أولاً في الذاكرة ، وللتوضيح أكثر فإن أنواع المتغيرات ذات الحجم أربعة بايت مثل الأرقام والمؤشرات ( integers, pointers ) سيتم تخزينها في الذاكرة بطريقة معكوسة ، فلو كانت لدينا القيمة الست عشرية التالية :

0x12345678

فإنك ستراها في الذاكرة وقد تم تخزينها على النحو التالي :

0x78563412

وبرغم أن كمبايلرات Compilers اللغات العالية المستوى مثل السي ستتولى ترتيب البايتات بهذا الشكل تلقائياً دون تدخل منك إلا أن هذه المعلومة تعتبر مهمة فلذا وجب عليك تذكرها جيداً .

بايت الإنهاء : ( Null Byte Termination )

قد تقوم أحياناً بإعلان مصفوفة حرفية character بحجم عشرة بايتات ولكنك لا تستخدم فعلياً سوى أربعة بايتات منها ، فمثلاً لو أعلنا مصفوفة حرفية بحجم عشرة بايت ثم قمنا بتخزين الكلمة 'test' فيها ، عندها سيكون هناك بايتات إضافية في آخر المصفوفة لم تستخدم ، في هذه الحالة سيتم إستخدام حرف محدد يُدعى null byte أو zero byte لإنهاء النص ولإخبار أي برنامج أو دالة تتعامل مع هذا النص أن تتوقف عند هذا البايت دون أن تكمل إلى نهاية المصفوفة .

Ten Bytes Array: 


تم تعديل بواسطه majed316
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

9 إجابة على هذا السؤال .

  • 0

فعلاً أواجه مشكلة في إضافة مشاركات في المنتدى :

أولاً : عندما أضيف رد على مشاركتي لا تظهر وكأنها رد وإنما تظهر في المشاركة الأصلية .

ثانياً : أضفت ثلاثة ردود ثم لم أعد أستطيع أن أرد أكثر حتى مع إنتظاري لوقت طويل .

ثالثا : بعد إضافتي الردود وغيابي لمدة الساعة تقريباً عدت لأجد أن كافة الردود قد حذفت ولم يبقى سوى الرد الأول وقد حذف منه الكثير .

لذا سأرفق الدروس كملف مرفق للتسهيل .

أرجوا أن تنجح أيضاً .

أرجوا أن أكون قدمت ما هو مفيد .

للأسف أخفقت للمرة الثانية .

سأحاول إرفاق الملف الآن .

Buffer_Overflows.zip

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

بارك الله فيك اخي كفيت و وفيت الحقيقة نحن محتاجين لشروحات مثل هذه.

تم تعديل بواسطه DATA_SNIPER
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

شرح ودرس اكثر من راائع فانت تتقن فن التفسيرر....

احييك اخي على هذه الروح وارجوا ان تستمر بما بدأت ,فنحن فعلا نحتاج الى شرح اساسي كهذه يتناول جميع النقاط...

لقد قرأت كل كلمه كتبتها بدرسك بالاول بشغف وسوف اكمل بما ارفقه ...

ان شاء الله رح اتشوف التفاعل

ارجوا من اداره المنتدى البحث في مشكلة ,الانه نشر الدروس هنا اكثر فاعليه واسهل للتواصل ..

في امان الله...

تم تعديل بواسطه TheKiLLeR
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

الحمدلله أن هناك من استفاد منها .

وأشكر كل من شكرني أو رد على موضوعي أو شجعني .

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

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

تم تعديل بواسطه majed316
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

ما شاء الله majed316

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أووووووووووووف إبداع والله إبداع

مشكور أخ ماجد بارك الله فيك وجعلها الله في ميزان حسناتك

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

الله يبارك فيك و الله يا أخي نورت لي الطريق وفهمت من كتابك اشياء كثيرة الله يجازيك.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

Up

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .