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

1. حقن SQL
تم تصميم خدمة
partner.steampowered.com لتلقي المعلومات المالية من شركاء Steam. في صفحة تقرير المبيعات ، يتم رسم رسم بياني بأزرار تغير الفترة التي يتم خلالها عرض الإحصائيات. ها هم في المستطيل الأخضر:

يبدو طلب تنزيل الإحصائيات كما يلي:
حيث "UA" هو رمز البلد.حسنًا ، حان الوقت لعروض الأسعار!
لنجرب "UA":

لم ترجع الإحصائيات وهو أمر متوقع.
الآن "UA" ":

لقد عادت الإحصائيات مرة أخرى ويبدو أنها حقنة!
لماذا؟لنفترض أن تعليمات قاعدة البيانات تبدو كما يلي:
SELECT * FROM countries WHERE country_code = `UA`;
إذا قمت بإرسال UA '، فسيكون تعليمات قاعدة البيانات:
SELECT * FROM countries WHERE country_code = `UA``;
لاحظت الاقتباس الإضافي؟ وهذا يعني أن التعليمات غير صالحة.
وفقًا لبناء جملة SQL ، فإن الاستعلام أدناه صالح تمامًا (لا توجد علامات اقتباس إضافية):
SELECT * FROM countries WHERE country_code = `UA```;
يرجى ملاحظة أننا نتعامل مع مجموعة من
countryFilter [] . افترضت أنه إذا قمنا بتكرار معلمة
countryFilter [] في الاستعلام عدة مرات ، فسيتم دمج جميع القيم التي نرسلها في استعلام SQL بهذه الطريقة:
'value1', 'value2', 'value3'
نتحقق ونتأكد من:

في الواقع ، طلبنا إحصاءات من ثلاث دول من قاعدة البيانات:
`UA`, `,` ,`RU`
بناء الجملة صحيح - الإحصائيات عادت :)
تجاوز جدار حماية تطبيق ويبخوادم البخار تختبئ وراء Akamai WAF. يدرج هذا الخزي العصي في عجلات المتسللين (وليس كذلك). ومع ذلك ، تمكنت من التغلب عليه من خلال دمج قيم الصفيف في استعلام واحد (ما شرحته أعلاه) والتعليق. أولاً ، تأكد من توفر الأخير:
?countryFilter[]=UA`/*&countryFilter[]=*/,`RU
الطلب صالح ، لذلك هناك تعليقات في تشكيلتنا.
كان لدينا العديد من خيارات بناء الجملة ، وقواعد البيانات المحلية لاختبار الحمولات ، وشخصيات التعليق وعدد لا نهائي من الاقتباسات لجميع الترميزات ، بالإضافة إلى نصوص مكتوبة ذاتيًا على الثعبان ، ووثائق لجميع قواعد البيانات ، وإرشادات حول كيفية تجاوز جدران الحماية ، وويكيبيديا ، ومضاد. ليس الأمر أنه كان احتياطيًا ضروريًا للترويج للحقن ، ولكن نظرًا لأنه بدأ في كسر قاعدة البيانات ، فمن الصعب التوقف ...
يمنع WAF طلبًا عندما يصادف وظيفة فيه. هل تعلم أن
DB_NAME / ** /
() هو استدعاء دالة صالح؟ يعرف جدار الحماية أيضًا ويمنعه. ولكن ، بفضل هذه الميزة ، يمكننا تقسيم استدعاء الوظيفة إلى معلمتين!
?countryFilter[]=UA',DB_NAME(),'RU
لقد أرسلنا طلبًا باستخدام
DB_NAME / * على
أي حال * /
() - لم يفهم WAF أي شيء ، لكن قاعدة البيانات عالجت مثل هذه التعليمات بنجاح.
استرجاع القيم من قاعدة البياناتلذا ، مثال على الحصول على طول قيمة DB_NAME ():
https://partner.steampowered.com/report_xml.php?query=QuerySteamHistory&countryFilter[]=',(SELECTCASEWHEN(len(DB_NAME())=1)THEN'UA'ELSE'qwerty'END),'
في SQL:
SELECT CASE WHEN (len(DB_NAME())= 1) THEN 'UA' ELSE 'qwerty' END
حسنًا ، إنسانيًا:
DB_NAME() "1", “UA”, “qwerty”.
هذا يعني أنه إذا كانت المقارنة صحيحة ، في المقابل نحصل على إحصاءات للبلد "UA". ليس من الصعب التكهن بأن تجاوز القيم من 1 إلى اللانهاية ، سنجد عاجلاً أم آجلاً القيم الصحيحة.
بنفس الطريقة ، يمكنك التكرار عبر القيم النصية:
DB_NAME() “a”, "UA", "qwerty".
عادة ، يتم استخدام وظيفة "سلسلة فرعية" للحصول على الشخصية Nth ، لكن WAF حجبتها بعناد. هنا جاءت المجموعة لإنقاذ:
right(left(system_user,N),1)
كيف يعمل؟ نحصل على N من قيمة system_user التي نأخذ منها آخر حرف.
تخيل أن system_user = "البخار". هذه هي الطريقة التي سيبدو بها الحرف الثالث:
left(system_user,3) = ste right(“ste”,1) = e
باستخدام نص برمجي بسيط ، تم أتمتة هذه العملية وحصلت على اسم المضيف ، و user_user ، والإصدار ، وأسماء جميع قواعد البيانات. هذه المعلومات أكثر من كافية (الأخيرة حتى زائدة ، لكنها كانت مثيرة للاهتمام) لإثبات الأهمية.
بعد 5 ساعات ، تم إصلاح الثغرة الأمنية ، ولكن تم تعيين حالة الفرز عليها بعد 8 ساعات ، وبالفعل ، بالنسبة لي كان الأمر صعبًا للغاية لمدة 3 ساعات تمكن دماغي من النجاة من المراحل من الرفض إلى القبول.
شرح جنون العظمةنظرًا لعدم تحديد الثغرة الأمنية على أنها مقبولة ، أعتقد أن الخط لم يصل بعد إلى تقريري. لكنهم قاموا بإصلاح الخلل ، مما يعني أنه كان بإمكانهم تسجيله قبلي.
2. الحصول على جميع مفاتيح أي لعبة
في واجهة شريك Steam ، هناك وظيفة لتوليد مفاتيح اللعبة.
يمكنك تنزيل مجموعة المفاتيح التي تم إنشاؤها باستخدام الطلب:
https://partner.steamgames.com/partnercdkeys/assignkeys/ &sessionid=xxxxxxxxxxxxx&keyid=123456&sourceAccount=xxxxxxxxx&appid=xxxxxx&keycount=1&generateButton=Download
في هذا الطلب ، تكون معلمة
keyid هي معرف مجموعة المفاتيح ، و
keycount هو عدد المفاتيح التي يجب الحصول عليها من هذه المجموعة.
بالطبع ، توصلت يدي على الفور إلى القيادة
باستخدام keyid مختلفة ، ولكن هناك خطأ ينتظرني: "لم
أستطع إنشاء مفاتيح القرص المضغوط: لا توجد مهمة للمستخدم. ". اتضح أن ليس كل شيء بسيطًا جدًا ، وتأكد Steam من ما إذا كنت أملك مجموعة المفاتيح المطلوبة. كيف استطعت الالتفاف حول هذا الاختبار؟ انتباه ...
keycount=0
تم إنشاء ملف يحتوي على 36000 مفتاح للعبة Portal 2. Wow.
في مجموعة واحدة فقط كان هذا العدد من المفاتيح. وجميع المجموعات في الوقت الحاضر أكثر من 430،000. وبالتالي ، من خلال فرز قيم
keyid ، كنت مهاجمًا محتملًا يمكنه تنزيل جميع المفاتيح التي تم إنشاؤها من قبل مطوري لعبة Steam.
الاستنتاجات
- أنظمة WAF المكلفة من أفضل الشركات بعيدة عن ضمان أمن تطبيقات الويب الخاصة بك.
- إذا كنت صائد حشرات ، فحاول اختراق أعمق ما يمكن. كلما قل وصول المستخدمين إلى الواجهة ، زاد احتمال العثور على ثغرة في تلك الواجهة.
- المطورين وأصحاب الأعمال ، لا توجد تطبيقات آمنة تماما! ولكن انتظر. مزاج جيد!
لكن بجديةقم بعمل البنت ، ودفع نقاط الضعف ، وفكر بشكل استراتيجي.