هل سمعت يومًا بثغرة تُسمّى Blind IDOR؟ تبدو غريبة، أليس كذلك؟


هل سمعت يومًا بثغرة تُسمّى Blind IDOR؟ تبدو غريبة، أليس كذلك؟


سأتحدث اليوم – بمشيئة الله – عن ثغرة صادفتُها في إحدى أكبر الشركات.

ثغرة بدأت كميزة عادية تمامًا، لا يظهر عليها أي مؤشر يدلّ على خطورتها، ولا حتى ما يستحق التوقّف عنده… لكن مع التجربة والتعمّق تحوّلت إلى واحدة من أغرب وأقوى الثغرات التي مرّت عليّ في هذا المجال.


جهّز قهوتك ولنبدأ…

البداية: فحص اعتيادي للتارغت

كالعادة، بدأت بفحص الهدف الرئيسي:

http://redacted.com

كان الموقع كبيرًا نسبيًا، يحوي الكثير من الصفحات والوظائف والخصائص.

عزمت على فحصه كاملًا، وبدأت أتعمّق فيه يوميًا صفحةً صفحةً، ووظيفةً وظيفةً، مجرّبًا كل ما يمكن… وما لا يمكن.


ومع كثرة المحاولات لم أجد شيئًا قابلًا للاستغلال إطلاقًا، حتى أدوات الـ fuzzing لم تُظهر أي نتيجة مفيدة.


ولكن أثناء مرحلة الـ Recon لفت نظري أمر مهم للغاية…


كل شيء يدور حول API واحد


لاحظت أن المنصّة كلّها تعتمد على API واحد، وكل التفاعل الحقيقي يتم عبر نطاق فرعي محدد:

http://api.redacted.com


ومهما فعلت على الواجهة الأمامية، فالتنفيذ كلّه يمرّ من هنا.

فقررت التركيز عليه بالكامل.


بدأت بإجراء fuzzing موسّع، وكانت النتائج واضحة:


200 → الـ endpoint يعمل

404 → غير موجود

403 → موجود لكن ينقصك التفويض


وكما هو متوقّع، كانت معظم النقاط الحسّاسة تُرجع 403.



جرّبت عشرات طرق الـ bypass:

  • تعديل الهيدرز
  • تغيير شكل الأحرف
  • Encoding & Double Encoding


ولا واحدة نجحت.

وهنا تأكدت أن المشكلة ليست WAF… بل صلاحيات.


اختلاف الصلاحيات بين الحسابات

المنصة تمتلك نوعين من الحسابات:

  • حساب أفراد
  • حساب شركات


أنشأت حساب شركة، حصلت على الـ token، وعدت لأتلاعب بالـ endpoints التي كانت تُرجِع 403.


وفعلًا…

بعض الـ endpoints الحسّاسة أصبحت مفتوحة فورًا!


بدأت الصورة تتضح:

اختلاف الأدوار هو المفتاح.


البداية الحقيقية: Search Endpoint


من بين النقاط التي ظهرت أثناء الفحص:

/api/v2/all-users/search



الرد كان يعرض قائمة مستخدمين بمعلومات بسيطة جدًا: الاسم – المستخدم – رقم الهوية.

لا شيء مشجّع.


لكنّي معتاد على فحص كل شيء… فبدأت بعمل parameter fuzzing.


فحص البراميترات

وجدت مجموعة براميترات مثل:

page – length – sort – search – username … إلخ.


جميعها كانت طبيعية باستثناء براميتر واحد:

search


بدأت أختبره بقيم مختلفة:

  • username → يظهر الحساب
  • display name → يظهر الحساب


ثم جربت شيئًا لا ينبغي أن يُفحص أصلًا:

كتبت أوّل جزء من بريدي الإلكتروني: ahmedsdp


والنتيجة؟

عاد لي الردّ يحتوي على حسابي!


مع أن هذا الجزء من البريد لا يظهر إطلاقًا لأي مستخدم.


وهنا أدركت أن البحث لا يعتمد على البيانات الظاهرة…

بل يبحث داخل النموذج الكامل في الباكند.

idor


الربط بين البحث وتحديث الحساب

لاحظت أن صفحة update profile تُرجع نفس هيكلة JSON التي رأيتها في search endpoint.

  • نفس الحقول.
  • نفس الأسماء.
  • نفس النموذج.


وهذا يعني أن البحث يستخدم نموذج بيانات الحساب ذاته.


لكن توجد مشكلة:

لا يمكن تخمين بيانات حسّاسة مباشرة مثل البريد ورقم الهاتف، لا تعرف طولها ولا بدايتها ولا نطاقها… وأي إزعاج للـ WAF سيغضب عليك 😅.


هنا يبدأ التفكير الحقيقي كـ Bug Hunter.


اكتشاف دعم الـ Regex داخل البحث

أثناء تحليل ملفات الـ JS لاحظت أن البحث يستخدم Regex داخليًا.


فقلت لِمَ لا أجرب؟

  • ahmed → يظهر
  • ahm ed → لا يظهر
  • ahm_ed → يظهر!


وهنا تكمن الزبدة…


الرمز _ يُعامل كـ Wildcard لحرف واحد.

ماذا يعني هذا؟ يعني أنك تستطيع تخمين أي قيمة حرفًا حرفًا بطريقة شرطية (نعم/لا)،

تمامًا مثل Blind SQL Injection ولكن على API.


طريقة الاستغلال

الآلية كانت كالتالي:

  • تثبيت username للمستخدم عبر براميتر username
  • استخدام Regex في search:


إن ظهر الحساب → التخمين صحيح

وإن اختفى → التخمين خاطئ


وبهذا يصبح البحث Oracle يخبرك صح أو خطأ.

بدأت استخراج البريد:

تحديد مزود الخدمة:

@gmail.com

@outlook.com


تحديد عدد الأحرف:

_@gmail.com

__@gmail.com

___@gmail.com


تخمين كل حرف:

a___@gmail.com

b___@gmail.com

… حتى يكتمل البريد كاملًا.


ونفس الشيء للرقم والعنوان وغيرها.


الأتمتة

كتبت سكربت Python يقوم بالعملية تلقائيًا:

تُدخل اسم المستخدم → وفي دقيقة أو دقيقتين تحصل على كل بياناته:

  • البريد
  • رقم الهاتف
  • العنوان


أي معلومة أخرى غير ظاهرة أصلًا

وهنا لم تعد ثغرة IDOR عادية… بل أصبحت Blind IDOR شديدة الخطورة.


محاكاة لما يحدث في الباكند

(تختصر الفكرة هنا: البحث يستخدم Regex ويُعامل _ كـ wildcard، مما يسمح بتخمين قيم حسّاسة من النموذج الداخلي.)

idor


الخلاصة

بدأ الفحص بطريقة اعتيادية جدًا…

لكن بربط السلوك بين الـ endpoints وبتحليل الآلية الداخلية، اتضح أن ميزة البحث مرتبطة بنموذج بيانات الحساب، مما فتح بابًا لاستعلام غير مقصود سمح باستخراج معلومات حسّاسة عبر Blind IDOR.


تم الإبلاغ عن الثغرة وتم إصلاحها بالكامل ولله الحمد.


أهم درس هنا

أغلب الثغرات لا تأتي من خطوة واضحة، بل من ملاحظة صغيرة تربطها بأخرى… حتى تتكوّن لديك الصورة الكاملة.


التحدّي


صنعت لكم تحديًا بسيطًا لمحاكاة ثغرة Blind IDOR باستخدام Flask.

يعتمد على استغلال الـ Regex و الـ Wildcard للحصول على بيانات مخفية.


هدفك: استخراج الفلاق

Flag{......................................}


رابط التحدي:

http://172.237.155.131:5000/


ننتظر الـ First Blood 🩸👀


شكرًا لقراءتكم… ونلتقي في رايت أب جديد بإذن الله 🫡

تعليقات