الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

ما ادوات و طرق تنظيف الكود من الثغرات

بدأه apex في 6 مايو 2009 · 11 رد · 2,431 مشاهدة · في منتدى تحليل التطبيقات البرمجية وحمايتها
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

حاليا اقوم بتعلم لغة سى بلس بلس  وانوى تعلم السى ايضاء 

المهم اخذنى الفضول لاتعرف على ما معنى الثغرات الامنية فى الكود وكيفية الوقوع فى تلك الاخطاء 

فبدات بقراء بعض الاجزاء من Hacking: The Art of Exploitation, 2nd Edition

نظرا لانة لا يتطلب معرفة قوية بالاسمبلى (لا انوى تعلمها قبل عام ) ويناقش بطريقة عامة 

بدون اطالة لاحظت ان الطريقة المتبعة فى الكتاب لتتبع اخطاء الكود هى الطريقة الصعبة وهى الترجمة للاسمبلى ومتابعة الكود وما الى ذلك 

هل يوجد ادوات جاهزة لفعل ذلك مثل ان اخبر المترجم ان هذا المتغير مثلا لا اريدة ان يكون عرضة 

للoverwritten 

او غير قابل للظهور فى المكدس وما الى ذلك 

باختصار ادوات جاهزة لفعل ذلك بطريقة اوتوماتيكا لسد تلك الانواع من الثغرات

هل يوجد ؟ ام هناك تقنيات اخرى ؟ 

ارجو الافادة 

تم تعديل هذه المشاركة بواسطة apex في 6 مايو 2009 في 18:31

name : mohamedyosry

#3

جزاك الله خيرا اخى GamingMasteR

اقتباس
Performance Impact

A performance tradeoff for using security checks in an application must be made. The Visual C++ compiler team focused on making the performance degradation small. In most cases, the performance should not degrade more than 2 percent. In fact, experience has shown that most applications, including high-performance server applications, have not noticed any performance impact.

The most important factor behind keeping the performance impact from being an issue is that only functions that are vulnerable to attack are targeted. Currently, the definition of a vulnerable function is one that allocates a type of string buffer on the stack. A string buffer that is considered vulnerable allocates more than four bytes of storage and where each element of the buffer is either one or two bytes. Small buffers are unlikely to be the target of an attack, and limiting the number of functions that have security checks limits the code growth. Most executables will not even notice an increase in size when building with /GS.

كنت اقصد اخى ادوات فى مرحلة debugging ليس فى مرحلة compiling بمعنى اخر تصحيح الكود منذ البداية(مرحلة تصليح الكود) افضل

بمعنى اخر ان فى مرحلة الdebugging يكون هناك عملية معالجة للثغرات فى مرحلة صنع الكود (ربما تعتمد على ذكاء اصطناعى او ما الى ذلك المهم القدرة على اكتشاف اماكن الثغرات ) ويفضل تقديم اقتراحات للحلول

وان انتهى الامر الى ان من المستحيل تامين البرنامج بالكامل وقت المعالجة اضع حلول فى compiling time لحل الذى لم استطع سدة فى الكود (مثل الحل الذى يقدمة الرابط)

Conclusion

اقتباس
Buffer overruns can clearly be a critical flaw in an application. Nothing replaces writing tight, secure code in the first place. Despite popular opinion, a minority of buffer overruns are extremely difficult to discover. The /GS switch is a useful tool for developers interested in writing secure code. It does not solve the problem that buffer overruns exist in the code, however. Even with the security checks to prevent the buffer overrun from being exploited in some cases, the program still terminates, which is a denial of service attack, especially against server code. Building with /GS is a safe and secure way for developers to mitigate the risks of vulnerable buffers of which he or she was not aware.

While tools exist to flag possible vulnerabilities such as the ones discussed in this article, they are provably imperfect. Nothing compares to a good code review by developers who know what to look for. The book Writing Secure Code by Michael Howard and David LeBlanc provides an excellent discussion of many other ways to mitigate risk when writing highly secure applications.

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

اما بخصوص الكتب الخاصة بتامين الكود (كالكتاب المشار لة ) والذى ان ينصح بان الطريقة اليدوية والتقليدية افضل .... :blink:

لا اوافقة الراى اظن ان مايستطيع المطورون فعلة يستطيع برنامج فعلة

بل نسبة خطاء المطوربن اكبر على ما اظن عوضا عن تكاليف المطورين والوقت المستهلك وما الى ذلك .

تم تعديل هذه المشاركة بواسطة apex في 6 مايو 2009 في 21:44

name : mohamedyosry

#4

السلام عليكم .....

اقتباس
لا اوافقة الراى اظن ان مايستطيع المطورون فعلة يستطيع برنامج فعلة

بل نسبة خطاء المطوربن اكبر على ما اظن عوضا عن تكاليف المطورين والوقت المستهلك وما الى ذلك .

ما تطلبه يا عزيزي ببساطة غير ممكن, هناك أدوات "للمساعدة", و لكن وجود ثغرة يعني أنها موجودة, و يجب إصلاح الكود نفسه من قبل المبرمج....

الآن دعني أعطيك مثالاً.....

بعض مترجمات C توفر دالة تسمى itoa ... دالة بسيطة جداً تأخذ عدد من النوع int و تقوم بتحويله لنص ... بسيط جداً أليس كذلك ....

هذا مثال ..

int main(){

	char numberAsString[12];

	int x = -2147483648;

	itoa(x, numberAsString, 10);

	return 0;
}

قمنا بتحويل العدد x إلى نص, كيف سنعرف عدد الـ bytes التي يجب أن تحملها المصفوفة النصية ؟

أكبر "عدد خانات" للنوع int إذا كنا نعمل على معالج 32bit هو 2147483648- لاحظ أني قلت عدد خانات و لم أقل أكبر قيمة, أكبر قيمة مساوية في عدد الخانات للقيمة السالبة و لكن القيمة السالبة يضاف لها الإشارة السالبة كما ترى في المثال...

الآن في المثال الذي عرضته لك لايوجد أي نوع من الخطر على الإطلاق!

لدينا عدد عند تحويله سيحتوي على 11 خانة و حجم مصفوفتنا هو 12 بالطبع لأنه في لغة C يضاف العدد 0 كدليل على نهاية النص....

إلى هنا لا مشكلة.....

تصور الآن أننا أخذنا البرنامج و قمنا بترجمته على معالج يعمل على 64bit !!!!

هنا تظهر المشكلة,

فحجم المصفوفة لايكفي!

فمثلاً أكبر عدد خانات لمتغير int يعمل على معالج 64bit هو 9223372036854775807- و كما ترى عدد الخانات هو ضعف حجم مصفوفتنا تقريباً,

بالتالي ستم الكتابة على الذاكرة التي تلي مصوفتنا :)

المشكلة كلها مشكلة مبرمج, و ليست مشكلة لغة, كل لغة تمكنك من التلاعب في الذاكرة يدوياً تحتوي على هذه المشاكل :)

بالطبع لكل شيء ضريبة, عموماً الهاكرز لا يقومون باختراق الأكود, هم يقومون باختراق عقلية مبرمج تلك الأكواد :)

أما ما تطلبه بأن يكون هناك أدوات تقوم بالتأكد فهذا غير ممكن, لأنك عندما تقوم بالتحكم في الذاكرة يدوياً, لا يستطيع المترجم تحديد ما تريد فعله!

المترجمات, برامج غبية إلى أبعد الحدود, و رغم التقدم الكبير في نظرياتها و تطبيقاتها فلا تزال برامج غبية إلى أبعد الحدود :)

خذ مثلاً عمليات الـ Optimization, لايوجد حتى الآن مترجم يدعي أنه يقوم بعملية Optimization للبرنامج ككل, و إنما ينظر لكل "سطر" و يقوم بمحاولة تحسينه,

لهذا نجد أن مبرمجي الأسمبلي بيننا :lol:

تحياتي ...

#5
Khaled.Alshaya كتب:

لهذا نجد أن مبرمجي الأسمبلي بيننا :lol:

<cough>

We exist because there is no patch for human stupidity

</cough>

:P

تم تعديل هذه المشاركة بواسطة Xacker في 7 مايو 2009 في 08:48

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#6

شكراً لكم اخوانى 

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

limits لمعرفة حدود الارقام فى النظام وليس الاعتماد انة يعرف الحد الخاص ب32بت)

عموما قمت برفع الكتاب 

التحميل

اقتباس
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int check_authentication(char *password) {

  int auth_flag = 0;

  char password_buffer[16];

  strcpy(password_buffer, password);

  if(strcmp(password_buffer, "brillig") == 0)

  auth_flag = 1;

  if(strcmp(password_buffer, "outgrabe") == 0)

  auth_flag = 1;

  return auth_flag;

}

int main(int argc, char *argv[]) {

  if(argc < 2) {

  printf("Usage: %s <password>\n", argv[0]);

  exit(0);

  }

  if(check_authentication(argv[1])) {

  printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");

  printf(" Access Granted.\n");

  printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");

  } else {

  printf("\nAccess Denied.\n");

  }

}

اقتباس
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int check_authentication(char *password) {

  char password_buffer[16];

  int auth_flag = 0;

  strcpy(password_buffer, password);

  if(strcmp(password_buffer, "brillig") == 0)

  auth_flag = 1;

  if(strcmp(password_buffer, "outgrabe") == 0)

  auth_flag = 1;

  return auth_flag;

}

int main(int argc, char *argv[]) {

  if(argc < 2) {

  printf("Usage: %s <password>\n", argv[0]);

  exit(0);

  }

  if(check_authentication(argv[1])) {

  printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");

  printf(" Access Granted.\n");

  printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");

  } else {

  printf("\nAccess Denied.\n");

  }

}

كمبرمج سى هل تلاحظ اى فرق بين الكودين ؟ فقط تبديل السطرين المظللين    والذى لا بلاحظة ا ى مبرمج ان هذا خطاء ؟

فى الفصل 0x320

فى الكتاب سيقوم بشرح كيف ان الكود الاول يحتوى ثغرة ويمكنك المخترق من كسر البرنامج

وكيف ان البرنامج الاخر قام بسد تلك الثغرة 

وقيس على ذلك تلك الانواع من الثغرات التى تحتاج الى مبرمج سى + مكتشف اخطاء (والذى بدورة يجب ان ذو خبرة وتركيز عالى

اذا قرات كيف اكتشف المولف الخطاء اكتشفة عن طريق قراء خارج التنقيح وعن طريق خطوات منطقية (اى يمكن تحوليها لخوازمية) لكن فقط بيئة التطوير يجب ان تنبها الى ذلك المتغير يجب ان يكون بعيد عن القراء والعبث 

نعم الكمبيوتر كائن غبى لكن اى شى منطقى يمكن تحويلة لخوازمية يفهمها خاصة ان ذلك الشى غير منطقى الا لمبرمج ينقح عن طريق الاسمبلى 

ارجو تصليح معلوماتى ان كنت اخطات 

تحياتى وشكرا لك على اجابتك على تساولتى

name : mohamedyosry

#7

We exist because there is no patch for human stupidity

:lol: :lol: :lol:

أخي المثالان متساويان, و كلاهما يحتويان على نفس الثغرة, و لا فرق في كتابة أي السطرين في الأول :)

لو أردت سد الثغرة, تستطيع استخدام strncpy أو memcpy ....

تحياتي ....

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 7 مايو 2009 في 15:41

#8

نعم اخى من وجة نظر مبرمج سى لا يوجد اى اختلاف

لكن من وجة نظر مكتشف ثغرات هناك اختلاف (يمكنك مراجعة ذلك الفصل من الكتاب للتاكد )

الكتاب يصف الكود الثانى بعد تغيير السطر فقط

اقتباس
This simple change puts the auth_flag variable before the password_buffer in memory. This eliminates the use of the return_value variable as an execution control point, since it can no longer be corrupted by an overflow.

اتكلم عن هذا النوع من الاخطاء

تم تعديل هذه المشاركة بواسطة apex في 7 مايو 2009 في 17:02

name : mohamedyosry

#9

السلام عليكم ....

حسناً أخي نفس الكلام الذي قلته لك في الأول..

هناك overflow في الحالتين :)

الآن المثال الثاني سيعمل دون مشاكل على منصة little-endian... و لكن قم بترجمته على منصة big-endian كـ 68K و ستظهر المشكلة من جديد, و يصبح المثال الأول هو الصحيح :)

كما قلت, الحل هو أن تكتب كود "آمن", إذا كتبت كود في C يعتمد على المنصة الفلانية في تصرف معين, فإنك عند نقله سترى العجب العجاب :lol:

تحياتي ....

#10

شكرا اخى على المعلومات (ما هو الجزء فى الكود السابق الذى يعتمد على نوع المنصة )

ما هى طرق معالجة تلك المشكلات فى البرامج الضخمة

هل يقومون باعادة كتابة الكود

ام هناك تقنيات اخرى

تم تعديل هذه المشاركة بواسطة apex في 7 مايو 2009 في 19:14

name : mohamedyosry

#11

حسناً, لاتوجد طريقة واحدة لمعرفة الخلل :) و إلا لما كان هناك ثغرات ...

عموماً, البرامج الضخمة, تقسم إلى أجزاء, و قلب البرنامج أو المحرك الرئيسي أو لتقل مكتبات البرنامج يقوم ببرمجتها الـ Senior Programmers... أي مبرمجون بخبرة كبيرة,

هذا هو الحل الوحيد :)

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

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

و بالتالي فإن هذه الأمور يتم تلافيها..... بالطبع لايتم تلافي جميع الثغرات :) و لكن يبقى القليل لإخواننا الهاكرز :lol:

كتابة كود Portable C Code ليس صعباً فحسب, و لكنه يحتاج لهاكرز ( هاكرز و ليس كراكرز :P )

لديك هاكرز نواة لينكس, لديك أيضاً Mozilla .. مثلاً Mozilla أكوادها تضمن لك ترجمتها على أكثر من 25 منصة بدون مشاكل ( ربما أكثر من عدد الـ VM المتوفرة لـ Java :P )

إضافة إلى ذلك شكراً على الكتاب القيم, قمت بتحميله :)

تحياتي ....

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 7 مايو 2009 في 19:06

#12

شكرا على النقاش

معلومات قيمة جزاك الله خيرا

لكن لدى استفسار اخير

(ما هو الجزء فى الكود السابق الذى يعتمد على نوع المنصة ؟)

انوى وضع فكرة debugger المكتشف للثغرات (عندما يتم اخبارة) على قائمتى وساتيح لنفسى للقراء فى تلك النقطة اكثر حين اتفرغ ;)

وشجعتنى على قراء اكواد الهاكر (الذى تضع شعارهم ;) لعلنا نستفيد من خبراتهم

name : mohamedyosry

مواضيع مشابهة