עקיפה ברמת פרוטוקול - תרגיל¶
הכנה¶
# הקמת סביבה עם ModSecurity מאחורי reverse proxy
docker run -d --name modsec-protocol -p 8080:80 \
-e PARANOIA=2 owasp/modsecurity-crs:apache
לחלק מהתרגילים תצטרכו לשלוח בקשות HTTP גולמיות. השתמשו בסקריפט הבא:
import socket
def send_raw(host, port, raw_request):
"""שליחת בקשת HTTP גולמית"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.send(raw_request.encode())
response = b""
while True:
data = sock.recv(4096)
if not data:
break
response += data
sock.close()
return response.decode(errors='replace')
תרגיל 1 - Chunked Transfer Encoding¶
משימה:
-
שלחו בקשה רגילה שנחסמת:
-
שלחו את אותו מטען מפוצל ב-chunks:
-
נסו פיצולים אסטרטגיים - פצלו בדיוק באמצע המילה
script:
-
כתבו פונקציה שמפצלת מטען ל-chunks באופן אופטימלי:
תרגיל 2 - Content-Type Mismatch¶
משימה:
-
שלחו בקשת POST עם גוף JSON ו-Content-Type של form-urlencoded:
-
נסו את ההפך - גוף form-urlencoded עם Content-Type של JSON:
-
בדקו: באיזה כיוון העקיפה עובדת? מדוע?
תרגיל 3 - Multipart Manipulation¶
משימה:
-
המירו בקשת form-urlencoded שנחסמת ל-multipart:
-
נסו boundaries שונים:
- boundary ארוך מאוד (200+ תווים)
- boundary עם תווים מיוחדים
-
boundary עם מרכאות בכותרת Content-Type
-
נסו כפל boundary:
השתמשו ב-secondכ-boundary בגוף. האם ה-WAF מפרסר עםfirst?
תרגיל 4 - Method Override¶
משימה:
-
שלחו בקשת POST עם X-HTTP-Method-Override: GET:
-
בדקו את הכותרות הבאות:
איזו מהן השרת מכבד? -
נסו את פרמטר
_method:
-
האם ה-WAF מגן על פעולות DELETE אם הבקשה מגיעה כ-POST עם override?
תרגיל 5 - Null Byte Injection¶
משימה:
-
שלחו null byte באמצע מטען:
-
בדקו: איפה ה-WAF חותך? איפה השרת חותך?
-
נסו null byte במיקומים שונים:
-
נסו null byte ב-path:
תרגיל 6 - הערות ותחליפי רווח¶
משימה:
-
בנו מטען SQLi שמשתמש בהערות במקום רווחים:
-
נסו סוגי הערות שונות:
-
נסו תחליפי רווח:
-
כתבו פונקציה שמנסה כל שילובי תחליפי רווח:
תרגיל 7 - שילוב טכניקות¶
משימה:
אתם צריכים לעקוף WAF שמגן על נקודת הזרקת SQL:
ה-WAF חוסם:
- UNION SELECT (עם רווח)
- UNION/**/SELECT (עם הערות)
- קידוד URL של הנ"ל
משימה:
שלבו לפחות שלוש טכניקות ברמת פרוטוקול:
- שלב 1: שנו Content-Type
- שלב 2: השתמשו ב-chunked encoding
- שלב 3: הוסיפו קידוד בתוך ה-chunks
- שלב 4: הוסיפו HPP
כתבו את הבקשה הגולמית המלאה ושלחו:
raw_request = """
# השלימו את הבקשה
"""
response = send_raw("localhost", 8080, raw_request.strip())
print(response[:500])
- תעדו: איזה שילוב הצליח? מהי המינימום הנדרש?