מיפוי משטח תקיפה¶
מבוא¶
מיפוי משטח תקיפה (Attack Surface Mapping) הוא תהליך שיטתי של זיהוי כל נקודות הכניסה שתוקף יכול לנצל. בעוד שבקורס הבסיסי למדנו להשתמש בכלי סריקה פשוטים, בשיעור זה נלמד טכניקות מתקדמות - גילוי פרמטרים נסתרים, סריקות תוכן רקורסיביות, זיהוי טכנולוגיות, ובניית רשימות מילים מותאמות.
גילוי פרמטרים נסתרים¶
מה הם פרמטרים נסתרים¶
פרמטרים נסתרים הם פרמטרים שהשרת מגיב אליהם אך אינם מתועדים ואינם חלק מהממשק הרגיל. הם יכולים לשנות התנהגות, לחשוף מידע, או לעקוף מנגנוני אבטחה.
Arjun - גילוי פרמטרים¶
# התקנה
pip3 install arjun
# גילוי פרמטרי GET
arjun -u "https://target.com/api/search" -m GET
# גילוי פרמטרי POST
arjun -u "https://target.com/api/login" -m POST
# גילוי פרמטרי JSON
arjun -u "https://target.com/api/data" -m JSON
# שימוש עם רשימת מילים מותאמת
arjun -u "https://target.com/endpoint" -w custom_params.txt
# סריקה של מספר URLs
arjun -i urls.txt -m GET -o arjun_results.json
# דוגמת פלט:
# [+] Parameter found: debug (Type: GET)
# [+] Parameter found: admin (Type: GET)
# [+] Parameter found: verbose (Type: GET)
# [+] Parameter found: format (Type: GET)
Param Miner ב-Burp Suite¶
# שימוש ב-Param Miner (ראו שיעור Burp מתקדם):
# לחיצה ימנית על בקשה > Extensions > Param Miner > Guess params
# פרמטרים נפוצים שמתגלים:
# debug=1 - מפעיל מצב debug
# admin=true - מעניק הרשאות admin
# test=1 - מצב בדיקה
# verbose=1 - פלט מפורט
# format=json - שינוי פורמט תגובה
# callback=func - פרמטר JSONP
# _method=PUT - עקיפת שיטת HTTP
# x-debug=1 - כותרת debug
כותרות HTTP נסתרות¶
כותרות HTTP מסוימות יכולות לשנות את התנהגות השרת. רוב הכותרות האלו משמשות Reverse Proxies ו-Load Balancers.
# כותרות לעקיפת הגבלות גישה:
X-Forwarded-For: 127.0.0.1
X-Real-IP: 127.0.0.1
X-Originating-IP: 127.0.0.1
X-Client-IP: 127.0.0.1
True-Client-IP: 127.0.0.1
# כותרות לשינוי נתיב:
X-Original-URL: /admin
X-Rewrite-URL: /admin
X-Custom-IP-Authorization: 127.0.0.1
# כותרות לעקיפת cache:
X-Forwarded-Host: attacker.com
X-Host: attacker.com
# בדיקה עם curl:
curl -s "https://target.com/admin" -H "X-Forwarded-For: 127.0.0.1" -v
curl -s "https://target.com/" -H "X-Original-URL: /admin" -v
curl -s "https://target.com/" -H "X-Rewrite-URL: /admin" -v
# header_fuzz.py - סקריפט לבדיקת כותרות נסתרות
import requests
target = "https://target.com/admin"
headers_to_test = {
"X-Forwarded-For": "127.0.0.1",
"X-Real-IP": "127.0.0.1",
"X-Originating-IP": "127.0.0.1",
"X-Client-IP": "127.0.0.1",
"True-Client-IP": "127.0.0.1",
"X-Custom-IP-Authorization": "127.0.0.1",
"X-Original-URL": "/admin",
"X-Rewrite-URL": "/admin",
"X-Forwarded-Host": "localhost",
"X-Host": "localhost",
"X-Forwarded-Proto": "https",
"X-ProxyUser-Ip": "127.0.0.1",
"Client-IP": "127.0.0.1",
"Forwarded": "for=127.0.0.1",
}
# בקשה ללא כותרות מיוחדות (baseline)
baseline = requests.get(target, verify=False)
print(f"[Baseline] Status: {baseline.status_code}, Length: {len(baseline.text)}")
for header, value in headers_to_test.items():
resp = requests.get(target, headers={header: value}, verify=False)
if resp.status_code != baseline.status_code or len(resp.text) != len(baseline.text):
print(f"[INTERESTING] {header}: {value}")
print(f" Status: {resp.status_code}, Length: {len(resp.text)}")
סריקת תוכן מתקדמת¶
ffuf - סריקה מהירה ומתקדמת¶
# סריקת ספריות בסיסית
ffuf -u "https://target.com/FUZZ" -w /usr/share/wordlists/dirb/common.txt -mc all -fc 404
# סריקה רקורסיבית
ffuf -u "https://target.com/FUZZ" -w wordlist.txt -recursion -recursion-depth 3
# סריקה עם סיומות
ffuf -u "https://target.com/FUZZ" -w wordlist.txt -e .php,.asp,.aspx,.jsp,.html,.js,.json,.xml,.bak,.old,.txt
# סריקה עם סינון לפי גודל תגובה (התעלמות מדפי 404 מותאמים)
ffuf -u "https://target.com/FUZZ" -w wordlist.txt -mc all -fs 1234
# סריקה עם סינון לפי מספר מילים
ffuf -u "https://target.com/FUZZ" -w wordlist.txt -mc all -fw 42
# סריקה עם כותרות מותאמות
ffuf -u "https://target.com/FUZZ" -w wordlist.txt \
-H "Cookie: session=abc123" \
-H "Authorization: Bearer token123"
# סריקת פרמטרים
ffuf -u "https://target.com/api/search?FUZZ=test" -w params.txt -mc all -fs 0
# סריקת ערכי פרמטר
ffuf -u "https://target.com/api/user?id=FUZZ" -w /usr/share/wordlists/ids.txt -mc 200
# סריקת סאבדומיינים
ffuf -u "https://FUZZ.target.com" -w subdomains.txt -mc 200,301,302,403
# סריקת vhosts (Virtual Hosts)
ffuf -u "https://target.com" -w vhosts.txt -H "Host: FUZZ.target.com" -mc all -fs 1234
feroxbuster - סריקה רקורסיבית מתקדמת¶
# התקנה
sudo apt install feroxbuster
# סריקה רקורסיבית עם סיומות
feroxbuster -u https://target.com -w wordlist.txt -x php,asp,html,js \
--depth 4 --threads 50
# סריקה עם פילטר
feroxbuster -u https://target.com -w wordlist.txt \
--filter-status 404 --filter-size 1234
# סריקה עם אותנטיקציה
feroxbuster -u https://target.com -w wordlist.txt \
-H "Cookie: session=abc123" \
-H "Authorization: Bearer token"
# שמירת תוצאות
feroxbuster -u https://target.com -w wordlist.txt -o results.txt
gobuster - סריקה מהירה¶
# סריקת ספריות
gobuster dir -u https://target.com -w wordlist.txt -t 50 -x php,html,js
# סריקת vhosts
gobuster vhost -u https://target.com -w vhosts.txt -t 50
# סריקת DNS
gobuster dns -d target.com -w subdomains.txt -t 50
# סריקה עם follow redirects
gobuster dir -u https://target.com -w wordlist.txt -r
זיהוי טכנולוגיות - Technology Fingerprinting¶
כלי זיהוי¶
# Wappalyzer (תוסף דפדפן) - מזהה אוטומטית טכנולוגיות בעמודים שאתם גולשים
# WhatWeb - כלי שורת פקודה
whatweb https://target.com
# דוגמת פלט:
# https://target.com [200 OK] Apache[2.4.41], Bootstrap, HTML5,
# JQuery[3.6.0], PHP[7.4.3], WordPress[6.0]
# httpx עם זיהוי טכנולוגיות
echo "https://target.com" | httpx -tech-detect -status-code -title
# builtwith.com - שירות מקוון לזיהוי טכנולוגיות
# https://builtwith.com/target.com
זיהוי ידני מכותרות¶
# כותרות HTTP שחושפות טכנולוגיה
curl -sI https://target.com | grep -iE "server|x-powered|x-aspnet|x-generator|x-drupal|x-framework"
# כותרות נפוצות:
# Server: Apache/2.4.41 (Ubuntu)
# Server: nginx/1.18.0
# X-Powered-By: PHP/7.4.3
# X-Powered-By: Express
# X-Powered-By: ASP.NET
# X-Generator: WordPress 6.0
# X-Drupal-Cache: HIT
# X-Framework: Laravel
זיהוי מתוכן הדף¶
# חיפוש מזהים בקוד HTML
curl -s https://target.com | grep -oP '(wp-content|wp-includes|drupal|joomla|angular|react|vue|next|nuxt)'
# חיפוש meta tags
curl -s https://target.com | grep -i "generator"
# <meta name="generator" content="WordPress 6.0">
# בדיקת קבצים ספציפיים
curl -sI https://target.com/wp-login.php # WordPress
curl -sI https://target.com/administrator/ # Joomla
curl -sI https://target.com/user/login # Drupal
curl -sI https://target.com/elmah.axd # ASP.NET
curl -sI https://target.com/package.json # Node.js
גוגל דורקינג - Google Dorking¶
דורקים מתקדמים¶
# חשיפת קבצי תצורה
site:target.com ext:conf OR ext:cfg OR ext:ini OR ext:env OR ext:yml
# חשיפת גיבויים
site:target.com ext:bak OR ext:old OR ext:backup OR ext:swp OR ext:save
# חשיפת לוגים
site:target.com ext:log OR inurl:log OR inurl:logs
# חשיפת בסיסי נתונים
site:target.com ext:sql OR ext:db OR ext:sqlite OR ext:mdb
# חשיפת מסמכים פנימיים
site:target.com ext:doc OR ext:docx OR ext:xls OR ext:xlsx OR ext:pdf intext:confidential
# מציאת דפי התחברות
site:target.com inurl:login OR inurl:signin OR inurl:admin OR inurl:dashboard
# מציאת שגיאות
site:target.com intitle:"Error" OR intitle:"Exception" OR intext:"stack trace"
# חשיפת ספריות פתוחות
site:target.com intitle:"index of" OR intitle:"directory listing"
# מציאת API documentation
site:target.com inurl:swagger OR inurl:api-docs OR inurl:graphql
# חשיפת קוד מקור
site:target.com ext:php OR ext:asp OR ext:jsp intext:"<?php" OR intext:"<%"
# מציאת דפי phpinfo
site:target.com inurl:phpinfo OR ext:php intitle:"phpinfo()"
אוטומציה של דורקים¶
# google_dork.py - יצירת דורקים אוטומטית
import sys
domain = sys.argv[1]
dorks = [
f'site:{domain} ext:conf OR ext:cfg OR ext:ini OR ext:env',
f'site:{domain} ext:bak OR ext:old OR ext:backup',
f'site:{domain} ext:log inurl:log',
f'site:{domain} ext:sql OR ext:db',
f'site:{domain} inurl:admin OR inurl:dashboard',
f'site:{domain} intitle:"index of"',
f'site:{domain} inurl:swagger OR inurl:api-docs',
f'site:{domain} intitle:"phpinfo()"',
f'site:{domain} intext:"sql syntax" OR intext:"mysql_fetch"',
f'site:{domain} ext:xml OR ext:json inurl:config',
f'site:{domain} inurl:wp-content OR inurl:wp-includes',
f'site:{domain} inurl:".git" OR inurl:".svn" OR inurl:".env"',
f'site:{domain} filetype:pdf OR filetype:doc "confidential"',
f'site:{domain} inurl:redirect OR inurl:return OR inurl:next',
]
print(f"Google Dorks for {domain}:")
print("=" * 50)
for dork in dorks:
print(dork)
בניית רשימות מילים מותאמות¶
CeWL - יצירת רשימת מילים מאתר¶
# CeWL סורק אתר ויוצר רשימת מילים מהתוכן
cewl https://target.com -d 3 -m 5 -w custom_wordlist.txt
# הסבר:
# -d 3 : עומק סריקה (3 רמות)
# -m 5 : אורך מילה מינימלי (5 תווים)
# -w : קובץ פלט
# כולל כתובות מייל
cewl https://target.com -d 3 -m 5 -e --email_file emails.txt -w wordlist.txt
יצירת רשימת מילים מותאמת¶
# custom_wordlist.py - יצירת רשימת מילים מבוססת מידע על היעד
import itertools
company_name = "TargetCorp"
products = ["widget", "gadget", "service"]
years = ["2023", "2024", "2025"]
common_suffixes = [
"admin", "api", "app", "auth", "backup", "beta", "blog",
"cms", "config", "console", "dashboard", "db", "debug",
"demo", "dev", "docs", "download", "files", "git",
"internal", "jenkins", "jira", "lab", "legacy", "login",
"mail", "manage", "monitor", "new", "old", "panel",
"portal", "prod", "qa", "secret", "staging", "status",
"store", "test", "tmp", "upload", "v1", "v2", "vpn", "wiki"
]
words = set()
# שמות בסיסיים
words.update(common_suffixes)
# שילובים עם שם החברה
for suffix in common_suffixes:
words.add(f"{company_name.lower()}-{suffix}")
words.add(f"{suffix}-{company_name.lower()}")
# שילובים עם מוצרים
for product in products:
words.add(product)
for suffix in ["api", "admin", "app", "dev", "test", "staging"]:
words.add(f"{product}-{suffix}")
# שילובים עם שנים
for year in years:
for suffix in ["backup", "archive", "old", "data"]:
words.add(f"{suffix}-{year}")
words.add(f"{suffix}{year}")
# כתיבה לקובץ
with open("target_wordlist.txt", "w") as f:
for word in sorted(words):
f.write(word + "\n")
print(f"[+] Generated {len(words)} words")
שילוב רשימות מילים¶
# שילוב רשימות מובנות עם מותאמות
cat /usr/share/wordlists/dirb/common.txt \
/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
custom_wordlist.txt \
target_wordlist.txt | sort -u > combined_wordlist.txt
echo "Total words: $(wc -l < combined_wordlist.txt)"
השוואת גרסאות קבצי JavaScript¶
מציאת שינויים בין גרסאות¶
# הורדת גרסה ישנה מ-Wayback Machine
curl -s "https://web.archive.org/web/2024/https://target.com/static/js/app.js" > old.js
# הורדת גרסה נוכחית
curl -s "https://target.com/static/js/app.js" > new.js
# פירמוט
js-beautify old.js > old_pretty.js
js-beautify new.js > new_pretty.js
# השוואה
diff old_pretty.js new_pretty.js | head -100
# חיפוש נתיבים חדשים שהתווספו
diff old_pretty.js new_pretty.js | grep "^>" | grep -oP '"/[a-zA-Z0-9/_-]+"'
# js_diff.py - השוואת נתיבי API בין גרסאות JS
import re
import sys
def extract_paths(content):
patterns = [
r'["\'](/api/[a-zA-Z0-9/_\-{}:.?&=]+)["\']',
r'["\'](/v[0-9]+/[a-zA-Z0-9/_\-{}:.]+)["\']',
r'fetch\(["\']([^"\']+)["\']',
r'path:\s*["\']([^"\']+)["\']',
]
paths = set()
for pattern in patterns:
paths.update(re.findall(pattern, content))
return paths
with open(sys.argv[1]) as f:
old_paths = extract_paths(f.read())
with open(sys.argv[2]) as f:
new_paths = extract_paths(f.read())
added = new_paths - old_paths
removed = old_paths - new_paths
print(f"\n[+] New paths ({len(added)}):")
for p in sorted(added):
print(f" + {p}")
print(f"\n[-] Removed paths ({len(removed)}):")
for p in sorted(removed):
print(f" - {p}")
מיפוי גרסאות API ונקודות קצה ישנות¶
זיהוי גרסאות API¶
# בדיקת גרסאות נפוצות
for version in v1 v2 v3 v4 v5; do
status=$(curl -s -o /dev/null -w "%{http_code}" "https://target.com/api/$version/users")
echo "[$status] /api/$version/users"
done
# דוגמת פלט:
# [200] /api/v1/users <- גרסה ישנה, עשויה להיות פגיעה
# [200] /api/v2/users <- גרסה נוכחית
# [404] /api/v3/users <- לא קיימת
ניצול גרסאות ישנות¶
# גרסאות API ישנות לעיתים:
# 1. חסרות בדיקות הרשאה שהתווספו בגרסאות חדשות
# 2. מקבלות פרמטרים שנחסמו בגרסאות חדשות
# 3. מחזירות מידע מפורט יותר
# 4. חסרות rate limiting
# דוגמה - גרסה v1 חושפת מידע רגיש
curl -s "https://target.com/api/v1/users/1" | jq
# {"id":1,"name":"admin","email":"admin@target.com","password_hash":"$2b$10$...","role":"admin"}
# גרסה v2 מסננת מידע רגיש
curl -s "https://target.com/api/v2/users/1" | jq
# {"id":1,"name":"admin","email":"admin@target.com"}
מיפוי שלם - מתודולוגיה¶
סדר הפעולות המומלץ¶
1. מיפוי סאבדומיינים (שיעור קודם)
2. זיהוי טכנולוגיות (WhatWeb, Wappalyzer)
3. סריקת תוכן (ffuf, feroxbuster)
4. גילוי פרמטרים (Arjun, Param Miner)
5. ניתוח JavaScript (שיעור קודם)
6. גוגל דורקינג
7. בדיקת גרסאות API
8. בדיקת כותרות HTTP נסתרות
9. בניית רשימת מילים מותאמת וסריקה נוספת
10. תיעוד כל הממצאים
תיעוד ממצאים¶
# מבנה מומלץ לתיעוד:
# target: target.com
# date: 2024-01-15
#
# Subdomains:
# - admin.target.com [200] - Admin panel (WordPress)
# - api.target.com [200] - REST API (Node.js/Express)
# - staging.target.com [403] - Staging environment
# - old.target.com [200] - Legacy application (PHP/Apache)
#
# Technologies:
# - Main site: React, Next.js, CloudFlare
# - API: Node.js, Express, MongoDB
# - Admin: WordPress 6.0, PHP 7.4, MySQL
#
# Hidden Parameters:
# - /api/search?debug=1 - Exposes query details
# - /api/users?admin=true - Bypasses role check (!)
#
# Interesting Endpoints:
# - /api/v1/users (legacy, returns password hashes)
# - /admin/phpinfo.php (PHP info page)
# - /.git/HEAD (Git repository exposed)
# - /api/internal/config (Internal configuration)
סיכום¶
בשיעור זה למדנו:
- גילוי פרמטרים נסתרים - שימוש ב-Arjun, Param Miner, ובדיקת כותרות HTTP מיוחדות
- סריקת תוכן מתקדמת - ffuf, feroxbuster, gobuster עם הגדרות מתקדמות
- זיהוי טכנולוגיות - WhatWeb, Wappalyzer, זיהוי מכותרות ותוכן
- גוגל דורקינג - דורקים מתקדמים לחשיפת מידע רגיש
- רשימות מילים מותאמות - בניית רשימות ייעודיות ליעד ספציפי
- מיפוי גרסאות API - זיהוי וניצול גרסאות ישנות
שילוב כל הטכניקות האלו יוצר תמונה מלאה של משטח התקיפה ומגלה נקודות כניסה שכלים אוטומטיים מפספסים.