mcpField
F
find-hidden-subdomains

find-hidden-subdomains

github.com/useosint安全571.8k 次安装12 周前更新
代码仓库

关于 find-hidden-subdomains

find-hidden-subdomains 是面向安全与资产调查的子域名发现技能,利用证书透明度日志等被动来源查找组织相关主机。它区分历史记录与当前可解析主机,并提醒排除共享证书和多租户环境带来的误报。

主要功能

  1. 01查询证书透明度日志
  2. 02按组织名称查找域名
  3. 03检查证书 SAN 与历史记录
  4. 04结合被动 DNS 和解析结果
  5. 05识别共享证书导致的误报
  6. 06按来源与状态记录主机

适用场景

  1. 01为已知域名发现历史子域名
  2. 02查找组织名下未列出的域名
  3. 03筛选仍可解析的候选主机
  4. 04评估通配符证书与共享托管影响

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/useosint/skills --skill find-hidden-subdomains

安装后在 Claude Code 中输入/find-hidden-subdomains确认已加载。

附带文件reference/name-pattern-triage.mdreference/subdomain-sources.md

详细介绍

查找隐藏子域名

组织遗忘的主机最值得查找,而其中大多数在有人申请 TLS 证书时就已留下记录。证书透明度(CT)将这些记录变成可搜索、永久且有历史记录的索引,而且免费、完全被动。初学者常犯的错误,是把 CT 查询结果当作在线主机:查出的多数主机无法解析,但这也是信息,并非噪声。

先查哪个来源

你掌握的信息从这里开始原因
一个顶级域名crt.sh 通配符查询免费覆盖范围最广,包含早已失效的名称
一个使用通配符证书的域名被动 DNS,然后查档案CT 只会显示 *.example.com
对命名规则的猜测先用 CT 了解规则,再用字典先了解规律,再进行暴力枚举
组织名称,而非域名按证书主题中的组织名称搜索找出你不知道该组织拥有的域名
已有的证书先查 SAN,再查序列号和颁发者SAN 可找到同组域名;序列号可在其他地方找到完全相同的证书
只需要当前在线的主机解析候选列表CT 天生记录历史;DNS 才是判断在线状态的依据

CT 的实际工作原理

CA 会将其签发的每张证书提交到仅可追加、可通过密码学验证的公共日志中。日志会返回签名证书时间戳(SCT),而主流浏览器会拒绝信任不包含来自合格日志的 SCT 的公开信任证书。因此,参与并非自愿:如果证书能在浏览器中使用,它就会出现在日志中。

以下三点与你息息相关:

  • 记录不会被删除。 日志仅可追加。五年前出现在证书中的主机名,即使对应的主机已不存在,仍会留在日志中。
  • 你会看到预证书和正式证书。 CA 会先记录预证书,再记录最终证书,因此大多数名称至少会出现两次。请去重。
  • 日志只涵盖公开信任的证书。 私有/内部 CA、自签名证书或 Cloudflare 源站证书都不会进入日志。CT 完全无法发现这些主机。

crt.sh

网页界面使用 ?q=,其中 % 是通配符;output=json 可返回机器可读的结果。

# every name ever seen in a cert covering example.com or a subdomain
curl -s 'https://crt.sh/?q=%25.example.com&output=json' \
  | jq -r '.[].name_value' | sed 's/^\*\.//' | sort -u

# skip expired certs when you want a bias toward current infrastructure
curl -s 'https://crt.sh/?q=%25.example.com&output=json&exclude=expired' | jq -r '.[].name_value'

# an identity search on an organization string, which finds unknown domains
curl -s 'https://crt.sh/?q=Example+Corporation&output=json' | jq -r '.[].name_value'

q 参数用于身份搜索:它会匹配域名,也会匹配主题字段(例如组织名称),因此可以找到说明中未提及的域名。

有用的 JSON 字段:name_value(证书上的所有名称,以换行符分隔)、common_name、issuer_name、not_before/not_after、serial_number、entry_timestamp 和 id(打开 https://crt.sh/?id=<id> 阅读证书)。

crt.sh 还通过 Postgres 以只读方式提供数据库访问:主机为 crt.sh,端口为 5432,用户为 guest,数据库为 certwatch。你可以用它直接针对证书索引编写 SQL,而不必翻页查询 JSON。这是一项共享的免费服务:请限制查询范围;如果频繁发送大量查询,连接可能会被中断。

其他 CT 前端及其覆盖范围和访问方式,请参阅 reference/subdomain-sources.md。

SAN 字段才是关键

浏览器会忽略通用名称;真正列出所涵盖主机名的是 subjectAltName 扩展。把它看作一份声明,反映了同一个团队共同部署了哪些内容:

  • 包含少量相关名称的证书是有意分组的——这些主机属于同一项服务,而且很可能由同一位管理员管理。
  • 包含数十个互不相关名称的证书是托管服务提供商或 CDN 的捆绑证书。**这些名称属于其他客户,不是目标的资产。**这是基于 CT 的枚举中最大的误报来源。
  • 一张证书上包含不同可注册域名中的名称,这是有价值的发现:这意味着同一运营方同时管理这些域名,可以揭示收购、品牌重塑和未公开的姊妹品牌。得出结论前请先核实——参见上面的捆绑陷阱。
  • 内部名称经常在此泄露:jira、owa、vpn、*.corp.example.com、带有机架或数据中心代码的主机名,以及从未公开发布的产品代号。

通配符会隐藏信息,而非揭示信息

*.example.com 涵盖所有子域名,但不会列出其中任何一个。组织改用通配符后(通常还会配合 DNS-01 ACME 自动化),从那时起实际上就从 CT 中消失了。看到通配符时:

  • 挖掘通配符启用之前的 CT 数据,当时每台主机都有自己的证书。
  • 转向被动 DNS,它记录的是解析结果,而不是证书。
  • 检查存档和搜索索引中的主机名(read-deleted-pages、google-like-a-spy)。
  • 查找因技术原因必须继续使用独立证书的主机:通配符无法涵盖的更深层级标签(a.b.example.com 需要自己的证书),以及任何位于不同顶级域名下的主机。

组合数据源,然后解析

CT 提供历史记录。被动 DNS 提供观测到的实际情况。词表则提供无人公开发布的名称。三种来源都要用,并按来源标记结果,因为你能赋予名称的置信度取决于它的来源。

subfinder -d example.com -all -silent -o passive.txt   # aggregates many passive sources
amass enum -passive -d example.com                     # different source mix, slower
dnsx -l passive.txt -a -resp -silent                   # resolve candidates to A records

解析会把候选名称分成三类:解析到 IP 地址、解析到 CNAME(查看目标——它会显示供应商名称,而悬空的 CNAME 是可报告的接管候选项),或者完全无法解析。失效名称仍然是发现项:它们能标示基础设施的年代、揭示命名惯例,有时还会在之后重新解析。

**在信任任何暴力枚举结果之前,先检测通配符 DNS。**解析一个不可能存在的随机名称,例如 zzq7x-nonexistent.example.com。如果它能得到响应,说明该区域会解析所有名称,你的整份暴力枚举列表都是误报。

明确划分界限:查询 CT、被动 DNS、搜索引擎和存档都不会接触目标。通过公共递归解析器解析候选名称基本不会被察觉,但确实会产生查询。使用词表进行暴力枚举会产生大量 DNS 流量,目标的 DNS 提供商可以看到这些流量,而且有时会对其限速或拦截。使用 httpx 之类的工具对结果进行 HTTP 探测则属于主动操作——你正在连接目标的服务器。在范围说明中标明暴力枚举和探测;如果本次任务仅限被动操作,则跳过这些步骤。

名称模式意味着什么

不要把所有发现的主机一视同仁。dev、staging、uat、vpn、legacy、old 和管理面板,与 www 相比,风险和后续处理方式都大不相同。分类表见 reference/name-pattern-triage.md。

容易出错的地方

  • 捆绑证书和多租户证书。 共享主机和 CDN 证书会将互不相关的客户放在同一张证书上。采用证书上的其他名称之前,务必确认它们是否可能属于你的目标。
  • CT 不是资产清单。 它记录的是证书申请。使用内部 CA、自签证书、源站证书或纯 HTTP 的主机不会出现在其中。绝不要把根据 CT 得出的列表报告为完整清单。
  • 名称比主机存续更久。 大多数 CT 历史名称都已失效。一份包含 400 个子域名但未经解析验证的列表,只是 400 条未经核实的声明。
  • 名称比所有权存续更久。 域名曾属于前任所有者期间为某个主机名签发的证书,仍会出现在当前所有者的查询结果中。请通过 who-owns-this-domain,结合域名注册和转让历史,核对 not_before。
  • 指向第三方的 CNAME 不属于目标的资产。 目标拥有的主机名指向 SaaS 租户,体现的是目标的关联关系,而非其基础设施。不要把供应商的暴露情况视为目标的暴露情况。
  • 聚合器的结果各不相同,而且不会明确说明。 每个工具查询的来源集合都不同;免费版会截断结果,却不作提示。两个工具返回相同的 50 个名称,可能都读取自同一个来源。
  • 蓄意投毒。 任何人都可以在看起来像目标的域名上,为自己控制的名称申请证书。错拼抢注域名会出现在 CT 搜索结果中,看起来像是目标自己的主机。请逐字符核对可注册域名。

置信度分级

  • 已确认资产 — 名称可解析,且属于已验证注册信息的域名;其基础设施也与目标的其他主机一致(相同的 ASN、证书颁发者、命名惯例)。
  • 可能的资产 — 位于已验证目标域名下、目前无法解析的 CT 名称,或解析到供应商共享平台的名称。名称确实存在,但当前状态尚未证实。
  • 未确认 — 与无关客户捆绑在同一张证书上的名称、通配符 DNS 区域中的暴力枚举命中项、位于不同可注册域名且没有佐证关联的名称,或尚未查看底层证书或 DNS 答案的聚合器结果。

对每台主机记录:名称的来源、证书 id 或被动 DNS 来源、not_before 日期,以及带时间戳的解析结果。

示例

目标:example-health.test,范围仅限被动方式。

crt.sh 对 %25.example-health.test 的查询返回 61 个不重复名称。对预证书/证书对去重后,剩下 38 个。其中有三个立即值得关注: vpn-uat.example-health.test、jira.internal.example-health.test 和 billing-legacy.example-health.test。

一张证书包含 44 个名称,涉及九家互不相关的公司——这是托管服务提供商的捆绑证书。剔除其中不属于目标的 43 个名称。若不这样做,就会误入死胡同,导致报告中的发现数量膨胀,远超实际发现。

解析这 38 个名称:其中 12 个有响应。jira.internal 无法通过公开 DNS 解析,但它出现在证书中,证实了内部命名惯例和一个 Jira 实例——值得记录,尽管没有可供检查的主机。vpn-uat 解析到某设备供应商的网段,应转交给 find-exposed-servers。

使用某张证书上的组织名称进行身份搜索,找到两张签发给 examplehealth-group.test 的证书。这是简介中无人提及的域名。通过 who-owns-this-domain 查询 WHOIS,发现注册机构相同。这一线索扩展了此次评估的范围。

分级:12 台可解析主机为已确认;jira.internal 为可能的资产(名称确实存在,但无法通过公开网络访问);兄弟域名为可能的资产,有待企业备案文件佐证。

跳转

新选择器跳转至
实时主机名及其 IPfind-exposed-servers
同级域名和收购的域名who-owns-this-domain、who-really-owns-it
证书主题中的组织名称x-ray-a-company
含有历史内容的失效主机名read-deleted-pages
开发/暂存主机名、类似仓库的名称secrets-in-git-history
新发现主机上已编入索引的文件google-like-a-spy
需要梳理的大量主机/域名/IP 集合graph-the-network

法律和服务条款说明

读取 CT 日志和被动 DNS 数据本质上是公开行为:这些数据本来就是供人读取的。但有两项实际限制。首先,crt.sh 这类免费服务属于共享基础设施——大量自动查询会导致你被封禁,也是不礼貌的行为;请限制查询范围并缓存结果。其次,DNS 暴力枚举和 HTTP 探测会向目标发送流量,根据流量大小和司法管辖区的不同,可能被认定为未经授权的活动;请将此类操作限制在书面授权范围内,详见 ../../ETHICS.md。发现悬空 CNAME 或暴露的暂存主机后,你有义务报告,而不是进行测试。

评论

支持 Markdown