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

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

مثل المترجمين ، يتم استخدام التحليل اللغوي والنحوي لبناء تمثيل داخلي ، وغالبًا ما يكون شجرة تحليل (AST ، Abstract Syntax Tree). يقوم التحليل المعجمي بتقسيم نص البرنامج إلى الحد الأدنى من العناصر الدلالية ، في الإخراج الذي يستقبل مجموعة من الرموز. يتحقق التحقق من أن الدفق المميز يطابق قواعد لغة البرمجة ، أي أن دفق الرمز المميز الناتج صحيح من وجهة نظر اللغة. نتيجة للتحليل ، تم بناء شجرة تحليل - وهي بنية تقوم بنمذجة الكود المصدري للبرنامج. بعد ذلك ، يتم تطبيق التحليل الدلالي ؛ فهو يتحقق من الوفاء بشروط أكثر تعقيدًا ، على سبيل المثال ، مراسلات أنواع البيانات في تعليمات المهمة.
يمكن استخدام شجرة التحليل كتمثيل داخلي. يمكنك أيضا الحصول على نماذج أخرى من شجرة التحليل. على سبيل المثال ، يمكنك ترجمتها إلى رمز مكون من ثلاثة عناوين ، والذي بدوره يقوم بإنشاء رسم بياني لتدفق التحكم (CFG). عادة ، CFG هو النموذج الأساسي لخوارزميات التحليل الثابت.

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

على سبيل المثال ، إذا كان من الضروري تحديد ما إذا كان التعبير ثابتًا ، وكذلك قيمة هذا الثابت ، عندئذٍ تحل مشكلة ثوابت الانتشار (الانتشار الثابت). إذا كان من الضروري تحديد نوع المتغير ، فيمكننا التحدث عن مشكلة انتشار الكتابة. إذا كنت بحاجة إلى فهم المتغيرات التي يمكن أن تشير إلى منطقة معينة من الذاكرة (تخزين نفس البيانات) ، فإننا نتحدث عن مهمة تحليل المترادفات (تحليل الاسم المستعار). هناك العديد من مهام تحليل تدفق البيانات الأخرى التي يمكن استخدامها في محلل ثابت. مثل خطوات بناء نموذج الكود ، تُستخدم هذه المهام أيضًا في المجمعين.
في نظرية بناء المترجمين ، يتم وصف حلول لمشكلة التحليل الداخلي الإجرائي لدفق البيانات (من الضروري تتبع البيانات في إجراء / وظيفة / طريقة واحدة). تستند القرارات إلى نظرية المشابك الجبرية وعناصر أخرى من النظريات الرياضية. يمكن حل مشكلة تحليل تدفق البيانات في وقت متعدد الحدود ، أي لفترة مقبولة لأجهزة الكمبيوتر ، إذا كانت شروط المشكلة تلبي شروط نظرية قابلية الحل ، والتي لا تحدث دائمًا في الممارسة العملية.
سنخبرك المزيد عن حل مشكلة التحليل الداخلي الإجرائي لتدفق البيانات. لتعيين مهمة محددة ، بالإضافة إلى تحديد المعلومات التي تحتاجها ، تحتاج إلى تحديد قواعد تغيير هذه المعلومات عند تمرير البيانات وفقًا لتعليمات CFG. تذكر أن العقد الموجودة في CFG هي الكتل الأساسية - مجموعات من التعليمات ، والتي يكون تنفيذها دائمًا متسلسلًا ، وتشير الأقواس إلى إمكانية نقل السيطرة بين الكتل الأساسية.
لكل تعليمات
S مجموعات محددة:
- gen(S) (المعلومات الناتجة عن التعليمات S ) ،
(المعلومات التي دمرتها التعليمات S ) ،- في(S) (المعلومات في النقطة قبل التعليمات S ) ،
- خارج(S) (المعلومات في نقطة بعد التعليمات S )
الهدف من تحليل تدفق البيانات هو تحديد مجموعات
في(S) و
خارج(S) لكل تعليمات
S البرامج. يتم تحديد النظام الأساسي للمعادلات التي يتم بها حل مهام تحليل تدفق البيانات بالعلاقة التالية (معادلات تدفق البيانات):
out(S)=(in(S)−kill(S))∪gen(S)،
in(S)=∪iout(Si).
تقوم العلاقة الثانية بصياغة القواعد التي يتم بها "تجميع" المعلومات عند نقاط التقاء أقواس CFG (
Si - السلف
S في CFG). تشغيل الاتحاد ، تقاطع وغيرها يمكن استخدامها.
تتم صياغة المعلومات المطلوبة (مجموعة قيم الوظائف المقدمة أعلاه) باعتبارها شبكة جبرية. وظائف
gen و

تعتبر تعيينات رتيبة على المشابك (وظائف التدفق). بالنسبة لمعادلات تدفق البيانات ، يكون الحل هو النقطة الثابتة لهذه التعيينات.
تبحث الخوارزميات لحل مشكلات تحليل تدفق البيانات عن الحد الأقصى للنقاط الثابتة. هناك عدة طرق لحل هذا الحل: الخوارزميات التكرارية ، وتحليل المكونات المرتبطة بقوة ، وتحليل T1-T2 ، والتحليل الزمني ، والتحليل الهيكلي ، وما إلى ذلك. هناك نظريات حول صحة هذه الخوارزميات ؛ فهي تحدد نطاق إمكانية تطبيقها على المشاكل الحقيقية. أكرر ، قد لا يتم استيفاء شروط النظريات ، مما يؤدي إلى خوارزميات أكثر تعقيدًا ونتائج غير دقيقة.
تحليل Interprocedural
في الممارسة العملية ، من الضروري حل مشاكل التحليل المتداخل لتدفق البيانات ، حيث نادراً ما تكون مشكلة عدم الحصانة مترجمة بالكامل في وظيفة واحدة. هناك العديد من الخوارزميات الشائعة.
وظائف مضمنة . عند نقطة استدعاء الوظيفة ، قمنا بتضمين الوظيفة المسماة ، وبالتالي تقليل مهمة التحليل بين المهام إلى مهمة التحليل داخل الإجراء. يتم تنفيذ هذه الطريقة بسهولة ، ولكن في الممارسة العملية ، عندما يتم تطبيقها ، يتم تحقيق انفجار اندماجي بسرعة.
بناء رسم بياني عام لتدفق التحكم في
البرنامج ، حيث يتم استبدال مكالمات الوظائف بعمليات انتقالية إلى عنوان البدء الخاص بالوظيفة المدعوة ، ويتم استبدال تعليمات الإرجاع بنقالات إلى جميع الإرشادات التي تتبع جميع الإرشادات الخاصة باستدعاء هذه الوظيفة. يضيف هذا النهج عددًا كبيرًا من مسارات التنفيذ غير القابلة للتحقيق ، مما يقلل بدرجة كبيرة من دقة التحليل.
خوارزمية تشبه تلك السابقة ، ولكن عند التبديل إلى وظيفة ، يتم
حفظ السياق - على سبيل المثال ، إطار مكدس. وبالتالي ، يتم حل مشكلة إنشاء مسارات غير قابلة للتحقيق. ومع ذلك ، فإن الخوارزمية قابلة للتطبيق مع عمق اتصال محدود.
بناء وظيفة المعلومات (ملخص وظيفة). خوارزمية التحليل الأكثر قابلية للتطبيق. يعتمد ذلك على بناء ملخص لكل وظيفة: القواعد التي يتم بواسطتها تحويل المعلومات حول البيانات عند تطبيق هذه الوظيفة ، اعتمادًا على القيم المختلفة لوسائط الإدخال. يتم استخدام ملخص جاهز في التحليل الإجرائي الداخلي للوظائف. تتمثل الصعوبة المنفصلة هنا في تحديد ترتيب اجتياز الوظيفة ، لأنه في تحليل كل حالة على حدة ، ينبغي بناء ملخص بالفعل لجميع الوظائف التي تسمى. عادة ، يتم إنشاء خوارزميات تكرارية خاصة لاجتياز رسم بياني للمكالمات.
يعد تحليل تدفق البيانات Interprocedural مهمة صعبة للغاية ، ولهذا السبب يحتاج المحلل إلى تنفيذ عدد من التحسينات والافتراضات (من المستحيل إيجاد الحل الدقيق في الوقت المناسب لقوة الحوسبة). عادة ، عند تطوير محلل ، من الضروري إيجاد حل وسط بين مقدار الموارد المستهلكة ، وزمن التحليل ، وعدد الإيجابيات الخاطئة ونقاط الضعف الموجودة. لذلك ، يمكن للمحلل الثابت أن يعمل لفترة طويلة ، ويستهلك الكثير من الموارد ويعطي إيجابيات خاطئة. ومع ذلك ، بدون هذا ، من المستحيل العثور على نقاط الضعف الأكثر أهمية.
في هذه المرحلة ، تختلف أدوات التحليل الثابتة عن العديد من الأدوات المفتوحة ، والتي ، على وجه الخصوص ، يمكنها وضع نفسها في البحث عن نقاط الضعف. تكون الاختبارات السريعة في الوقت الخطي جيدة عندما تحتاج إلى الحصول على النتيجة بسرعة ، على سبيل المثال ، أثناء التجميع. ومع ذلك ، لا يمكن لهذا النهج العثور على نقاط الضعف الأكثر أهمية - على سبيل المثال ، المتعلقة بتنفيذ البيانات.
تحليل ملوث
يجب علينا أيضًا أن نتطرق إلى إحدى مهام تحليل تدفق البيانات - تحليل الملوثات. يتيح لك تحليل Taint توزيع الأعلام في جميع أنحاء البرنامج. هذه المهمة هي المفتاح لأمن المعلومات ، لأنه بمساعدة ذلك يتم اكتشاف نقاط الضعف المتعلقة بتنفيذ البيانات (حقن SQL ، البرمجة النصية لموقع crossite ، عمليات إعادة التوجيه المفتوحة ، تزوير مسار الملف ، وما إلى ذلك) ، وكذلك تسرب البيانات السرية (إدخال كلمة المرور في سجلات الأحداث ، ونقل البيانات غير آمنة).
دعنا نحاول محاكاة مهمة. لنفترض أننا نريد تتبع أعلام n -
f1،f2،...،fn . سيكون هناك الكثير من المعلومات هنا الكثير من المجموعات الفرعية
\ {f_1، ...، f_n \} ، نظرًا لأن كل متغير في كل نقطة في البرنامج نريد تحديد أعلامه.
بعد ذلك ، نحن بحاجة إلى تحديد وظائف التدفق. في هذه الحالة ، يمكن تحديد وظائف التدفق حسب الاعتبارات التالية.
- يتم إعطاء الكثير من القواعد التي يتم تعريف الإنشاءات التي تؤدي إلى ظهور أو تغيير مجموعة من العلامات.
- تقلب عملية التعيين الأعلام من اليمين إلى اليسار.
- أي عملية غير معروفة لمجموعات القواعد تجمع بين الإشارات من جميع المعاملات وتضاف المجموعة الأخيرة من العلامات إلى نتائج العملية.
أخيرًا ، تحتاج إلى تحديد قواعد دمج المعلومات في نقاط الوصلات الخاصة بأقواس CFG. يتم تحديد الدمج بواسطة قاعدة الاتحاد ، أي إذا كانت مجموعات مختلفة من الإشارات لمتغير واحد تأتي من كتل أساسية مختلفة ، عندئذ يتم دمجها عند الدمج. بما في ذلك الإيجابيات الخاطئة تأتي من هنا: الخوارزمية لا تضمن أن المسار إلى CFG الذي ظهر العلم يمكن تنفيذها.
على سبيل المثال ، تحتاج إلى الكشف عن الثغرات الأمنية مثل SQL Injection. تحدث مشكلة عدم الحصانة هذه عندما تندرج بيانات لم يتم التحقق منها من المستخدم في أساليب العمل مع قاعدة البيانات. من الضروري تحديد أن البيانات جاءت من المستخدم وإضافة علامة تافهة إلى هذه البيانات. عادةً ما تحدد قاعدة قاعدة المحلل قواعد تعيين العلامة الملوثة. على سبيل المثال ، قم بتعيين إشارة إلى قيمة الإرجاع للأسلوب getParameter () لفئة الطلب.

بعد ذلك ، ستحتاج إلى توزيع العلامة خلال البرنامج الذي تم تحليله باستخدام تحليل التلوين ، بالنظر إلى أنه يمكن التحقق من صحة البيانات وقد تختفي العلامة على أحد مسارات التنفيذ. يقوم المحلل بتعيين العديد من الوظائف التي تزيل الأعلام. على سبيل المثال ، يمكن لوظيفة التحقق من صحة البيانات من علامات html أن تمسح علامة الضعف في البرمجة النصية للمواقع المشتركة (XSS). أو ، الدالة لربط متغير إلى تعبير SQL تزيل علامة التضمين في SQL.
قواعد البحث في الضعف
نتيجة لتطبيق الخوارزميات المذكورة أعلاه ، يتم استكمال التمثيل الوسيط بالمعلومات اللازمة للبحث عن الثغرات الأمنية. على سبيل المثال ، في نموذج التعليمات البرمجية ، تظهر معلومات حول المتغيرات التي تنتمي إلى إشارات معينة ، والتي تكون البيانات ثابتة. تتم صياغة قواعد البحث عن الثغرات الأمنية من حيث نموذج الشفرة. تصف القواعد الميزات الموجودة في العرض المؤقت النهائي والتي قد تشير إلى وجود ثغرة أمنية.
على سبيل المثال ، يمكنك تطبيق قاعدة بحث عن ثغرة أمنية تعرّف استدعاء أسلوب باستخدام معلمة تحتوي على علامة taint. بالعودة إلى مثال حقن SQL ، نتحقق من أن المتغيرات التي تحمل علامة taint لا تندرج في وظيفة استعلام قاعدة البيانات.
اتضح أن جزءًا مهمًا من أداة التحليل الثابت ، بالإضافة إلى جودة الخوارزميات ، هو التكوين وقاعدة القاعدة: أي وصف للإنشاءات في الكود يولِّد أعلامًا أو معلومات أخرى ، مما يبني التحقق من صحة هذه البيانات ، وأي بناء له يعد استخدام هذه البيانات أمرًا بالغ الأهمية.
طرق أخرى
بالإضافة إلى تحليل تدفق البيانات ، هناك طرق أخرى. أحد أشهرها هو التنفيذ الرمزي أو التفسير التجريدي. في هذه الطرق ، يعمل البرنامج على مجالات مجردة ، وحساب وتوزيع قيود البيانات في البرنامج. باستخدام هذا النهج ، لا يمكن للمرء العثور على الثغرة الأمنية فحسب ، ولكن أيضًا حساب الشروط على بيانات المدخلات التي تكون الثغرة الأمنية قابلة للاستغلال في ظلها. ومع ذلك ، فإن هذا النهج له عيوب خطيرة - مع حلول قياسية للبرامج الحقيقية ، تنفجر الخوارزميات بشكل كبير ، وتؤدي التحسينات إلى خسائر فادحة في جودة التحليل.
الاستنتاجات
في النهاية ، أعتقد أن الأمر يستحق التلخيص ، والحديث عن إيجابيات وسلبيات التحليل الثابت. من المنطقي أن نقارن بالتحليل الديناميكي ، الذي يحدث فيه بحث الثغرات الأمنية أثناء تنفيذ البرنامج.

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