مرحباً أعزائي، اليوم سوف نتحدث عن نوع من انواع ثغرات الclient-side ألا و هي ثغرة HTTP Header Injection.

 

ما هي HTTP Response Splitting : 

هي أحد أنواع ثغرات الclient-side التي تظهر اذا تم استخدام مدخلات تحت تحكم المستخدم كقيم لHTTP Response Headers بدون تطهير و تأكد مناسبين، الأمر الذي قد يؤدي الي أمور خطيرة مثل ثغرات الCross Site Scripting و الCache Poisoning.

 

في هذه الحالة يستطيع المهاجم استخدام قيمة الresponse header و اضافة الصيغتين CR و LF للخروج من الheader الراجع من الserver و إضافة الheaders المرادة، مما يسمح للمهاجم باستغلال الثغرة لتنفيذ هجوم Cache Poisoning اذا ما كان هناك caching server و من ثم إعادة نفس الرد من الserver لكل من يستخدم الموقع.

يمكن أيضا الخروج كلياً من قسم الheaders و إضافة أي محتوي يريده المهاجم في قسم الbody من الرد، و الذي سوف يتم عرضه من قبل المتصفح. في هذه الحالة يمكن تنفيذ هجمات الCross-Site Scripting و التي قد تؤدي إلي سرقة حسابات المستخدمين.

 

الصيغة CR هي اختصار لمصطلح Carriage Return، و التي تستخدم في الكتابة للرجوع لبداية السطر و عادةً ما توضح عن طريق كتابة r\ في لغات البرمجة. الصيغة الأخري، ألا و هي LF  هي اختصار للمصطلح Line Feed، و تستخدم للحصول علي سطر جديد، سواء في ملف أو غيره، و تستخدم عن طريق كتابة n\ في العديد من لغات البرمجة.

 

الصيغتين السابق ذكرهما لا يستخدمان عادةً بنفس الطريقة كما هو الحال في لغات البرمجة عندما نستخدمهما في البحث عن ثغرات الHeader Injection، لأن الweb applications تعتمد علي تقنية الURL Encoding في فهم و ترجمة أي مدخل ما لم يكن أحد حروف اللغة الإنجليزية أو أحد الأرقام من 0-9. لذلك، تم تعيين القيمة 0a% و 0d% للقيمتين n\ و r\ بالترتيب، علي أن تستخدم القيمة 0a% حينما نود التعبير عن الLF، و القيمة 0d% حين يتم التعبير عن الCR.

 

أحد اكثر الأماكن شيوعاً لوجود هذا النوع من الثغرات هما الSet-Cookie و الLocation Headers. في الحالة الأولي يتم استخدام مدخل من المستخدم مباشرة كقيمة لcookie، و التي سوف تستخدم لاحقاً من قِبَل الweb application لتحديد حالة المستخدم. في الحالة الثانية يتم استخدام المدخل كقيمة الLocation Header، و الذي تستخدمه المتصفحات لمعرفة الهدف المرات التحويل إليه من قبل الweb application، سوف نشرح كل من هذين السيناريوهين لاحقا في هذا المقال.

 

مثال 1:

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

 

http://example.com?lang=en

 

اذا ما تم الضغط علي هذه ال link، يتم إرسال طلب GET ل http://example.com?lang=en. يستقبل الserver الطلب، ثم يتم تحويل المستخدم لنفس الصفحة و لكن في الresponse يتم تحديد http header جديد، اسمه Set-Cookie و قيمته هي lang=en.

 

في هذه الحالة يقوم الserver باستخدام القيمة المخصصة للمدخل lang مباشرة في الheader المسمي Set-Cookie بدون أي تأكد من عدم احتواؤه علي الصيغتين CR و LF مما يؤدي لظهور ثغرة HTTP Header Injection. في هذه الحالة يستطيع المهاجم استخدام الثغرة لتثبيت headers جديدة بأي قيم مرادة كالآتي:

 

http://example.com?lang=en%0d%0aSet-Cookie:hacked=1

 

في المثال السابق، يقوم المهاجم بالخروج من قيمة الSet-Cookie header الأولي (الأصلية) عبر استخدام الصيغتين 0d% و 0a% متتابعتين، ثم إضافة header جديد إسمه Set-Cookie و قيمته hacked=1 كتوضيح للثغرة، التالي هو منظر تخيلي للجزء المعني من رد الserver بعد الطلب السابق:

HTTP/1.1 200 OK

Content-Type: text/html

Set-Cookie: lang=en

Set-Cookie: hacked=1

 

يمكن للمهاجم أيضا تغيير محتوي الصفحة كما ذكرنا سابقا عن طريق إضافة أكواد HTML لقسم الbody من رد الserver، الأمر الذي يمكن إستغلاله بسهولة للحصول علي و استغلال ثغرة Cross-Site Scripting إذا ما كان وجود القيم < و > في المدخلات مسموحاً من قِبَل الserver. التالي هو طلب GET تخيلي للاستغلال المذكور:

 

http://example.com/?lang=en%0d%aContent-Length:53%0d%0a%0d%a%3Chtml%3E%3Cscript%3Ealert%28document.cookie%29%3C%2fscript%3E%3C%2fhtml%3E

في المثال السابق يتم إستخدام الصيغتين 0d% و 0a% متبوعتان بالheader المسمى Content-Length و قيمته 53، مما يخبر المتصفح ان عدد البايتات (الحروف) المراد إظهارها كbody للرد هو 53. يتم بعد ذلك استخدام نفس الصيغتين و لكن مرتين متتابعتين، و ذلك لإعلام المتصفح اننا نريد الوصول لقسم الbody من إجابة الserver، ثم بعد ذلك يتم حقن القيمة المراد إظهارها من المتصفح.

القيمة  %3Chtml%3E%3Cscript%3Ealert%28document.cookie%29%3C%2fscript%3E%3C%2fhtml%3E ما هي الا <html><script>alert(document.cookie)</script></html>  و لكن بعمد عملية  URL encoding. المثال يقوم بحقن كود javascript و الذي يستخدم دالة ال alert لإظهار قيمة الcookie الخاصة بالمستخدم كمثال. التالي هو المنظر التخيلي للرد القادم من الserver:

HTTP/1.1 200 OK

Content-Type: text/html

Set-Cookie: lang=en

Content-Length: 53

<html><script>alert(document.cookie)></script></html>

 

مثال 2:

 

في هذا المثال سنفترض اننا اكتشفنا ثغرة open redirects (تحويل مفتوح) في أحد المواقع و نود أن نستغلها بصورة أكبر لإحداث ثغرة Cross-Site Scripting. في هذه الحالة سنفترض أن الURL المصاب هو الآتي:

 

http://example.com?redirect=http://evil.com

 

على أن يكون المدخل المسمي redirect هو المستخدم من قِبَل الserver للتحويل للURL المعطي له، في هذا المثال http://evil.com، و لنتفرض أيضا أن الآتي هو الرد العائد من الserver في حين تنفيذ طلب GET للURL السابق ذكره:

HTTP/1.1 302 Found

Location: http://evil.com

 

إكتشفنا بعد ذلك وجود ثغرة Header Injection و إكتشفنا ان الserver يقوم بتمرير قيمة المدخل redirect مباشرةً للLocation header، تماما كما هو الحال في المثال الأول، و نريد اﻵن استغلال الثغرة للحصول علي ثغرة Cross-Site Scripting. هناك أمر مختلف في هذه الحالة و الذي يجب ملاحظته حتي يكون الهجوم ناجح في النهاية، ألا و هو الresponse code العائد من الserver. في المثال الأول الresponse code كان 200 OK، في هذه الحالة لم يكن هناك مشكلة في استغلال الثغرة، و لكن في حالة المثال الثاني الresponse code هي 302 Found. المتصفحات تستخدم هذا الresponse code للتحويل تلقائياً للقيمة المخصصة للLocation header، إذاً فما العمل في هذه الحالة ؟

 

لحسن الحظ، فمعظم المتصفحات تستخدم آخر قيمة موجودة في الرد للresponse code إذا ما كانت قيمة الContent-Length header للresponse code الأصلي صفر،  بمعني أننا في هذه الحالة يمكننا أيضاً إضافة الresponse code المناسب و سوف يستخدمها المتصفح تلقائياً و سيتجاهل القيمة الأصلية و في هذه الحالة تعرف الثغرة باسم HTTP Response Splitting. التالي هو قيمة تخيلية لما سيحقنه المهاجم:

 

http://example.com/?redirect=http://evil.com%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2053%0d%0a%0d%0a%3Chtml%3E%3Cscript%3Ealert%28document.cookie%29%3C%2fscript%3E%3C%2fhtml%3E

 

في المثال السابق يتم الآتي:

 

  • إستخدام الصيغتين المعروفتين للخروج من الLocation header
  • إضافة Content-Length header قيمته 0 لإبطال مفعول الرد الأصلي من الserver
  • إضافة HTTP/1.1 200 OK كبداية للرد الجديد
  • إضافة Content-Type header قيمته text/html ليعلم المتصفح ان قسم الbody من الرد سيحتوي علي كود HTML
  • إضافة Content-Length header آخر، و لكن هذه المرة قيمته 53، و هو طول كود الHTML المحقون
  • و أخيرا كود الHTML المحقون نفسه، و هي نفس القيمة المستخدمة في المثال الأول

 

التالي هو منظر تخيلي للرد الناتج من الطلب السابق :

HTTP/1.1 302 Found

Location: http://evil.com

Content-Length: 0

 

HTTP/1.1 200 OK

Content-Type: text/html

Content-Length: 53

<html><script>alert(document.cookie)</script></html>

 

أتمني أن تكونوا قد استفدتم من الموضوع، و أعتذر لطول المقال و إذا كان هناك أمراً غير واضح.

الباب مفتوح للاستفسارات طبعا

اقرا ايضا : إستغلال HTTP header في ثغرات XSS