
لوحة تحكم CTF مستضافة ذاتيًا لفعاليات التعلّم الأمني: تسجيل الفرق، ولوحة صدارة مباشرة، ووحدات patch-to-score، والاختبارات القصيرة، وjeopardy، وتحديات الذكاء الاصطناعي على صندوق Docker Compose واحد.
لوحة تحكم ذاتية الاستضافة لفعاليات التعلّم الأمني — جهاز واحد، ومنظمة GitHub مجانية واحدة.
شغّلها لجامعة، أو مدرسة ثانوية، أو فرع OWASP، أو لقاء مجتمعي.
اقرأ AGENTS.md قبل أن تكتب أي كود. فهو دليل التشغيل:
الأوامر الدقيقة التي يشغّلها CI، وأنماط الفشل التي واجهها هذا المستودع
سابقًا، وثوابت المراجعة في
docs/reviewing.md. وCLAUDE.md هو مجرد مؤشر إلى
الملف نفسه.
يكون التغيير جاهزًا عندما يصبح CI أخضر و تُحلّ كل خيوط CodeRabbit القابلة للتنفيذ على أحدث commit (أو تُرفض بشكل موثّق). تتبع الـ commits نمط Conventional Commits ولا تحمل أي إسناد للذكاء الاصطناعي.
يُوسم العمل الصغير والمحدد جيدًا بـ
good first issue.
تبدأ الوحدات الجديدة كـ issue، لا كـ PR — راجع
CONTRIBUTING.md.
لوحة تحكم، لا لعبة واحدة. يمنح الجهاز الفعالية عمودها الفقري المشترك — منظمة GitHub، وتسجيل الفرق، ولوحة صدارة حية، ولوحة إدارة للمنظّمين، وخط تقييم يغذّيها. وتُوصِل الوحدات محتوى التحديات إلى ذلك العمود الفقري، ويمكن لأي مجموعة فرعية أن تعمل وحدها أو معًا: التصحيح-للتقييم Secure Development، وبنك Quiz، ولوحة Jeopardy، وتحديات AI المستضافة خارجيًا. وعقد الوحدة هو الحد الفاصل بين العمود الفقري والمحتوى، لذا صُمّم الجهاز لاستضافة مزيد من الوحدات — التحليل الجنائي، وأمن الـ API، والسحابة — مع ظهورها تباعًا.
لماذا وُجد. تعلّم وحدة Secure Development الدفاع بدلًا من الهجوم، وهي طريقة جيدة حقًا لتعليم البرمجة الآمنة. حتى الآن، كان تشغيل واحدة منها يعني إعداد Vercel وUpstash وLambda وDynamoDB، وتحمل فاتورة السحابة، والحصول على صورة تقييم خاصة. هذا طلب معقول لمؤتمر له ميزانية. لكنه طلب غير معقول لمقرر أمني جامعي، أو نادٍ في مدرسة ثانوية، أو أمسية فرع OWASP، أو ورشة نهاية أسبوع.
تُزيل هذه المجموعة ذلك كله. كل شيء يعمل عبر Docker Compose على جهاز واحد تملكه بالفعل — حاسوب محمول، أو حاسوب مكتبي احتياطي، أو VPS صغير — بالإضافة إلى منظمة GitHub مجانية واحدة للـ forks. وتُشحن معايير التقييم للأهداف الستة جميعها داخل الجهاز، فلا توجد صورة خاصة تُطلب ولا كود تقييم يُكتب. لا تُفرض أي فواتير، ولا يتصل أي شيء بخوادم خارجية، وعند انتهاء الفعالية تُؤرشف المستودعات وتوقف الـ stack.
لمن هذا: لكل من يريد تشغيل هذه الفعالية ولا يريد أن يصبح مشغّل سحابة من أجل ذلك — مدربو المقررات، ومنظّمو الأندية، وقادة فروع OWASP، وميسّرو الورش، والفرق الأمنية التي تنظّم يوم تدريب داخلي.
منشور ومُجرَّب من البداية إلى النهاية؛ لكنه لم يُشغَّل بعد لمجموعة حقيقية.
مسار التقييم الكامل يُشحن داخل المجموعة — POST /score الخاص بالمقيّم
المحمي بـ bearer، وسير عمل التقييم المكتفي بذاته للـ forks، ونقل الـ poll —
وscripts/smoke.sh يشغّل خط الأنابيب بأكمله مقابل محاكيات. وإلى جانب ذلك،
تعمل المجموعة باستمرار على جهاز مستضاف من ملف Compose نفسه الذي يشحنه هذا
المستودع، ويُبلّغ GET /health عن المراجعة الدقيقة التي تخدمه، وقد كُشفت
وأُصلحت دفعة من العيوب الحقيقية خلال مرور شامل من البداية إلى النهاية على
ذلك المثيل الحي — من النوع الذي لا تستطيع مجموعة اختبارات محاكاة رؤيته.
ما لم يحدث هو فعالية حقيقية: مجموعة متسابقين يفتحون PRs حقيقية مقابل forks حقيقية، في وقت واحد، لساعات. تلك هي الفجوة بين "خط الأنابيب يعمل" و"خط الأنابيب يعمل مع 40 شخصًا". وهناك تحفّظان معلنان لا مدفونان: لمطابق نتائج Security Shepherd حدّ متبقٍ معلن (فقد تُقرأ صيغة رفض غير معتادة على أنها حل — يمكن أن تمنح نقاطًا أقل لتصحيح صحيح، لكنها لا تمنح نقطة مجانية أبدًا)، كما أن ملف الحمل لمجموعة كاملة غير مُختبَر. التفاصيل والحالة الراهنة: الحالة والاعتماديات الخارجية.
ما يفعله هذا ولا تفعله تلك: تدريب دفاعي بنمط التصحيح-للتقييم يُقيَّم عبر طلبات السحب على GitHub، وعقد وحدات لخلط أنواع الألعاب على لوحة صدارة واحدة، ولوحة تحكم تملكها من البداية إلى النهاية — جهاز واحد، ومنظمة مجانية واحدة، بلا فاتورة سحابة، بلا قياس عن بُعد.
هذا المشروع غير تابع لمؤسسة OWASP ولا معتمد منها. أربعة من الأهداف الستة القابلة للاستغلال هي مشاريع OWASP (Juice Shop، WebGoat، Security Shepherd، VulnerableApp)؛ أما DVWA وVAmPI فهما مشروعان مجتمعيان.
شاهده يعمل في دقيقتين — بلا منظمة GitHub، بلا تطبيق OAuth، ولا شيء
يُضبط. تحتاج إلى Docker مع Compose v2 و**openssl**:```sh
git clone https://github.com/dcotelo/owasp-ctf
cd owasp-ctf
./scripts/dev-stack up
يكتب أسرارًا محلية مؤقتة، ويبني صورة المُسجِّل وصورة التطبيق، ويُشغِّل
الحزمة، ويزرع لوحة صدارة تجريبية عبر واجهة برمجة التطبيقات الحقيقية للتسجيل،
ويطبع عنوان URL للفتح. يجب أن ترى لوحة الصدارة مع الفرق المزروعة
ورسمًا بيانيًا للنقاط عبر الزمن؛ `./scripts/dev-stack score <login> juice-shop 3`
يضيف ثلاثة حلول مباشرة. `./scripts/dev-stack down` يزيلها.
**شغِّل حدثًا حقيقيًا** باستخدام المعالج الموجَّه. أضف **[`gh`
CLI](https://cli.github.com)** (مُصادَق عليه)، بالإضافة إلى **منظمة GitHub مجانية واحدة**
إذا كان الحدث يشغِّل Secure Development؛ `./setup/ctf-setup.sh check` يتحقق
من الأدوات أولاً:```sh
./setup/ctf-setup.sh # guided, prompts for values, resumable
يطلب كل قيمة أثناء تقدمه — رابط صندوقك، منظمة الحدث، تسجيلات دخول المسؤول، ما إذا كنت تشغّل Secure Development، بيانات اعتماد GitHub — يكتب .env، ينفّذ كل خطوة قابلة للأتمتة، يرشدك خلال الخطوات التي تتطلب واجهة GitHub، ويستأنف إذا توقفت وعدت لاحقًا. كل ما عدا ذلك (اسم الحدث، أي الوحدات تعمل، أي الأهداف) هو إعداد /admin وقت التشغيل، لذا لا يوجد ملف تهيئة لتحريره. يسأل فقط عمّا تحتاجه فعلاً: حدث بدون Secure Development لا يحتاج منظمة، ولا forks، ولا صورة scorer، ولا يُسأل عنها أبدًا. عاين أي خطوة معدِّلة باستخدام --dry-run — يروي الخطوات 4–9 من .env مكتمل بالفعل، ويرفض (بحكم التصميم) عندما لا يوجد تسجيل دخول مسؤول، أو عندما يكون Secure Development مفعّلاً بدون منظمة. يُغلق المعالج بتشغيل ./setup/ctf-setup.sh doctor — مصفوفة حالة لكل fork يمكنك إعادة تشغيلها في أي وقت — ثم يعرض نشر fly.io اختياريًا (الافتراضي لا)، لذا فإن وضع الحدث نفسه على اسم مضيف عام هو تدفق موجَّه — اسم المضيف، نشر معاين، ثم تأكيد — بدلاً من رحلة عبر وثائق النشر.
تريد التفاصيل؟ كل أمر فرعي منفصل، وكل خطوة تتطلب الواجهة فقط، وكيف يختلف تطبيقا GitHub:
docs/hosting.md.
في السحابة بدلاً من ذلك؟ docs/aws.md (Terraform: ECS Fargate، ElastiCache و ALB — apply للأعلى / destroy للأسفل) أو
docs/fly.md (جهاز Fly واحد).
Secure Development — اعمل fork لتطبيق معرّض للثغرات عن قصد، اعثر على الخلل، أصلحه، وافتح PR. يشغّل GitHub Action في الـ fork معيار التقييم الخاص بالهدف مقابل التصحيح وتهبط النتيجة على لوحة الصدارة (بعد ~30 ثانية في وضع الاستطلاع). ستة أهداف، 321 تحديًا؛ الحالة الأصلية تسجّل 0، والتصحيح الصحيح يكسب نقاطه — محكوم في كلا الاتجاهين. يحتاج منظمة GitHub وخط أنابيب التقييم.
Quiz — أسئلة أمنية أحادية ومتعددة الاختيار، تُقيَّم في التطبيق لحظة الإجابة عليها (كل شيء أو لا شيء في متعدد الاختيار)، مع حد أقصى للمحاولات وفترة تهدئة لإعادة المحاولة. تُنشأ من /admin واحدة تلو الأخرى أو تُستورد وتُصدَّر كحزمة JSON واحدة. لا يحتاج GitHub، ولا forks، ولا خط أنابيب.
Jeopardy — لوحة من الأعلام التي ينشئها المنظمون في فئات. تُشذَّب الإجابات وتُوحَّد، ويُتسامح مع حالة الأحرف إلا إذا كان العلم مُعلَّمًا كحساس لحالة الأحرف (بطاقته تقول ذلك)، مع فترة تهدئة للإرسال وتلميحات مدفوعة اختيارية. نفس إنشاء /admin + حزمة JSON كالاختبار. لا يحتاج GitHub أيضًا.
AI — تحديات حقن الأوامر والحواجز الأمنية المستضافة خارج الصندوق. تنشئ صفحة تحديات كل متسابق رابط إطلاق شخصي إلى الموقع الخارجي؛ ويُبلَّغ عن الحل إلى لوحة الصدارة، إما عبر callback الموقع نفسه أو عبر علم يُكتب في التطبيق. لا يحتاج GitHub، ولا forks، ولا خط أنابيب.
حول أي وحدات تفعّلها، توفّر المنصة: التسجيل الذاتي للفرق مع القادة، ورموز الانضمام وروابط /join/<code> (اللعب الفردي فريق من واحد؛ العلم الذي يحله عدة أعضاء يُحتسب مرة واحدة)؛ لوحة الصدارة الحية مع رسم بياني للنقاط عبر الزمن بأسلوب CTFd من الطوابع الزمنية الحقيقية لكل حل؛ لوحة /admin المقيّدة بقائمة سماح — التجميد، ونوافذ التقييم والتسجيل، والتلميحات وتكاليفها، والحد الأقصى للفرق، وفترات التهدئة، ومحتوى الوحدات، وإجراءات الدعم لكل متسابق، وتدفق النشاط ومقاييس التفاعل — كلها وقت التشغيل، بلا إعادة بناء؛ وسجل تدقيق محدود السعة على كل إجراء إداري.
| تفصيل المتسابق | متصفح التحديات |
|---|---|
![]() | ![]() |
| لوحة أعلام Jeopardy | Quiz |
|---|---|
![]() | ![]() |
Captured from the contestant app running locally via scripts/dev-stack up
with seeded demo players. Targets and fork links are event-config driven; the
event name and the rest of its branding are admin-panel settings.
حزمة Docker Compose واحدة: يُنهي Caddy بروتوكول TLS أمام تطبيق Next.js؛
يتحدث التطبيق إلى Redis فقط عبر srh (وكيل REST متوافق مع Upstash) —
الشبكة مقسّمة بحيث لا يملك أي شيء مواجه للإنترنت مسارًا إلى redis:6379.
يقيّم Quiz وJeopardy وAI داخل التطبيق ويدفع النقاط مباشرة إلى Redis.
يُقيَّم Secure Development خارج الصندوق: يشغّل fork المتسابق
GitHub Action يُقلع الهدف، ويشغّل معيار التقييم مقابل التصحيح، وينشر
تعليق نتيجة قابلًا للقراءة آليًا على الـ PR. يسحب مُستطلِع sync
تلك التعليقات — صفر سطح شبكة وارد، لذا يعمل الصندوق خلف NAT وعلى
واي فاي المكان (هذا هو النقل الوحيد: أُزيل الدفع الوارد في v0.6،
انظر #377). تدخل النتيجة عبر كاتب واحد مُدقَّق:
POST /score الخاص بالمقيّم والمصادَق بحامل الرمز، الذي يتحقق ويكتب
بشكل رتيب — لا تُلغى الحلول أبدًا بتشغيل فاشل لاحق.
الصورة الكاملة — المكوّنات، وتدفق بيانات النتيجة ذو الخطوات التسع، ونموذج الأمان — في docs/architecture.md.
محتوى هذه الوحدة عبارة عن مجموعة من الأهداف المعرّضة للثغرات ومعايير
التقييم الخاصة بها. يختار المتسابقون هدفًا، ويعملون fork لنسخة المنظمة، ويصححونها، ويفتحون PR. تحديات كل هدف هي أجنحة node:test قابلة للتنفيذ، مسعّرة
حسب الصعوبة.
Counts are maintained by hand and pinned to the vendored rubric by
apps/web/src/lib/tests/apps-catalogue.test.ts — re-check them
after a vendor-rubric.sh bump. Reference patches
that prove a correct fix scores (the positive-direction gate) live separately
under patches/.
توجد معايير التقييم في scorer/rubric.owasp/، منسوخة من
OWASP-CTF/dc34-owasp-secure-development-ctf
ومثبّتة على الالتزام الواحد في المنبع المسجّل في
scorer/rubric.owasp/PROVENANCE.md. أعد النسخ مقابل التزام أحدث باستخدام:```sh
./scripts/vendor-rubric.sh --all --ref
يُدعم شكلان من معايير التقييم في آنٍ واحد، ويمكن لدليل معايير واحد أن يخلط بينهما: ملفات `<target>.yaml` تستخدم قواعد فحص طلبات/توقعات HTTP التصريحية، بينما تستخدم أدلة `<target>/tests/challenges/` اختبارات قابلة للتنفيذ مُسعَّرة عبر `catalogue.<target>.json`. دليل التأليف:
[docs/scorer.md](https://github.com/owasp/owasp-ctf/blob/main/docs/scorer.md).
**حول سرية معايير التقييم.** هذه المعايير علنية. الأهداف مفتوحة المصدر وحلولها منشورة بالفعل، لذا تعامل المجموعة خصوصية المعايير كحماية ضد التلاعب بالفحوصات بدلاً من الحماية ضد معرفة الإجابات — وهي مقايضة مقبولة لحدث مُستضاف ذاتيًا. يمكنك التجاوز بمعيارك الخاص غير العلني في أي وقت:```sh
cp -r /path/to/private-rubric scorer/rubric
docker build -t ghcr.io/<org>/score:latest --build-arg RUBRIC_DIR=rubric scorer/
scorer/rubric/ مُستبعَد من git ومخصّص لهذا الغرض تحديدًا.
بمجرد أن تصبح المنظومة جاهزة على EVENT_URL الخاص بك:
/admin: تجميد لوحة المتصدرين، وفتح التسجيل وإغلاقه،
وضبط الجدول الزمني، وتأليف أسئلة الاختبارات والتحديات الكلاسيكية
وتحديات ai — وعندما يتعثّر أحد المتسابقين، أصلح ذلك المتسابق
بعينه بدلًا من إعادة ضبط الفعالية.docker compose logs -f sync (يعمل مع
تمكين secure-development). كل الحالة تعيش في أحجام Docker المُسمّاة، لذا
إعادة تشغيل الجهاز لا تفقد شيئًا../setup/ctf-setup.sh teardown بأرشفة المستودعات
المستهدفة — ثم ألغِ تثبيت GitHub App واحذف أسرار Actions الخاصة بالمنظمة
بنفسك. الفعالية بدون secure-development ليس لديها forks لأرشفتها.الفرق، ولوحة الإدارة، والتحقق من العدة قبل اليوم، وبيئة التطوير المحلية كلها مشروحة في docs/operations.md؛ والمتطلبات المسبقة، ونقل النقاط، وإعداد OAuth، وتهيئة الفعالية في docs/hosting.md.
التبرير الكامل، والبدائل، والمقايضات مسجّلة كـ ADRs مرقّمة في docs/decisions.md.
معروض على dcotelo.github.io/owasp-ctf.
المساهمات مرحّب بها — CONTRIBUTING.md يغطي بيئة التطوير، وبوابات CI، وكيفية اقتراح وحدة؛ وCODE_OF_CONDUCT.md ساري.
ينبغي للوكلاء اتباع AGENTS.md. الأوامر أدناه تطابق CI؛
وmake help يسرد نفس الأهداف.
كل خدمة تُختبر بشكل مستقل (Node 22 في كل مكان):```sh (cd sync && npm ci && npm test) (cd scorer && npm ci && npm test && node tools/vacuous-sweep.mjs) ./scripts/acceptance-scorer.sh # from the repo root — the script lives in scripts/ (cd apps/web && corepack pnpm install --frozen-lockfile && corepack pnpm lint && corepack pnpm test) ./scripts/smoke.sh # the full poll pipeline, end to end
هل وجدت ثغرة أمنية في المجموعة نفسها؟ **[SECURITY.md](https://github.com/owasp/owasp-ctf/blob/main/SECURITY.md)** — ثغرات الأهداف مقصودة وخارج النطاق.
## الترخيص والحقوق
MIT — انظر [LICENSE](https://github.com/owasp/owasp-ctf/blob/main/LICENSE). محتوى معايير التقييم تحت `scorer/rubric.owasp/`
مُضمَّن من حدث
[OWASP-CTF](https://github.com/OWASP-CTF/dc34-owasp-secure-development-ctf)
الأصلي، مثبَّت على الالتزام المذكور في `scorer/rubric.owasp/PROVENANCE.md` — هذه المجموعة
موجودة لأن ذلك الحدث كان يستحق التكرار أكثر من مرة. الأهداف القابلة للاستغلال غير مُضمَّنة:
بل تُفرِّعها الأحداث من مصادرها الأصلية
([Juice Shop](https://github.com/juice-shop/juice-shop)،
[WebGoat](https://github.com/WebGoat/WebGoat)،
[DVWA](https://github.com/digininja/DVWA)،
[Security Shepherd](https://github.com/OWASP/SecurityShepherd)،
[VulnerableApp](https://github.com/SasanLabs/VulnerableApp)،
[VAmPI](https://github.com/erev0s/VAmPI))، ولكل منها ترخيصها الخاص.
OWASP® علامة تجارية مسجَّلة لمؤسسة OWASP؛ هذا المشروع غير
تابع لها ولا معتمد منها.
| الهدف | التحديات | النقاط | ملاحظات |
|---|
vulnerableapp | 110 | 187 | أكبر هدف؛ يُقيَّم بتوازٍ من 8 مسارات |
webgoat | 69 | 137 | بناء على مرحلتين: Maven، ثم Dockerfile الخاص بالـ fork للتشغيل فقط |
dvwa | 55 | 108 | يحتاج شقيق MariaDB وتهيئة schema |
securityshepherd | 40 | 79 | HTTPS، حزمة من ثلاث حاويات، تسلسلي صرف |
juice-shop | 38 | 141 | الهدف الوحيد الذي تمتد صعوبته إلى 6 نجوم |
vampi | 9 | 16 | مكتفٍ ذاتيًا؛ أسرع إثبات من البداية للنهاية |
| الإجمالي | 321 | 668 | كل حدث يوفّر الستة جميعًا؛ اختر مجموعة فرعية في /admin → Secure Development → Targets |
| اقرأ هذا عندما تكون… | المستند |
|---|
| تُجهّز العدة | docs/hosting.md — المتطلبات المسبقة، والمعالج وكل خطوة منفصلة، وكيف تصل النقاط إلى الجهاز، وتطبيق GitHub OAuth، وتهيئة الفعالية |
| تنشر إلى سحابة | docs/aws.md (Terraform: ECS Fargate + ElastiCache + ALB) · docs/fly.md (جهاز Fly واحد) |
| على وشك فتح الأبواب | docs/security-checklist.md — جولة ما قبل الفعالية من صفحة واحدة |
| تُدير الفعالية | docs/operations.md — الفرق، ولوحة الإدارة، وأدلة منظّم الاختبارات/الكلاسيكي/ai، والتحقق، والتفكيك |
| تفهم النظام | docs/architecture.md — المخطط، وتدفّق بيانات النقاط، ومفاتيح Redis، ونموذج الأمان، واستراتيجية الاختبار |
| تكتب rubric | docs/scorer.md — وضعا serve + judge، وقواعد الـ rubric كليهما، والتأليف والبناء |
| تبني وحدة جديدة | docs/modules.md — عقد المنصة/الوحدة |
| تسأل "لماذا هو هكذا؟" | docs/decisions.md — ADRs مرقّمة |