شرح حقن القالب من جانب الخادم (Part 3)

Safely LocK
0

 




المقدمة


في الأقسام السابقة، استكشفنا كيفية تحديد ثغرات حقن القوالب (Template Injection) وتحديد محرك القوالب المستخدم. الآن، لنأخذ الأمور خطوة إلى الأمام  نحول هذه الثغرة البسيطة إلى خطر أمني جدي يمكن أن يؤدي إلى اختراق كامل للنظام.




تصعيد الهجوم (Escalating the Attack)


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


على سبيل المثال، تنفيذ أوامر النظام (execute system commands) يسلط الضوء على خطورة الثغرة. تعتمد طريقة التصعيد على المحرك (مثل "Jinja2" هنا). تنفيذ الأوامر يسمح للمهاجمين بالوصول إلى ملفات حساسة (مثل `/etc/shadow` على لينكس)، تعديل الإعدادات، تصعيد الصلاحيات، أو مهاجمة أجهزة أخرى على الشبكة، مما يثبت التأثير الكبير للثغرة.




البحث عن الوصول إلى النظام عبر كود بايثون (Searching for System Access via Python Code):


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



عادةً في بايثون، يمكنك تنفيذ أوامر النظام باستخدام الدالة `os.system()` من الوحدة `os`. على سبيل المثال، هذا السطر من كود بايثون سينفذ أمر النظام `ls` لعرض محتويات المجلد الحالي:
os.system(‘ls’)




ومع ذلك، إذا قمت بإرسال هذه الحمولة إلى تطبيقنا، على الأرجح لن تحصل على النتائج المتوقعة:



بدلًا من ذلك، من المحتمل أن تواجه خطأ في التطبيق:



هذا لأن الوحدة "os" غير معترف بها في بيئة القالب. بشكل افتراضي، لا تحتوي على وحدات خطيرة مثل os.


عادةً، يمكنك استيراد وحدات بايثون باستخدام الصيغة `import MODULE`، أو `from MODULE import`، أو أخيرًا `import('MODULE')`. لنحاول استيراد الوحدة `os`:


إذا قمت بإرسال هذه الحمولة إلى التطبيق، من المحتمل أن ترى خطأ آخر:

 


هذا لأنه لا يمكنك استيراد وحدات داخل قوالب Jinja. معظم محركات القوالب تمنع استخدام وظائف خطيرة مثل import أو تقوم بإنشاء قائمة سماح (allowlist) تسمح للمستخدمين بتنفيذ عمليات معينة فقط داخل القالب. للهروب من هذه القيود في Jinja2، تحتاج إلى الاستفادة من تقنيات الهروب من الحماية (sandbox-escape techniques) في بايثون.


الهروب من الحماية باستخدام دوال بايثون المدمجة (Escaping the Sandbox by Using Python Built-in Functions)


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




الفكرة الأساسية (The Basic Idea):


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




عندما تقوم بحقن هذا الكود في ثغرة تسمى "حقن القوالب"، سترى قائمة بالفئات المتاحة في بايثون، مثل هذا:





هذه القائمة هي جميع الفئات التي ترث من الفئة الأساسية object. إذن كيف يحدث هذا؟ دعني أفصل الكود خطوة بخطوة:




تفصيل الكود (Breaking Down the Code)


ثم يمكنك استخدام السمة `__bases__` للإشارة إلى الفئات الأساسية لفئة **list**.



هذه السمة ستعيد tuple (وهي مجرد قائمة مرتبة في بايثون) من جميع الفئات الأساسية لفئة list. الفئة الأساسية هي الفئة التي تم بناء الفئة الحالية منها؛ list لديها فئة أساسية تسمى object. بعد ذلك، نحتاج إلى الوصول إلى فئة object بالإشارة إلى العنصر الأول في tuple.




 

أخيرًا، نستخدم `__subclasses__()` للإشارة إلى جميع الفئات الفرعية للفئة.


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




الهدف: تنفيذ الأوامر (Executing Commands)


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


في بايثون، هناك دالة مدمجة تسمى "__import__"، وتُستخدم لاستيراد الوحدات. ولكن إذا كان التطبيق (مثل Jinja2، على سبيل المثال) يمنعك من استخدامها مباشرة، عليك أن تكون ذكيًا وتصل إليها بشكل غير مباشر. هنا نستخدم الوحدة "__builtins__"، التي تحتوي على جميع الدوال والفئات المدمجة في بايثون. يمكنك الوصول إلى هذه الوحدة من خلال أي فئة أخرى تحتوي على سمة "__builtins__".




خطوة عملية: العثور على الفئة الصحيحة (Practical Step: Finding the Right Class)


في القائمة التي حصلنا عليها من "__subclasses__()"، هناك فئة تسمى "catch_warnings". هذه فئة يمكننا استغلالها. للعثور عليها، نستخدم حلقة في الكود كما يلي:



  • هذه الحلقة تمر عبر جميع الفئات في "__subclasses__()" ، عندما تجد فئة تحتوي على `catch_warnings` في اسمها، تقوم باستدعائها (إنشاء كائن منها).

  • عندما تنشئ كائنًا من `catch_warnings`، يكون لهذا الكائن سمة تسمى `_module`، والتي تُرجع وحدة تسمى `warnings`. وهذه الوحدة تحتوي على سمة `__builtins__`، والتي تتيح لنا الوصول إلى جميع الدوال المدمجة في بايثون، كما يلي:


عند تشغيل هذا الكود، ستحصل على قاموس يحتوي على جميع الدوال المدمجة، بما في ذلك `__import__`.




استخدام `__import__` لاستيراد وحدة (Using __import__ to Get a Module)


الآن بعد أن أصبح لدينا طريقة للوصول إلى `__import__`، يمكننا استخدامها لاستيراد وحدة مثل `os`، على سبيل المثال، ومن هناك تنفيذ الأوامر على النظام. سيبدو الكود كما يلي:



هنا، نقوم باستيراد وحدة `os`. بعد ذلك، يمكننا استخدام الدالة `system()` في `os` لتنفيذ أمر، كما يلي:


إذا كان التطبيق يعمل على نظام Linux، على سبيل المثال، فإن الأمر `ls` سيعرض محتويات المجلد الحالي. إذا كان يعمل على Windows، يمكنك استبداله بالأمر `dir`، على سبيل المثال.




أنظمة مختلفة، حيل مختلفة (Different Systems, Different Tricks)


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




ملاحظة أخيرة


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


أتمنى لك دائمًا النجاح!

إرسال تعليق

0تعليقات

إرسال تعليق (0)

#buttons=(موافق!) #days=(20)

يستخدم موقعنا ملفات تعريف الارتباط لتحسين تجربتك. تاكد الان
Ok, Go it!