信息收集详解——企业资产、子域名、空间测绘与真实 IP
外网打点通常从一条命令开始:
1 | curl -s "https://crt.sh/?q=%25.example.com&output=json" | jq -r '.[].name_value' | sort -u |
回显里除了 www 和 mail,往往还有 admin、oa、test、git、jenkins 这些在任何导航页上都找不到入口的名字。能查到它们,是因为公开信任的证书要满足浏览器的证书透明度要求才能生效,装过证书的主机名就此永久留在日志里,与主机是否存活无关。
crt.sh 本身不太稳,网页隔三差五 502,脚本里得带重试或者用 Cert Spotter 的查询接口兜底。
资产边界:单位名称到域名清单
子域名枚举只能枚举手里已有的域名。主站叫 example.com,子公司、控股公司、独立法人的分支机构往往各用各的域名,只枚举根域名一个都碰不到。这块的产出不是”更多子域”,而是”该枚举哪几个根域名”。
- 股权与分支机构:企查查、爱企查的「对外投资」「分支机构」页能直接拉出子公司名单(部分字段需登录),顺带看企业曾用名——改名之后旧域名继续在用的情况很常见
- ICP 备案:在工信部备案系统按主体名称查备案号,再拿备案号反查同主体名下的其他域名。备案按实际部署的网站来登记,穿透力常常强于股权关系
- 移动端入口:APP 名称反查(七麦、点点,反查功能需登录)、公众号与小程序名称反查,这些入口背后挂的 API 域名通常不在主站范围内
- 注册信息:WHOIS 的注册邮箱、注册人反查同邮箱下的其他域名,老域名尤其有效
| 信息源 | 能拿到 | 常见失效点 |
|---|---|---|
| 企业信息平台 | 子公司、曾用名、分支机构 | 分支机构未必独立备案,名单不全 |
| 备案查询 | 同主体名下所有已备案域名 | 未备案的境外或临时域名查不到 |
| APP / 小程序 | 后端 API 域名 | 只上架过旧版本,域名已换 |
| WHOIS | 同注册人的关联域名 | 隐私保护开启后只剩代理邮箱 |
半小时能把上面的表格过一遍,换来的是一份完整的根域名清单。这一步决定后面所有枚举的天花板。
域名层:证书日志与子域名枚举
证书日志给的是历史,字典爆破给的是当下,两者混着用比单靠一种覆盖高得多。
证书透明度日志是被动数据,不产生任何对目标的流量。除了 crt.sh,Cert Spotter 也提供按域名查证书的接口,免费额度够做小范围查询,crt.sh 挂掉时正好补位。
1 | curl -s "https://crt.sh/?q=%25.example.com&output=json" \ |
sed 那一步剥掉通配符前缀,sort -u 去重——同一条证书会以预证书和正式证书各出一次,一个域名重复几十行是常态。证书有效期在 2026 年 3 月起被压到 200 天,站点换证变勤,日志里同一域名的新条目也变多,被动数据比几年前更完整。
字典爆破是主动行为,覆盖面取决于字典质量。子域名的字典和目录字典不是一回事,用目录字典去跑子域只会得到一堆无意义的名字。枚举结果交给 dnsx 批量解析,顺便把 CNAME 一起打出来:
1 | subfinder -d example.com -all -silent | dnsx -silent -a -resp |
-all 会把 subfinder 的全部源都跑一遍,包括需要配 key 的源,速度明显变慢;不加时只用免 key 的默认源。导入接口 key 的收益是覆盖率,不是速度。
泛解析是这一层最大的坑。*.example.com 全部解析到同一个 IP 时,字典里每个词都会”命中”,几千个结果是假的。用 dnsx 的 -wd 指定根域名做主泛解析过滤,阈值默认 5 次比对;这个模式下别的记录类型参数会被忽略,不报错,程序按 A 记录查,输出建议切到 JSON。
存活验证把上面两步的结果压成可用的清单:
1 | httpx -l alive.txt -sc -title -td -cdn -o web.txt |
httpx 的 -td 用的是 Wappalyzer 的指纹数据集,-cdn 会标出 CDN 与 WAF 厂商。它的 README 自己提醒过,favicon 抓取、页面截图这类探针不适合和其他探针一起默认跑,单独跑一轮更稳。
空间测绘:证书与图标反查
一个资产可以不挂域名,但两样东西很难藏住:证书和图标。空间测绘的价值就在这里——它能找到那些没有任何域名解析指向的边缘资产。
国内三家常一起用:FOFA、Hunter、Quake。同一个意图,各家的写法不一样:
| 找什么 | FOFA | Hunter | Quake |
|---|---|---|---|
| 证书里含某域名 | cert="example.com" |
cert="example.com" |
cert:"example.com" |
| 证书主体组织 | cert.subject.org="某公司" |
cert.subject_org="某公司" |
cert:"某公司" |
| 图标相同 | icon_hash="123456" |
web.icon="<md5>" |
favicon:"<md5>" |
| 标题 / 正文 | title= / body= |
web.title= / web.body= |
title: / body: |
图标的算法三家用两套,混用查不到东西:Hunter 与 Quake 收的是 ico 原文件的 MD5,FOFA 的 icon_hash 是有符号 32 位 mmh3。
1 | import base64, mmh3, requests |
算出来的值与 Shodan 的 http.favicon.hash 同一口径,也和 httpx -favicon 的输出一致,负数要连负号一起带进查询。
encodebytes 和 b64encode 在这里不能互换——前者每 76 字符插一个换行、末尾再补一个,后者不折行,同一个图标算出来的值差得很远。FOFA 那边先用平台自带的图标计算工具核一次,两边对上再批量跑。
FOFA 的权限分层要看清楚:cert 系列与 title 免费可查,图标哈希、正文字段要商业版,排除蜜罐的开关要高级会员。查不到结果时先确认字段权限,别先怀疑语法写错。
证书反查是最容易被忽略的一步。一个 IP 没挂域名、也没有备案,但装了含主域名的证书,用 cert= 一搜就露出来了,这正是”没有域名却存在”的那类资产。
指纹:把资产对上具体组件
指纹服务的不是识别本身,是后面两件事:找同款系统(一套后台往往铺了几十个站),以及确认组件版本好对已知漏洞。
whatweb 用的是自己维护的签名库,命令行批量跑,适合拿一批存活结果过一遍。webanalyze 是 Wappalyzer 的 Go 移植,-update 拉的是 enthec 维护的指纹库——原版 Wappalyzer 的仓库 2023 年闭源归档,社区从最后一版 GPL 指纹集接着维护,webanalyze 与 httpx 的指纹都来自这套数据(httpx 另叠了 HTTPArchive 的一份)。
闭源的只是指纹定义,不是检测能力。fork 库继承的是 2023 年那套规则的盲区,新框架没跟上;上线半年内出现的框架识别不出来是正常的,别把”没识别到”当成”不存在”。
插件之外,响应包里有几个稳定特征值得直接看:
| 特征 | 位置 | 指向 |
|---|---|---|
rememberMe=deleteMe |
响应 Set-Cookie |
Shiro |
X-Powered-By: ThinkPHP |
响应头 | ThinkPHP |
laravel_session |
请求 Cookie |
Laravel |
| Whitelabel Error Page | 页面正文 | Spring Boot |
判定组件版本之后,把它和已知漏洞对上才有意义。同一组件的不同大版本,处置完全不同,指纹这一步的价值在于给出一个可核对的版本区间,而不是贴一堆”疑似存在漏洞”。
真实 IP:CDN 判定与绕过
判定先于绕过,判错了后面全是白费。多地 ping 出多个 IP 不代表有 CDN——自建多活配轮询 DNS 也是这个结果;单 IP 也不代表没 CDN。靠得住的是三条:CNAME 指向 CDN 厂商的域名、IP 归属 ASN 属于 CDN 厂商、证书签发者是 CDN 厂商自己的 CA。
1 | dig +short CNAME www.example.com |
确认挂了 CDN 之后,按代价从低到高试:
- 子域未加速——CDN 常常只加速主域,test、oa、mail 这些子域的 A 记录直接指向源站。先把域名层的结果全部解析一遍,很多目标到这一步就结束了
- 证书反查——源站装的证书通常与 CDN 上的一致,用证书语法在测绘平台里筛,能捞出没挂域名的源站 IP
- 历史解析——接入 CDN 之前的 A 记录会留在被动 DNS 库里,查历史记录经常直接给出现成答案
- 邮件头——触发注册验证、找回密码、订阅推送,看
Received里的发信 IP - 全网扫描——按 CDN 厂商的 IP 段之外逐段扫,再按页面特征比对
邮件头这条路要打个折:目标用第三方企业邮箱发信时,Received 里是邮件服务商的 IP,不是目标的源站。判断依据是发信域与 MX 记录是否指向自建邮件系统,第三方托管的基本取不到。
全网扫描是最后手段,代价也最实在:大规模连接会在 CDN 与目标两侧同时留痕,触发告警的概率远高于前四条,扫到自己被拉黑再回来补课的时间成本更高。
泄露面:JS 与代码仓库
SPA 站点把逻辑全推到了前端,抓包看不到的接口往往直接写在 JS 里。
1 | URLFinder -u https://example.com -s all -m 3 -o . |
URLFinder 从页面和 JS 里递归提取 URL 与子域,-m 2 是深入抓取(URL 深入一层、JS 深入三层,防止抓偏),-m 3 在同样的深度上再过滤掉 delete、remove 这类敏感路由。
-s all 连非 200 的响应一起收。比 JSFinder 更新得勤,后者已经很久没动了。
浏览器插件 FindSomething 走的是另一条路:边浏览边把页面里的接口、IP、邮箱、证件号标出来,人工过站时不容易漏。Burp 那边自带 Target → Sitemap → Find scripts 就能把 JS 全捞出来,配合 HaE 这类高亮插件按正则标敏感字段。
代码仓库是另一条独立的线,泄露的值钱程度取决于有没有硬编码凭据。搜索语法按 in:name 与 org: 组合仓库名和组织名,再叠 password、jdbc、accessKey 这类词;要长期盯新泄露,得挂监控而不是手工搜。
版本库元数据泄露(.git / .svn / .hg)是这条线上最容易直接拿到源码的一类,探测点、恢复流程与防御写在源码泄露详解里,这里只留一句:目录扫描时把这三类探测点带上,成本几乎为零。
边界与防御
资产归属判断错了,后面的工作全是负收益——把不属于目标的 IP 当成源站去测,性质立刻从授权测试变成越权。判定依据要留痕:备案主体、证书持有者、页面版权与备案号三者对上,才算这条资产归属于目标。
同一套指纹也是防御方的抓手。把自己的 favicon、证书、页面标题当成检索条件,在测绘平台上搜一遍,能查出连自己都不知道的暴露面;下线资产时撤 DNS 记录的同时要撤证书,只撤域名不撤证书,反查仍然能定位到那台机器。测试环境复用生产证书与图标是关联泄露的主因,独立域名加独立证书能切断这条链。
证书透明度日志是只增不改的。任何一次为内部测试机签发的公开证书,都会永久留在日志里成为子域名来源——内部命名规范如果在证书里体现,等于把资产结构主动交出去。
速查表
| 卡在哪 | 先看什么 | 用什么 |
|---|---|---|
| 不知道目标有哪些域名 | 股权、分支机构、备案主体 | 企查查、工信部备案系统 |
| 域名有了,子域还是不全 | CT 日志是否查过 | crt.sh,Cert Spotter 兜底 |
| 字典跑出几千个假子域 | 泛解析 | dnsx -wd 过滤 |
| 有 IP 没域名 | 证书里的域名 | 测绘平台 cert= 语法 |
| 想找同款系统 | favicon、标题、正文 | icon_hash(注意平台算法不同) |
| 挂了 CDN 要真实 IP | CNAME 与 ASN 先定性 | 未加速子域 → 证书反查 → 历史解析 |
| SPA 抓不到接口 | JS 文件 | URLFinder、Burp 的 Find scripts |
| 指纹没识别出组件 | 响应包特征是否看过 | 手工比对响应头与 Set-Cookie |







