פגמים בלוגיקה עסקית - תרגול¶
תרגיל 1 - אמון מוגזם בבקרות צד-לקוח (Apprentice)¶
מעבדה: Excessive trust in client-side controls (PortSwigger)
רקע:
חנות מקוונת שמחיר המוצר נשלח מהלקוח. המטרה: לרכוש מוצר "Lightweight l33t leather jacket" שמחירו 1337 דולר בעוד שהיתרה שלכם 100 דולר בלבד.
שלבים:
- התחברו עם הפרטים
wiener:peter - הוסיפו את המוצר לעגלה ולכדו את הבקשה ב-Burp
- בדקו את הפרמטרים בבקשה - האם המחיר נשלח מהלקוח?
- שנו את המחיר בבקשה לערך נמוך
- השלימו את הרכישה
שאלה: איזה פרמטר שיניתם ולאיזה ערך?
תרגיל 2 - כשלון בטיפול בקלט לא שגרתי (Practitioner)¶
מעבדה: High-level logic vulnerability (PortSwigger)
רקע:
חנות מקוונת שאין לה ולידציה מספקת על כמויות. המטרה: רכישת מוצר עם כמות שלילית.
שלבים:
- התחברו והוסיפו מוצר לעגלה
- לכדו את הבקשה ובדקו את פרמטר הכמות
- נסו לשלוח כמות שלילית
- בדקו מה קורה לסך הכולל של העגלה
- הוסיפו מוצרים בכמות שלילית כדי להפחית את סך העגלה
- השלימו את הרכישה כאשר הסכום הכולל חיובי אבל נמוך מהיתרה
תרגיל 3 - עקיפת ולידציית כמות (Practitioner)¶
מעבדה: Low-level logic flaw (PortSwigger)
רקע:
החנות בודקת שהכמות חיובית, אבל לא מגבילה את הערך המקסימלי. המטרה: ניצול גלישת מספר שלם (integer overflow).
שלבים:
- הוסיפו את המוצר היקר לעגלה בכמות 99 (המקסימום המותר)
- חזרו על הפעולה עד שהסכום הכולל גולש ונהפך לשלילי
- הוסיפו מוצרים זולים כדי להביא את הסכום לערך חיובי נמוך
- השלימו את הרכישה
רמז: השתמשו ב-Burp Intruder כדי לשלוח בקשות רבות של הוספת כמות 99. עקבו אחרי הסכום בעגלה.
תרגיל 4 - עקיפת תהליך רכישה (Practitioner)¶
מעבדה: Inconsistent handling of exceptional input (PortSwigger)
רקע:
תהליך רכישה מרובה שלבים שבו אפשר לדלג על שלבים. המטרה: להשלים רכישה ללא תשלום.
שלבים:
- בצעו רכישה תקינה ומפו את כל הבקשות שנשלחות
- זהו את שלב התשלום
- נסו לגשת ישירות לשלב האישור ללא מעבר בשלב התשלום
- בדקו אם ההזמנה התקבלה
תרגיל 5 - ניצול מנגנון קופונים (Practitioner)¶
מעבדה: Inconsistent security controls (PortSwigger)
רקע:
חנות עם שני קודי הנחה. המטרה: לנצל חוסר עקביות בבדיקת הקופונים כדי לרכוש מוצר בחינם.
שלבים:
- מצאו את קוד ההנחה הזמין (רמז: בדקו את דף הבית)
- החילו את הקוד והסירו אותו
- נסו להחיל אותו שוב - האם זה עובד?
- נסו להחיל שני קופונים שונים לסירוגין
- חזרו על התהליך עד שהמחיר מגיע לאפס
תרגיל 6 - מניפולציית workflow (Practitioner)¶
מעבדה: Authentication bypass via flawed state machine (PortSwigger)
רקע:
תהליך כניסה דו-שלבי שבו אפשר לדלג על שלב בחירת התפקיד. המטרה: לקבל הרשאות אדמין.
שלבים:
- התחברו עם הפרטים הנתונים
- בשלב בחירת התפקיד, במקום לבחור - הפילו את הבקשה (Drop ב-Burp)
- נווטו ישירות ל-
/admin - בדקו איזה תפקיד קיבלתם כברירת מחדל
תרגיל 7 - ניצול כללי קידום (Practitioner)¶
מעבדה: Flawed enforcement of business rules (PortSwigger)
רקע:
חנות עם מבצע הנחה בהרשמה לניוזלטר. המטרה: שילוב בין קודי הנחה שונים לרכישה במחיר מופחת.
שלבים:
- מצאו את קוד ההנחה בבאנר בראש הדף
- הירשמו לניוזלטר וקבלו קוד הנחה נוסף
- נסו להחיל את שני הקודים - האם המערכת מגבילה קופון אחד בלבד?
- נסו להחיל אותם לסירוגין (קוד A, קוד B, קוד A, קוד B...)
- המשיכו עד שהמחיר נמוך מספיק לרכישה
תרגיל 8 - ניצול לוגיקה של מערכת הנחות (Expert)¶
מעבדה: Infinite money logic flaw (PortSwigger)
רקע:
חנות עם כרטיסי מתנה ומערכת קופונים. המטרה: ליצור מעגל רווח אינסופי.
שלבים:
- מצאו מוצר "כרטיס מתנה" בחנות
- מצאו קוד הנחה שחל גם על כרטיסי מתנה
- רכשו כרטיס מתנה עם הנחה (למשל: כרטיס של 10 דולר ב-7 דולר)
- ממשו את כרטיס המתנה - קיבלתם 10 דולר
- רווח: 3 דולר!
- אוטמטו את התהליך באמצעות Burp Macros:
- הוספת כרטיס מתנה לעגלה
- החלת קופון
- ביצוע רכישה
- מימוש כרטיס המתנה
- חזרו על התהליך עד שיש מספיק כסף לרכישת המוצר היעד
רמז: השתמשו ב-Session Handling Rules ב-Burp כדי ליצור מאקרו שחוזר על עצמו.
תרגיל 9 - ניתוח לוגיקה עסקית (Expert)¶
תרגיל עצמאי:
לפניכם קוד של מערכת רכישה. מצאו את כל הפגמים בלוגיקה העסקית:
app.post('/checkout', async (req, res) => {
const { items, couponCode, shippingAddress } = req.body;
let total = 0;
for (const item of items) {
total += item.price * item.quantity;
}
if (couponCode) {
const coupon = await db.getCoupon(couponCode);
if (coupon && coupon.isActive) {
total -= coupon.discountAmount;
}
}
if (total > req.user.balance) {
return res.status(400).json({ error: 'Insufficient funds' });
}
req.user.balance -= total;
await req.user.save();
const order = await Order.create({
userId: req.user.id,
items,
total,
status: 'confirmed',
shippingAddress
});
res.json({ orderId: order.id });
});
שאלות:
1. כמה פגמים מצאתם?
2. תארו כיצד לנצל כל אחד מהם
3. כתבו גרסה מאובטחת של הקוד