subdomain-takeover-hunt について
DNS が未取得のサードパーティーサービスを指すサブドメインを検出・検証するセキュリティテスト用スキルです。CNAME の確認から手動検証、報告までを扱います。
主な機能
- 01CNAME レコードの抽出と絞り込み
- 02subzy と subjack によるスキャン
- 03サービス固有のエラー応答の確認
- 04候補の手動検証
- 05発見事項と誤検出の記録
活用シーン
- 01列挙したサブドメインの DNS 残存を調査
- 02NXDOMAIN やサービスエラーページの確認
- 03クラウドサービスの取得可能性を検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill subdomain-takeover-huntインストール後、Claude Code で/subdomain-takeover-huntを入力して読み込まれたか確認します。
詳細
サブドメイン乗っ取りの検出
未登録または未取得のサードパーティーのクラウドサービスを指すサブドメインを検出します。CNAME レコードがすでに存在しないサービスを指している場合、攻撃者がそのリソースを登録し、対象のサブドメインで任意のコンテンツを配信できます。これにより、フィッシング、Cookie の窃取、オリジンの完全な偽装が可能になります。
使用する場面
- サブドメインの列挙で大量のリストが生成され、残存する DNS レコードをスキャンする場合。
- 対象が、共有名前空間の識別子を使用するクラウドサービス(Heroku、S3、Azure、Zendesk、Shopify)を利用している場合。
- サブドメインが NXDOMAIN、404、または「アプリが存在しない」というエラーページを返す場合。
- CNAME の転送先が、ユーザーが名前を登録できるサービスである場合。
前提条件
- curl、dnsx、subfinder を備えた
terminal。 - 自動検出用に
subzyまたはsubjackがインストールされていること。 subdomain-enumerationで取得した有効なサブドメインのリスト。
クイック検出
# DNS resolution with CNAME extraction
dnsx -retry 3 -a -cname -resp -silent -l alive_subs.txt | tee dns_records.txt
# Automated takeover scan
subzy run --targets alive_subs.txt --hide_fails --vuln
手順
フェーズ 1 — CNAME レコードの抽出
# Get all CNAME records
cat alive_subs.txt | dnsx -silent -cname -resp-only > cname_targets.txt
# Filter to suspicious services
grep -iE "heroku|s3\.amazonaws|azure|zendesk|shopify|github\.io|bitbucket|surge\.sh|netlify|vercel|ghost\.io|readme|statuspage|pantheon|desk\.com|campaignmonitor|intercom|unbounce|wordpress\.com|cargo\.collective" \
cname_targets.txt > takeover_candidates.txt
フェーズ 2 — 自動検出
# subzy — fast, shows vulnerable + fingerprint
subzy run --targets alive_subs.txt --hide_fails --vuln
# subjack — with custom fingerprints
subjack -w alive_subs.txt -t 100 -timeout 30 -o takeover_results.txt \
-ssl -c ~/subjack/fingerprints.json -v
# nuclei — takeover templates
nuclei -l alive_subs.txt \
-t nuclei-templates/takeovers/ \
-o nuclei_takeover_results.txt
フェーズ 3 — 手動での検証
# For each candidate, verify the service is claimable
CANDIDATE="api.target.com"
# Check what the CNAME points to
dig $CANDIDATE CNAME +short
# Check HTTP response
curl --max-time 30 --connect-timeout 10 -skI "https://$CANDIDATE" | head -10
# Key service-specific verification:
# Heroku: visit https://CANDIDATE — "no such app" = claimable
# S3: curl -s https://BUCKET_NAME.s3.amazonaws.com — 404 NoSuchBucket = claimable
# Zendesk: visit https://CANDIDATE — "account not found" = claimable
# GitHub Pages: dig CNAME returns user.github.io — 404 = claimable
# Azure: visit https://CANDIDATE — "tenant not found" = claimable
# Shopify: visit https://CANDIDATE — "Sorry, this shop is currently unavailable"
フェーズ 4 — S3 乗っ取りのパイプライン
subfinder -d target.com -silent \
| dnsx -silent -cname \
| grep "s3.amazonaws" \
| while read line; do
sub=$(echo "$line" | awk '{print $1}' | sed 's/\.$//')
curl --max-time 30 --connect-timeout 10 -sk "https://$sub" | grep -q "NoSuchBucket" && echo "CLAIMABLE: $sub"
done
フェーズ 5 — サービスのフィンガープリント参照
| サービス | エラーメッセージまたは識別情報 | 取得可能な兆候 |
|---|---|---|
| Heroku | 「No such app」/「There's nothing here」 | はい |
| S3 | 「NoSuchBucket」/「The specified bucket does not exist」 | はい |
| Azure | 「tenant not found」/「This tenant is not found」 | はい |
| Zendesk | 「account not found」/「Help Center Closed」 | はい |
| GitHub Pages | 404「There isn't a GitHub Pages site here」 | はい |
| Shopify | 「Sorry, this shop is currently unavailable」 | はい |
| Netlify | 「Not Found」/「Site not found」 | はい |
| Vercel | 404 — 「DEPLOYMENT_NOT_FOUND」 | はい |
| Bitbucket | 「Repository not found」 | はい |
| Surge.sh | 「project not found」 | はい |
| Readme.io | 「Project not found」 | はい |
| Statuspage | 404 — ステータスページが見つかりません | はい |
| Desk.com | 「This site is currently not available」 | はい |
| Campaign Monitor | 「Trying to get your email from」 | はい |
| Intercom | 「This page is reserved for Intercom customers」 | はい |
| Unbounce | 「The requested URL was not found」 | はい |
| WordPress.com | 「Do you want to register domain.wordpress.com?」 | はい |
注意点
- CNAME が CDN サービスに解決されても、発見事項ではありません。 Cloudflare/CloudFront/Akamai のサブドメインは取得できません。
- CNAME が有効で使用中のサービスを指している場合があります。 発見事項として報告する前に、必ずエラーページを確認してください。
- 一部のサービスは自動スキャナーをブロックします。 ブラウザーで URL にアクセスして確認してください。
- サブドメインの乗っ取りには、対象リソースの登録が必要です。 明示的な許可なくリソースを登録しないでください。
- ワイルドカード DNS(
*.target.com→ IP)は誤検出を引き起こします。 乗っ取りをスキャンする前に、ワイルドカードの応答を除外してください。
検証
dig SUBDOMAIN CNAME +shortが、ユーザー登録可能な名前空間を持つサービスを返すこと。curl --max-time 30 --connect-timeout 10 -sk https://SUBDOMAINが、リソースを利用できることを示すサービス固有のエラーページを返すこと。- CNAME の転送先が CDN またはロードバランサーに解決されていないこと。
- 報告する前に、正確なエラーメッセージとサービスの種類を記録すること。
関連スキル
subdomain-enumeration— 乗っ取りスキャン用のサブドメインリストを生成します。origin-ip-discovery— 乗っ取りが見つかった場合、同じ IP でほかのサービスがホストされていないか確認します。port-service-discovery— CNAME の解決先 IP をスキャンし、ほかに公開されているサービスを調べます。
コメント
Markdown 対応