Race Condition وAccount Takeover في Bug Bounty

x32x01
  • بواسطة x32x01 ||
مش عارف هخرج من الـ Zone دي إمتى، ولا هخلص من الـ Duplicates والنصب إمتى، بس الحمد لله على كل حال. 😅
التجربة دي كانت مع برنامج Bug Bounty كنت شايف إنه برنامج كويس جدًا، وبلغت فيه عن أكتر من ثغرة. للأسف، تقرير اتقفل باعتباره Duplicate، وتقرير تاني اتصنف Business Logic وخرج من الـ Scope، رغم إني كنت شايف إن فيه مشكلة أمنية تستحق المراجعة.

حبيت أشارك التجربة معاكم؛ لأن فيها تفاصيل ممكن تساعد أي حد بيشتغل في Bug Bounty، خصوصًا في اختبار الـ Authentication والـ Business Logic.



🔐 الثغرة الأولى: Race Condition في Reset Password Flow تؤدي إلى Account Takeover​

أثناء اختباري لخاصية استعادة كلمة المرور، لاحظت إن الـ Request المسؤول عن العملية بيحتوي على 3 Parameters أساسية:
JSON:
{
    "email": "email@domain.com",
    "request_id": "UUID",
    "method": "CODE"
}
قلت أجرب أبعت Requests لبريدين إلكترونيين مختلفين في نفس الوقت، وأشوف التطبيق هيتعامل معاهم إزاي.

🔍 أول محاولة: استخدام request_id مختلف​

اعترضت الـ Request باستخدام Burp Suite، وبعدها جربت أبعت طلبين ببريدين مختلفين، وكل طلب كان فيه request_id مختلف.
النتيجة إن التطبيق بعت OTP لكل بريد، لكن كل بريد استقبل كود مختلف.
في اللحظة دي، افتكرت إن السيناريو مش هيؤدي لحاجة، فسيبته وكملت اختبارات تانية.
لكن وأنا بجرب أبعت الـ Request مرة تانية بنفس البيانات، لاحظت حاجة غريبة: التطبيق بعت نفس الـ OTP مرة تانية!
استغربت وقلت: هو ليه بيستخدم نفس الكود؟

🧩 مقارنة الـ Requests كشفت تفصيلة مهمة​

رجعت أجرب من الـ UI، وطلبت إرسال كود التحقق مرتين. المرة دي لاحظت إن الكودين مختلفين.
فتحت Burp History وقارنت الـ Requests، ولقيت إن قيمة request_id كانت مختلفة بين الطلبين.
هنا بدأت أشك إن فيه ارتباط بين قيمة الـ request_id ورمز التحقق OTP.

🚨 إعادة اختبار السيناريو​

قررت أعيد الاختبار مع استخدام نفس قيمة request_id في الطلبات بدل ما تكون مختلفة.
لاحظت إن التطبيق أرسل نفس رمز التحقق إلى البريدين المختلفين.
بعد كده، قدرت أكمل سيناريو إعادة تعيين كلمة المرور وأثبت إمكانية الوصول إلى Account Takeover.
وده كان الجزء المهم في الثغرة: المشكلة مش مجرد إن نفس الـ OTP اتبعت مرتين، لكن إن سلوك التطبيق سمح باستخدامه في سياق مختلف عن السياق المتوقع، ووصل التأثير إلى إمكانية الاستيلاء على الحساب.
طبعًا، لازم نفرّق بين إعادة إرسال OTP بشكل طبيعي وبين وجود خلل أمني حقيقي. إعادة استخدام الكود وحدها مش دليل كافي، لكن ربط الكود بالحساب والطلب الصحيحين، ومنع استخدامه خارج السياق المخصص له، هما الأساس في تأمين العملية.
النتيجة؟ قدمت التقرير، لكن للأسف اتقفل باعتباره Duplicate. 🙂
يعني الثغرة كانت متبلغ عنها قبل كده، وده مش معناه بالضرورة إن اكتشافي لها كان غلط، لكنه معناه إن البرنامج مش هيحتسبها كتقرير جديد قابل للمكافأة.



🗳️ الثغرة الثانية: التلاعب بالـ Upvote وDownvote بسبب ضعف التحقق من Session​

الثغرة التانية كانت في تطبيق E-commerce، وكان فيه نظام للتعليقات يسمح للمستخدمين يعملوا:
  • Upvote: لو التعليق مفيد.
  • Downvote: لو التعليق مش مفيد.
التصويتات دي كانت بتأثر على ترتيب التعليقات وظهورها للمستخدمين.
وأثناء الاختبار، اكتشفت أكتر من سيناريو خلاني أشك إن التطبيق مش بيتعامل مع التصويتات والتحقق من الـ Session بالشكل الصحيح.

1. Race Condition تسمح بتكرار التصويت​

أول حاجة جربتها كانت إرسال أكتر من Request للتصويت في نفس الوقت.
لاحظت إن التزامن سمح لي بتكرار عمليات Upvote أو Downvote، رغم إن المفروض التطبيق يمنع المستخدم من تكرار التصويت بالطريقة دي.
النوع ده من المشاكل ممكن يحصل لما التطبيق ينفذ عملية التحقق من التصويت السابق، وبعدها يسجل التصويت الجديد، من غير ما يضمن إن الخطوتين بيتموا بشكل آمن ضد الطلبات المتزامنة.
بمعنى أبسط، ممكن طلبين يوصلوا للسيرفر في وقت قريب جدًا، وكل واحد منهم يمر من التحقق قبل ما التاني يسجل التصويت.
لكن علشان نأكد إن المشكلة Race Condition فعلًا، لازم نثبت إن التزامن هو العامل المؤثر، مش مجرد تكرار الطلبات بشكل عادي.

2. حذف الـ Session وتجربة التصويت مرة تانية​

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

3. تعديل بيانات الـ Session وتجاوز التصويت السابق​

دي كانت من أغرب الحاجات اللي لاحظتها.
جربت أعدّل بيانات الـ Session نفسها، ولاحظت إن التطبيق بيتعامل مع بعض التعديلات بشكل يسمح لي بإعادة التصويت.
السيناريو كان كالتالي:
  1. أنفذ عملية Vote.
  2. أحاول أصوّت مرة تانية، فيظهر لي الرد You already voted.
  3. أعدّل بيانات الـ Session.
  4. أعيد إرسال طلب التصويت.
  5. ألاحظ إن التطبيق بيسمح بالعملية مرة تانية.
يعني التطبيق كان بيمنع التصويت المتكرر في حالة معينة، لكن تعديل بيانات الجلسة كان بيغيّر النتيجة.
وده خلاني أشك إن التطبيق بيعتمد على بيانات قابلة للتغيير في تحديد حالة التصويت، أو إن فيه مشكلة في طريقة ربط التصويت بالمستخدم.
المشكلة هنا مش مجرد إن المستخدم قدر يعدّل Session، لكن إن التعديل أثّر على قرار أمني المفروض السيرفر يتحكم فيه.
ومع ذلك، علشان نحدد السبب الجذري بدقة، لازم نعرف هل التطبيق بيعتمد على Cookie موقعة، أو Session ID، أو آلية منفصلة لتسجيل التصويتات. قبول الطلب بعد التعديل مش دليل قاطع وحده على إن التوقيع الرقمي اتكسر.

🤦‍♂️ رد البرنامج: RTFS وBusiness Logic​

قدمت التقرير، لكن الرد كان RTFS، واللي غالبًا معناها Read The Fine Scope؛ أي إن الباحث محتاج يراجع نطاق البرنامج وشروطه.
التقرير اتصنف باعتباره Business Logic Bug، واتقفل باعتبار المشكلة خارج نطاق البرنامج.
وده كان محبط بالنسبة لي؛ لأن السيناريو كان واضح بالنسبة لي، وكنت شايف إن فيه ضعف في التحقق من الـ Session والسماح بتكرار التصويت.
لكن لازم نفرّق بين حاجتين:
  • إن المشكلة تكون موجودة تقنيًا فعلًا.
  • إن المشكلة تكون مؤهلة للمكافأة حسب سياسة برنامج Bug Bounty.
ممكن تكون المشكلة الأمنية صحيحة، لكن البرنامج يستبعد النوع ده من الثغرات، أو يشترط إثبات تأثير أكبر علشان يقبلها.



⚖️ هل التلاعب بالتصويت Business Logic ولا Improper Access Control؟​

التصنيف بيعتمد على السبب الجذري وطريقة الاستغلال.
نوع الثغرةمعناها
Race Conditionخلل بسبب تنفيذ عمليات متزامنة بطريقة غير آمنة
Business Logicاستغلال خلل في قواعد العمل أو طريقة تنفيذ الوظيفة
Improper Access Controlالسماح بتنفيذ عملية من غير التحقق الصحيح من الصلاحيات
Session Managementخلل في إدارة الجلسات أو التحقق من سلامتها
ممكن المشكلة الواحدة تتداخل فيها أكتر من فئة.
مثلًا، لو التطبيق بيسمح بتكرار التصويت بسبب خلل في منطق تسجيله، فده ممكن يكون Business Logic Bug.
أما لو التطبيق بيعتمد على بيانات جلسة قابلة للتلاعب علشان يحدد هل المستخدم مسموح له يصوّت، فممكن يكون فيه خلل إضافي في Session Management أو Access Control، حسب طريقة التنفيذ.
علشان كده، وصف الثغرة باسم معين مش كفاية. الأهم هو شرح السبب الجذري، وإثبات التأثير الأمني، ومراجعة شروط البرنامج.



🛠️ إيه اللي ممكن نتعلمه من التجربة دي؟​

فيه شوية نقاط مهمة خرجت بيها من الاختبارات دي:
  • راجع الـ Parameters كويس: أحيانًا اختلاف قيمة واحدة زي request_id يكشف سلوك غير متوقع في التطبيق.
  • قارن بين الـ UI والـ HTTP Requests: واجهة المستخدم مش دايمًا بتوضح كل التفاصيل اللي تقدر تلاحظها من خلال Burp Suite.
  • اختبر التزامن والتتابع: علشان تفرق بين Race Condition وبين خلل منطقي بيحصل حتى من غير تزامن.
  • ما تعتمدش على Client-side Validation: أي تحقق أمني مهم لازم يكون على السيرفر.
  • اختبر ربط OTP بالحساب الصحيح: رمز التحقق لازم يكون مرتبطًا بعملية استعادة محددة، وما ينفعش استخدامه لحساب مختلف.
  • افهم طريقة إدارة الـ Session: لازم تعرف إيه البيانات اللي بيستخدمها السيرفر لتحديد هوية المستخدم وحالة التصويت.
  • اقرأ Scope البرنامج قبل الاختبار: لأن مش كل مشكلة أمنية قابلة للمكافأة.
  • وثّق التأثير الفعلي: التقرير القوي بيشرح إيه اللي يقدر المهاجم يعمله، مش بس اسم الثغرة.



📝 إزاي تخلي تقرير Bug Bounty أقوى؟​

لو اكتشفت مشكلة مشابهة، حاول توضح النقاط دي في التقرير:
  1. Summary: وصف مختصر للمشكلة الأمنية.
  2. Steps to Reproduce: خطوات واضحة لإعادة إنتاج المشكلة باستخدام حسابات اختبار مصرح بها.
  3. Expected Result: السلوك الصحيح المتوقع من التطبيق.
  4. Actual Result: السلوك اللي حصل بالفعل، مع الأدلة المناسبة.
  5. Security Impact: التأثير الأمني الحقيقي، زي إمكانية الاستيلاء على حساب أو التلاعب بنتائج التصويت.
  6. Root Cause: تفسير سبب المشكلة، لو قدرت تحدده.
  7. Scope: التأكد من إن نوع الثغرة وتأثيرها داخل نطاق البرنامج.
ولو التقرير اتقفل باعتباره Duplicate، راجع ملاحظات البرنامج واعرف هل فيه فرصة لتوضيح اختلاف جوهري في التأثير. أما لو اتقفل باعتباره Out of Scope، فراجع السياسة قبل ما تضيع وقت إضافي في نفس النوع من الاختبارات.



💭 الخلاصة​

مش عارف هخلص من الـ Duplicates والـ Out of Scope إمتى، بس الحمد لله على كل حال. 😅
التجربة بدأت بملاحظة صغيرة في request_id أثناء اختبار استعادة كلمة المرور، ووصلت لسيناريو Account Takeover. وبعدها اكتشفت سلوكًا غريبًا في نظام التصويت، مرتبطًا بالتزامن والتعامل مع بيانات الـ Session.
في النهاية، تقرير اتقفل Duplicate، والتاني اتقفل باعتباره Business Logic خارج النطاق.
لكن أهم حاجة اتعلمتها إن اختبار الاختراق مش مجرد اكتشاف سلوك غريب؛ لازم تفهم السبب الجذري، وتثبت التأثير، وتعرف إزاي تشرح المشكلة بشكل واضح لفريق الـ Triage.
وأحيانًا، أبسط تفصيلة في الـ Request هي اللي بتفتح لك باب اكتشاف الثغرة. 🔥
001.webp

002.webp



الأسئلة الشائعة​

---------------

هل تكرار رمز OTP يعتبر ثغرة؟​

مش بالضرورة. لازم تثبت إن إعادة استخدام الرمز بتسمح بتجاوز التحقق أو الوصول لحساب غير مصرح به.

هل Race Condition ممكن تؤدي إلى Account Takeover؟​

أيوه، لو التزامن بيؤدي إلى خلل في عملية حساسة زي استعادة كلمة المرور، وكان بالإمكان استغلال الخلل لتجاوز التحقق من ملكية الحساب.

هل تعديل Session يعتبر Improper Access Control؟​

مش في كل الحالات. لازم يكون التعديل بيؤدي فعلًا إلى تجاوز قيد أمني أو تنفيذ عملية غير مصرح بها.

هل الثغرة اللي اتقفلت Out of Scope معناها إنها مش حقيقية؟​

لا. ده معناه إن البرنامج مش بيقبلها وفقًا لسياسة النطاق، ومش حكم نهائي على وجود المشكلة التقنية من عدمه.
 
التعديل الأخير:
مواضيع مشابهة
x32x01
الردود
0
المشاهدات
59
x32x01
x32x01
x32x01
الردود
0
المشاهدات
98
x32x01
x32x01
الدخول أو التسجيل السريع
نسيت كلمة مرورك؟
إحصائيات المنتدى
المواضيع
2,346
المشاركات
2,414
الأعضاء
17
آخر عضو مسجل
fact
عودة
أعلى