我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

子域名信息查询与外部资产测绘:从探测到资产清单

子域名信息查询与外部资产测绘:从探测到资产清单 做资产梳理这行的朋友大概都有过类似经历接手一个项目台账上写着三十来个域名结果一轮子域名信息查询跑下来后端暴露出来的入口有三百多个其中一半以上没人说得清是谁维护的。子域名信息查询这件事听起来只是查一查有哪些子域实际上它是整个外部资产测绘里投入产出比最高的一环——不需要接触目标业务不需要复杂环境靠公开数据加字典就能把一张隐藏的资产地图铺开。它解决的核心问题是信息不对称主域名是明面上的子域名才是那些被遗忘的测试环境、临时上线系统、第三方托管入口的聚集地。这篇内容写给三类人负责资产台账的运维同学、做安全自查的工程师、以及想把这个流程工程化的开发者。下面我把整套思路、参数、踩过的坑都摊开讲能直接抄的部分我会写清楚。1. 先搞清楚子域名查询的价值边界1.1 从一个主站到一张资产地图很多人对子域名的理解停留在www、mail、blog这几个常见前缀上实际上一个运营超过五年的业务域名子域名规模往往和业务复杂度成正比。市场活动页会开临时子域测试环境会开test/uat/staging移动端会开app/m/wap接口层会开api/open/gateway还有各种外包团队交付时留下的、命名毫无规律的三级四级域名。这些入口的共同特征是创建时没人觉得需要登记创建后没人负责回收。所以子域名信息查询的真正产出不是一份域名列表而是一张资产地图。地图的价值在于它把分散的记录聚合成可比较的对象哪些域名解析到了内网地址段、哪些挂在第三方云服务上、哪些的 TLS 证书已经过期三个月、哪些页面的标题写着系统维护中却依然对外可达。我在实际项目里见过最典型的情况是某个业务线三年前做活动开了一个子域活动结束后页面没下线后台管理入口还留着默认路径——这类问题只有靠系统性的查询才能发现靠人工回忆是不可能的。从工程角度看一张好的资产地图至少要包含四个维度域名本身完整 FQDN、解析事实A/AAAA/CNAME 记录、服务特征HTTP 状态码、页面标题、响应头里的技术栈线索、归属判断自有 IP、云托管、CDN 加速。缺了最后一维你拿到的就是一堆无法定责的字符串。1.2 谁需要做、在什么前提下做先说前提这个必须放在最前面子域名信息查询只应该对自己拥有或已获得明确书面授权的资产进行。原因很实际——主动爆破环节会对目标权威 DNS 产生真实查询压力被动收集环节虽然只读公开数据但把结果与业务系统关联分析本质上已经属于资产测绘行为。未经授权的测绘在很多地区的法规里都是明确禁止的这不是技术问题是责任问题。合规的做法是查询范围以书面授权清单为准清单里写清楚根域名、允许使用的技术手段、允许的并发上限、数据留存期限。我建议在项目启动时就把这份清单落到文档里别嫌麻烦等到需要向业务方解释为什么上周 DNS 查询量涨了十倍的时候这份文档就是唯一的依据。需要做这件事的角色大致分三类。第一类是资产管理员目的是把台账补全把僵尸资产清理掉这类需求偏重完整度和归属判断。第二类是安全自查人员目的是找出对外暴露但缺乏防护的入口偏重服务特征识别和风险排序。第三类是开发者可能是为了做域名迁移、证书统一管理、或是给监控系统补全探针列表偏重解析事实和变更追踪。三类人的工具链其实高度重合差别只在最后的输出排序和处置动作上。提示任何一次查询开始前先确认根域名当前是否使用泛解析。这个判断会直接决定你后面几万条结果里有多少是噪音也会决定你字典策略要不要调整。2. 原理拆解子域名是怎么被一条条捞出来的2.1 被动收集不碰目标从公开数据里捡被动收集的核心思想是别人已经替我查过了。互联网上存在大量公开的、包含域名信息的数据集我们只是把这些数据集里的记录按根域名过滤出来。常见的来源有这几类证书透明度日志。这是目前性价比最高的单一来源。所有公开信任的 TLS 证书签发记录都会被写进日志而证书里的 SAN 字段Subject Alternative Name经常一次性列出一批域名。很多运维在申请证书时为了省事会把同一业务线的所有子域塞进一张证书等于主动把资产清单公开了。这类数据的好处是真实发生过不是猜出来的。搜索引擎索引。站点被收录时URL 里的主机名就是现成的子域名。按site:语法配合常见前缀做筛选能捞到一批。缺点是有滞后且只覆盖被索引过的页面。公开的 DNS 扫描数据集。有一些长期运行的互联网测量项目会定期全量扫描并公开解析结果从中可以筛出属于目标根域的记录。这类数据的价值在于覆盖长尾——那些字典里没有、搜索引擎也没收录的奇怪命名往往能在这里出现。代码托管平台的公开仓库。配置文件里硬编码的域名、CI 脚本里的部署地址、前端代码里的 API 基地址都是高价值线索。这一路要注意只读取公开可见的内容。邮件与 DNS 配置记录。SPF 记录里常会列出授权的发信服务器子域DMARC 的rua地址、DKIM 选择器、MX 记录指向的主机名都能反推出内部命名规范。我见过一个案例从 SPF 记录里翻出了三个从未在字典里出现过的区域性发信子域。被动收集的工程要点是去重和来源标记。同一个域名可能从五个来源出现你要记录来源CT日志搜索引擎因为来源数量本身就是一个可信度权重——单一来源出现的记录后面验证时要多留个心眼。2.2 主动探测字典、DNS与速率控制主动探测就是拿一份候选名字列表逐个拼成候选名.根域名去做 DNS 查询能解析出记录的就认为存在。原理简单到不能再简单难点全在工程细节上。第一是字典质量。一份好的字典不是几万个随机单词堆起来的而是分层组织的通用层www、mail、api、cdn、static、业务层按行业特点比如电商会有pay、order、cart教育行业会有course、exam、study、地域层bj、sh、gz之类的拼音缩写或者us、hk之类的区域码、环境层test、dev、uat、staging、pre、sandbox、数字与序列层1到999v1、v2app1到app20。分层的好处是可以按需组合先跑通用环境层拿到高置信度结果再决定要不要投入算力跑长尾。第二是解析器选择。直接用系统默认的递归解析器跑十万次查询大概率会被上游限速甚至临时拒绝服务。靠谱的做法是自建一个本地递归解析器并开启缓存或者准备一组解析出口做轮询。缓存命中率会很惊喜——很多字典里的高频词在不同根域下解析结果一致本地缓存能显著压低实际外部查询量。第三是并发与超时。这两个参数必须一起算。假设字典 8 万条单次查询平均耗时 60 毫秒并发 100那么理论吞吐是 100 / 0.06 ≈ 1666 QPS跑完需要 80000 / 1666 ≈ 48 秒。但现实里 DNS 查询的耗时分布极不均匀绝大部分在 20 毫秒内返回少数超时请求会拖到 3 秒。如果超时设得太宽松几个慢查询就能把并发槽位占满整体吞吐反而下降。我的经验值是超时设 2 到 3 秒并发从 50 起步观察失败率再往上加。失败率超时占比超过 5% 就说明压力过大或者解析器扛不住了要降并发。# 示意命令参数名以你实际选用的工具为准 # 字典爆破100 并发2 秒超时结果写入 brute.txt dns_brute -d example.com \ -w ./dict/level1.txt \ -c 100 \ -t 2 \ -r ./resolvers.txt \ -o ./out/brute.txt注意这段命令里的工具名和参数是示意写法不同实现差异很大。真正要抄的是参数之间的关系不是具体的字母。2.3 证书透明度最容易被忽略的高产来源单独把证书透明度拎出来讲是因为它值得单独做一轮。CT 日志的查询接口支持按域名做前缀匹配返回的是证书条目你需要从name_value字段里把域名一个个拆出来。这个源的两个特点是新鲜度高证书一签发就能查到、命名真实证书里的名字是运维自己填的不是猜的。实操中有几个细节。一是要处理通配符证书*.example.com这种记录只说明根域下有通配符不指向具体子域但它的存在本身就是个信号——说明该域可能开了泛解析后面要重点验证。二是要做时间窗口控制CT 日志的数据量随时间线性增长如果不限定起始时间一次查询可能返回几十万条历史记录其中大量是早已下线的。我通常只取最近 12 到 24 个月的记录兼顾完整度和效率。三是要注意证书里可能包含不属于目标组织但共用同一张证书的域名比如虚拟主机服务商把多个客户域名塞进一张证书这类记录必须靠后续的解析验证来剔除。同步一下如果目标根域有多个比如主域加几个品牌域CT 查询要按根域分别跑然后合并去重。合并时保留首次出现时间因为那往往对应资产的实际创建时间对后续的归属判断很有帮助。2.4 泛解析和 CDN两个最大的噪音源这两件事如果不处理你拿到的结果基本没法用。泛解析指根域配置了通配符记录任何随便什么.example.com都能解析成功。这时候你用字典跑出来的结果会是一份和字典长度完全一致的列表——看起来收获巨大实际全是假的。检测方法很简单生成 10 到 20 个高熵随机字符串比如x7k2m9q1、zz8f3a6b拼成子域去解析。如果全部解析成功且返回的 IP 集合高度重合基本可以判定为泛解析。判定为泛解析之后不要直接放弃要做的是记录泛解析 IP 集合然后在后续结果里反向剔除凡是解析结果落在泛解析 IP 集合内的记录全部标记为低置信度。但这里有个坑——真实的子域也可能恰好解析到同一组 IP尤其是在用统一入口做反向代理的架构下。我的处理方式是保留这些记录但打上标记同时在验证阶段用 HTTP 层做二次确认泛解析返回的通常是统一的默认页或 404而真实子域会有各自不同的响应内容、不同的证书、不同的标题。这个差异就是区分依据。CDN带来的是另一种误导。很多子域会返回CNAME指向某个 CDN 厂商的域名你顺着解析只能拿到 CDN 边缘节点的 IP拿不到真实源站。这时候不要试图去绕过——那既无必要也不合适。正确做法是把这类记录单独归类为托管型资产记录 CDN 厂商、证书信息、HTTP 响应特征这些信息对资产盘点同样有价值。真正需要关注的是那些没有走 CDN、直接解析到自有 IP 段的子域它们往往意味着更直接的暴露面。3. 工具选型不追求全能追求能串起来3.1 被动收集层的选型逻辑被动收集工具这个方向选择很多我的建议是先想清楚三件事再决定用什么。第一你要的是广度还是可控性。有些工具内置了几十个数据源一次调用能把公开数据几乎榨干代价是耗时很长几分钟到十几分钟不等而且部分数据源需要各自的 API 凭据。有些工具只做单一数据源胜在快、稳定、可编程。项目初期我倾向于先用广度型工具跑一轮拿基线后面做周期性监控时换成单源工具跑得快、diff 更清晰。第二凭据管理怎么做。多源聚合类工具通常需要配置一批第三方服务的 API Key这些 Key 有的免费额度很低有的按调用量计费。工程上要把凭据集中放在环境变量或配置文件里别硬编码进脚本。同时要记录每个源的消耗避免月底发现某个源的额度被打爆。第三输出格式是否统一。理想的输出是每行一个 FQDN 加来源标记方便后续sort -u和awk处理。如果工具输出的是带 ANSI 颜色的表格或者 JSON 嵌套结构前期多花十分钟写个转换脚本后面能省很多事。# 示意流程多源被动收集后做标准化归并 passive_scan -d example.com --sources ct,engine,dataset -o ./out/raw_passive.txt # 统一小写、去空白、去重、按字母序排列 tr A-Z a-z ./out/raw_passive.txt | tr -d \r | sort -u ./out/passive.txt wc -l ./out/passive.txt3.2 爆破层与字典的匹配爆破工具的差异主要在性能上功能层面反而趋同。选型时看三个指标单机 QPS 上限、是否支持自定义解析器列表、是否支持通配符自动检测。第三点很关键很多工具会在启动时自动做泛解析探测省掉你自己写检测脚本的功夫。字典这块我想多说两句因为它是决定上限的东西。网上流传的十万级子域名字典质量参差不齐里面大量是重复项、拼写错误、以及从别的行业硬搬过来的词。更靠谱的做法是自己维护一份分层字典层级内容示例规模建议使用阶段通用高频www、mail、api、cdn、static、img200 到 500每轮必跑环境标识test、dev、uat、staging、pre、sandbox50 到 100每轮必跑业务功能pay、order、user、admin、report300 到 800每轮必跑地域区域bj、sh、gz、hk、us、sg50 到 200视业务覆盖技术组件git、jenkins、wiki、monitor、log100 到 300每轮必跑数字序列1 到 999、v1 到 v201000 左右按需拼音组合业务相关的拼音全拼与首字母视情况按需分层字典的实际用法是第一轮只跑前三层约一千条几十秒出结果快速建立基线第二轮加技术组件和地域层第三轮才上数字序列和拼音组合。这种渐进式策略的好处是绝大多数情况下前两轮已经能覆盖 80% 以上的真实资产后面的长尾投入产出比很低可以根据项目时间预算决定要不要做。3.3 验证层把能解析变成确认存在能解析只是第一步。一个子域解析成功可能是真的有个服务在那跑也可能是一条遗留的 DNS 记录、一个已下线的 CNAME、或者泛解析的产物。验证层的任务就是把这三种情况分开。验证手段按成本从低到高排DNS 层看记录类型和 IP 归属TLS 层看证书是否有效、SAN 里有哪些名字HTTP 层看状态码、响应头、页面标题、favicon 哈希。这三层跑完一条记录的可信度基本就确定了。HTTP 验证要注意协议和端口。很多子域只开 HTTPS 不开 HTTP或者只在非标准端口上提供服务。验证时至少覆盖http://和https://两种协议端口先测 80 和 443如果 DNS 记录里有明确的其它端口线索再补测。并发不要开太高HTTP 探测比 DNS 查询重得多几百并发很容易把目标或自己的出口打满起始值建议 20 到 30。# 示意批量探测并抓取关键特征 http_probe -l ./out/passive.txt \ -ports 80,443 \ -threads 25 \ -timeout 8 \ -title \ -tech-detect \ -json -o ./out/probe.json4. 完整实操从零到一份可用的资产清单4.1 环境与目录规划动手之前先把目录结构定下来这个习惯能救命。我习惯按阶段 时间戳组织workdir/ ├── dict/ # 字典按层级分文件 │ ├── level1.txt │ ├── level2.txt │ └── level3.txt ├── resolvers.txt # 解析器列表 ├── out/ │ ├── 20250101_passive.txt │ ├── 20250101_brute.txt │ ├── 20250101_merged.txt │ ├── 20250101_probe.json │ └── 20250101_final.csv └── log/ └── 20250101_run.log带日期前缀的好处是永远知道哪份结果是哪次跑的做 diff 的时候一目了然。解析器列表单独放方便随时替换日志单独存出问题能回溯到具体是哪一轮、哪个参数导致的异常。环境上有两点准备一是确认本机对外的 DNS 查询不会被本地网络策略拦掉可以先手动查几个已知域名验证连通性二是确认磁盘空间一次完整跑下来中间文件加上 HTTP 响应体如果保留的话可能占几百 MB 到几个 GB别到时候写满。4.2 第一轮被动收集与初步归并第一轮目标只有一个在尽可能短的时间内拿到一份基线。我的做法是并行跑被动收集和第一层字典爆破两条线互不干扰。被动收集按 4 到 8 分钟的超时上限跑超时就收工已有的结果先拿去用。这一步要注意的是不要把多个根域混在一起跑每个根域单独出一份结果最后再合并。原因不同根域的泛解析配置不同混着跑后面剔除噪音会很麻烦。第一层字典爆破用level1.txt几百条几十秒完成。这一步的结果可信度最高因为通用高频词的命名在任何组织里都高度相似。两份结果合并后做第一次去重同时统计两个数字被动来源的独立记录数、爆破来源的独立记录数、两者的交集。交集的大小能反映一件事——如果交集几乎为零说明被动源的覆盖方向和你字典的方向完全不同这很正常CT 日志偏向真实业务命名字典偏向通用命名如果爆破结果远超被动结果说明这个组织的命名比较规范字典命中率高后面值得加大字典投入。# 合并、去重、按字母序输出 cat ./out/passive.txt ./out/brute_l1.txt \ | tr A-Z a-z \ | grep -E ^[a-z0-9._-]\.example\.com$ \ | sort -u ./out/merged_l1.txt # 看总量和交集 comm -12 (sort -u ./out/passive.txt) (sort -u ./out/brute_l1.txt) | wc -l那个grep -E过滤不能省。被动源里经常混进格式不对的字符串比如带路径的 URL、带端口的地址、甚至是被截断的半个域名不过滤干净后面每一步都要处理异常。4.3 第二轮字典爆破与并发参数估算第二轮把level2.txt和level3.txt加上规模跳到一个量级。这时候参数就没法拍脑袋了得算。先估总查询量假设合并后的字典是 5 万条已去重要跑 1 个根域总查询量 5 万。再估单查询耗时本地递归解析器开启缓存后命中缓存的查询在 1 到 5 毫秒未命中的要看上游平均下来我按 15 毫秒估。那么单线程 QPS 约 66开 100 并发理论 QPS 是 6600——这个数字明显不现实因为瓶颈很快会转移到解析器的处理能力和网络出口上。更靠谱的估算方式是从实际可承受的外部查询速率倒推。自建递归解析器在普通云主机上稳定跑 800 到 1500 QPS 是没问题的保守按 800 算5 万条查询需要 50000 / 800 ≈ 63 秒。这个数字才是计划依据。如果外部查询速率只有 200 QPS比如受限于上游服务商的限速那 5 万条就要 250 秒四分钟出头。两种情况都能接受真正要避免的是未估算就直接开到几百并发结果被上游判定为异常流量导致整个出口被封一段时间。并发值我一般这么定并发数 目标外部 QPS × 平均查询耗时秒。按 800 QPS 和 0.015 秒算并发 12 就够了但为了防止慢查询把吞吐拖死实际会开到 50 到 100留足余量吸收超时请求。这个公式背后的逻辑是利特尔法则理解了就能自己调不用记具体数字。# 示意带泛解析检测与速率控制的爆破 dns_brute -d example.com \ -w (cat ./dict/level2.txt ./dict/level3.txt | sort -u) \ -c 80 \ -t 2 \ --rate-limit 800 \ --wildcard-detect \ -r ./resolvers.txt \ -o ./out/brute_l2.txt跑的过程中盯两个指标实时 QPS和超时率。QPS 明显低于设定值说明解析器成了瓶颈超时率超过 5%说明并发或速率给大了。这两个指标在多数工具的输出里都能看到看不到就自己加个统计脚本每 10 秒打印一次。4.4 第三轮验证、指纹与去噪前三轮收集完把结果合并去重进入验证阶段。这一步的目标是把一份可能是资产的列表变成一份确认是资产的表格。第一道验证是 DNS 层。把合并后的列表全量重解析一遍记录每条的 A 记录、AAAA 记录、CNAME 链。这里会剔除掉一批第一次查到有、现在没有了的临时记录——DNS 缓存和短暂的记录变更都会造成这种假阳性。同时统计每个 IP 被多少条域名指向指向数量异常高的 IP比如一个 IP 被两百个域名共享大概率是泛解析或负载均衡入口标记出来。第二道验证是泛解析回流。把前面记录的泛解析 IP 集合拿出来凡是解析结果完全落在该集合内的记录全部打上wildcard标记。注意是完全落在如果一条记录解析到泛解析 IP 之外的地址说明它有自己的配置要保留。第三道验证是 HTTP/TLS 层。对保留下来的记录做协议探测抓这几样东西最终状态码、重定向链、页面标题、Server和X-Powered-By之类的响应头、favicon 哈希、TLS 证书的签发者和有效期。这几样组合起来一条记录的性质基本就明确了。去噪的判定规则我整理成了表格实际跑的时候直接套现象判定处理方式解析到泛解析 IP 集合内泛解析产物标记低置信度不进入正式清单CNAME 指向 CDN 厂商域名托管型资产单独归类记录 CDN 厂商解析成功但 HTTP 全部超时可能已下线标记待复核下一轮再看返回统一默认页、标题相同可能是反代兜底按 IP 分组后人工抽检证书过期超过 90 天疑似废弃优先级调高值得清理页面标题含测试维护中非生产环境重点标注风险排序靠前这个表格不是教条不同架构的组织会遇到不同情况。比如用统一网关做入口的架构大量子域解析到同一组 IP、返回同一套响应头这时候按 IP 分组就失去意义了得改成按证书 SAN 分组或者按业务命名前缀分组。4.5 输出规范与持续监控最终产出我建议用 CSV字段固定下来方便导入表格工具或者直接进数据库字段说明示例值fqdn完整域名api.example.comrecord_type记录类型A / CNAMEresolved_ip解析结果203.0.113.10cname_chainCNAME 链lb.example-cdn.nethttp_status最终状态码200title页面标题接口网关tech_stack技术栈线索nginx / 某框架cert_expire证书到期日2025-08-12source数据来源ct,engine,brute_l2confidence置信度高 / 中 / 低first_seen首次发现时间2025-01-01字段定好之后周期性重跑才是这套流程真正产生价值的地方。我的做法是每周跑一次轻量版只跑被动收集加第一层字典每月跑一次完整版。两次结果做 diff输出三类变化新增域名、解析变更、服务下线。新增域名要立刻确认归属因为新上线的资产往往配置不完整解析变更要关注从自有 IP 切到 CDN 的情况那可能是迁移服务下线可以做清理建议把 DNS 记录一并回收。# 简易 diff找出本次新增的域名 comm -13 (sort -u ./out/20241201_final.txt) (sort -u ./out/20250101_final.txt) \ ./out/new_domains.txtdiff 的噪音控制也有讲究。泛解析的 IP 集合每周可能在变如果不把泛解析记录先剔掉就做 diff你会看到几百条新增全是假的。所以 diff 之前必须先执行去噪顺序不能反。5. 常见问题与排查速查5.1 结果数量忽多忽少这是最常见的困惑。同一套字典上周跑出 400 条这周跑出 80 条第一反应是工具坏了其实八成是下面几个原因。上游解析器被限速或临时拒绝。表现是整体耗时没变但结果骤减日志里能看到大量超时。解决办法是换解析器出口降并发重新跑一遍关键部分。本地缓存污染。上一次跑的时候某些域名解析成功缓存还在这次直接命中看起来有结果但如果上一次是泛解析状态缓存里存的其实是泛解析 IP这次泛解析关了缓存没失效结果就不一致。排查方法是查一条已知记录看返回的 TTL 是不是异常小。字典文件被改动了。多人协作时最容易出这种事有人往字典里加了内容或者删了行。养成习惯每轮跑之前先wc -l和校验和记录到日志里。根域的 NS 变了。换了 DNS 服务商之后新服务商的解析行为、限速策略、泛解析默认配置都可能不同。这种情况要重新做一遍泛解析检测。5.2 泛解析干扰的识别与剔除判断是不是泛解析用随机串测试就够了但要注意测试的严谨性。随机串至少要 10 个长度 8 位以上字符集混合大小写字母和数字避免和真实命名撞上。全部解析成功才算泛解析有一部分失败说明用的是部分泛解析或者基于规则的解析比如只对特定前缀返回记录这种情况要单独分析规则。剔除的时候有个容易翻车的地方泛解析返回的 IP 可能不止一个。有的配置会轮询返回一组 IP你只记录了一个剔除的时候就会漏。解决办法是测试时多查几次把返回的 IP 全收集起来形成完整集合再比对。还有一种更隐蔽的情况泛解析返回的 IP 和某个真实子域返回的 IP 完全相同。这时候单看 DNS 没法区分必须靠 HTTP 层的内容差异。我遇到过一整个网段都是这种配置最后是靠页面标题和证书 SAN 才把真实资产挑出来的。5.3 超时、限速与误报的处理超时率高的时候第一反应往往是加并发这是错的。超时率高的本质是系统在告诉你压力太大了加并发只会更糟。正确的顺序是先降速率看超时率是否下降如果降了还是高换解析器换了还高检查本地网络出口是否有丢包。误报的处理要分类型。DNS 层误报记录存在但服务已下线靠 HTTP 验证剔除。内容层误报服务在线但不是目标资产比如共享 IP 上的其他站点靠证书和页面特征判断看证书 SAN 里有没有目标根域。命名层误报字典词恰好是别人的子域比如某些通用词被第三方注册这种其实很少见真遇到了就在字典里加排除项。还有一个隐性问题HTTP 探测的误报来自默认站点。很多服务器配置了默认虚拟主机任何指向该 IP 的域名请求都会返回同一个页面。判断方法是给一个不存在的子域发请求看返回内容和目标记录是否一致。一致就说明是默认站点兜底这条记录要么标记低置信度要么直接排除。5.4 问题速查表症状可能原因排查动作处理建议结果量与字典长度完全一致泛解析随机串测试记录 IP 集合后剔除耗时正常但结果为零字典路径错 / 根域拼错检查文件与参数修正后重跑大量超时并发或速率过高看实时 QPS 与超时率降并发至 50 起步HTTP 全部 403有访问控制看响应头与证书保留记录标注受限标题全相同默认站点兜底用不存在子域对照标记低置信度CNAME 指向陌生域名CDN 或第三方托管查 CNAME 目标归属归类为托管型两次结果差异巨大缓存 / 字典变动对比字典校验和固化字典版本6. 几句实在的踩坑体会6.1 字典质量决定上限工具只决定速度这个结论是我踩了几年坑才认下来的。刚开始做的时候沉迷于找更强的工具换来换去发现结果差不多瓶颈从来不在工具。后来把精力转到字典维护上效果立竿见影。具体做法是每做完一个项目把确认存在的、字典里原本没有的命名补进去标注来源行业。攒了两年字典从一万条涨到四万多条其中大概三成是自建的命中率比通用字典高出一大截。字典维护还有一个技巧记录命名的风格。有的组织喜欢用短横线连接user-center有的喜欢下划线有的喜欢连写usercenter还有的喜欢加数字后缀。同一个组织内部风格通常是一致的发现一种风格之后按这个风格批量生成变体比盲目扩字典有效得多。6.2 数据时效比完整度更重要一开始我追求一次跑全字典越大越好、数据源越多越好跑一次要半小时。后来发现资产梳理这个场景里上周的数据往往比三个月前的完整数据更有用。原因很实际新增资产才是风险集中区老资产大多已经被反复检查过了。所以现在的策略是高频轻量、低频全量。每周一次快速跑覆盖被动源加第一层字典十分钟内完成重点看新增。每月一次全量把长尾补齐。这个节奏下真正需要人工确认的记录数量很少大部分变化都能自动化处理。6.3 合规是底线不是免责声明最后说这个因为它比技术重要得多。我见过太多人把我只查了公开数据当成免责理由实际上主动爆破阶段的 DNS 查询压力是实打实作用在别人系统上的被动收集后的关联分析也可能触及不该碰的范围。合规的做法前面已经说过书面授权、明确范围、限定手段、记录留存。这几件事做了不费什么力气不做的话一旦出问题技术上的所有努力都归零。还有一个实操层面的建议查询结果要当作敏感数据管理。一份完整的资产清单包含内部系统命名、IP 段、技术栈信息泄露出去的风险不比漏洞小。存储加密、访问控制、定期清理该做的都要做。我在项目结束后的习惯是把中间文件清理掉只保留最终清单和日志摘要清单本身按授权约定的期限保存。这套流程跑顺之后一个中等规模的根域从零到一份可用的资产清单大概两个小时其中人工介入的时间不到二十分钟。剩下的大部分时间机器在跑你可以去做别的事。真正花时间的从来不是查询本身是接下来对结果的判断和处置——那部分没有工具能替你做。
返回列表