信息收集十技巧:从搜索语法到资产测绘与持续监控
信息收集这件事,我见过太多人把它做成了"关键词搜索大赏":打开浏览器,敲几个词,复制粘贴一堆链接,最后一问"你查到了什么",答不上来。真正做过完整信息收集的人都知道,难点从来不在"搜",而在"知道自己要找什么、找到的东西怎么判断真假、怎么把碎片串成一条能用的线索"。这篇就把我这些年踩坑攒下来的十个技巧完整拆开讲,从零基础能上手的搜索语法,到需要一点脚本能力的资产测绘和持续监控,一条线走完。不管你是做安全自查、竞品调研、行业研究,还是单纯想搞清楚"公开信息到底能挖到什么程度",下面这些方法都能直接拿去用。文章里涉及的所有工具和命令,都只在自有资产或明确授权的范围内使用,这是前提,后面我会反复强调。
1. 先画边界再动手:信息收集到底在收什么
1.1 三类信息,三种完全不同的处理路径
很多人一上手就乱,是因为没给信息分类。我的习惯是先分三类:静态事实类、动态变化类、关系结构类。静态事实指的是域名、IP、备案主体、组织架构、产品型号这类相对稳定的东西;动态变化类指的是端口开放状态、服务版本、页面上线时间、招聘岗位变化这类会随时间漂移的东西;关系结构类指的是"谁是谁的子公司""哪个域名属于哪个业务线""这个人负责哪个项目"这类关联信息。
分类的意义在于决定你怎么存。静态事实适合用表格加字段管理,一个资产一行,字段固定;动态变化适合带时间戳的追加式记录,每次采集都留一条,方便做差异对比;关系结构则适合用图的方式表达,节点和边比表格清楚得多。我早期犯的错就是把三类混在一张 Excel 里,结果查一个端口状态翻了半天,改一次结构全表崩。后面改成"一张资产主表 + 一份变更日志 + 一张关系表"三件套,效率直接翻倍。
这里给一个我常用的资产主表字段设计,可以直接抄:
| 字段名 | 说明 | 示例 |
|---|---|---|
| 资产标识 | 域名或 IP,主键 | api.example.com |
| 归属业务 | 内部约定的一级分类 | 门户站点 |
| 解析地址 | 当前 A 记录 | 192.0.2.10 |
| 开放端口 | 逗号分隔 | 80,443 |
| 指纹 | 框架与版本 | 某 Web 框架 2.x |
| 首次发现 | 日期 | 2024-03-11 |
| 最近确认 | 日期 | 2024-09-02 |
| 来源 | 从哪条线索拿到的 | 证书日志 |
字段不用多,八个足够。多了维护不动,少了后面查不动,这个度是我反复调整三四次才定下来的。
1.2 授权范围这件事,比技术重要一百倍
技术可以学,边界感学不会就容易出事。我的原则很简单:动手前能说清楚"我凭什么查这个",就动手;说不清楚,就停。自有资产、公司明确书面授权的资产、完全公开且不涉及任何个人隐私的公开信息,这三类是安全的。反过来,别人的业务系统、内部系统、任何需要绕过访问控制才能看到的东西,碰都不要碰。
安全自查场景下,我一般会先拉一份授权清单,写清楚范围(域名列表、IP 段)、时间窗口、允许的操作类型(只做被动收集还是允许主动探测)、联系人。这份清单不是形式主义,实际执行时它能救你很多次——比如枚举到某个域名其实属于合作方,清单一翻就知道该跳过。A 同学之前就因为没做这一步,把合作方的测试环境也扫了一遍,虽然最后没造成影响,但解释起来非常被动。
注意:任何主动探测行为之前,先确认授权范围和操作类型。被动收集公开信息(搜索引擎、公开文档)风险最低,主动探测(端口、路径)必须严格限定在授权清单内。
1.3 完整链路:从一个关键词到一份可交付的报告
我把整个流程拆成五步,后面所有技巧都挂在这五步上:定目标 → 铺面(广度收集)→ 收敛(深度验证)→ 关联(拼结构)→ 沉淀(报告与监控)。定目标阶段只干一件事,把"我想知道什么"翻译成可执行的查询条件,比如"我想知道这家公司对外暴露了哪些站点"翻译成"该主体的域名列表 + 子域名枚举 + 端口确认"。
铺面阶段追求覆盖度,宁可多抓,不追求准;收敛阶段反过来,只做验证,每条信息至少两个独立来源交叉确认;关联阶段是把散点连成线;沉淀阶段输出报告并设置监控,让信息能持续更新。这个顺序不能乱,我见过不少人一上来就做深度验证,结果验证了半天发现方向根本不对,白干。
2. 技巧一到三:把搜索引擎用成关系型数据库
2.1 技巧一:语法组合,让搜索框执行查询语句
大部分人用搜索引擎只会输入自然语言,实际上它支持一套相当完整的查询语法。我常用的核心就四个:site:限定站点、filetype:限定文件类型、intitle:限定标题、inurl:限定 URL 路径。这四个组合起来,表达力已经接近一句 SQL 了。
举个例子,想找某个站点上所有对外公开的 PDF 文档,一句site:example.com filetype:pdf就够了;想找后台入口页,site:example.com intitle:"登录"或者site:example.com inurl:admin;想找暴露在外的表格文件,site:example.com (filetype:xlsx OR filetype:csv)。这些查询在自有资产自查里非常好用,经常能翻出一些"以为已经下线其实还挂着"的历史文件。
但语法有个坑:各大搜索引擎的支持度不完全一致,filetype在某些引擎上只认少数几种格式,site对子域名的覆盖也时好时坏。我的做法是同一个查询语句在至少两个引擎上跑一遍,结果取并集再人工筛。另外注意搜索引擎会给结果做个性化,测试时最好用无痕窗口,避免历史记录影响结果。
下面这张表是我常年备着的语法速查,直接拿去改域名就能用:
| 目的 | 查询语句模板 | 备注 |
|---|---|---|
| 摸清站点规模 | site:example.com | 看结果总数做粗估 |
| 找文档类文件 | site:example.com filetype:pdf | 替换 pdf 为 doc/xlsx/ppt |
| 找登录入口 | site:example.com intitle:登录 | 换"后台""管理"再试 |
| 找目录列表 | site:example.com intitle:"Index of" | 命中说明目录未做限制 |
| 找特定路径 | site:example.com inurl:backup | 常见敏感路径词 |
| 找关联站点 | "example.com" -site:example.com | 排除主站看外部引用 |
2.2 技巧二:快照与历史归档,找回已经"删掉"的东西
网页删除不等于信息消失。搜索引擎的快照、公开的网页归档服务,经常能翻到几个月甚至几年前的内容。这个技巧在两类场景下特别有用:一是追溯某个页面什么时候上线、什么时候改版,用来判断业务节奏;二是找已经被删掉的公开信息,比如某份已经下架的产品说明书。
实操上,快照入口一般在搜索结果的折叠菜单里,点进去能看到抓取时间。归档服务则需要你手动提交 URL 查询,它返回的是按时间排列的历史版本列表。我用它做过一次很有意思的复盘:把某站点首页近两年的快照按月拉出来,能明显看出他们的业务重心从 A 方向挪到了 B 方向,比任何官方公告都直观。
要注意的是,快照和归档都不是实时的,抓取频率不稳定,冷门页面可能几个月才抓一次。所以这类信息只能作为"旁证",不能当作"当前状态"来用。我的习惯是:凡是来自快照的信息,在报告里一律标注"历史状态,采集于某年某月",绝不当成现状写。
2.3 技巧三:文档元数据,被严重低估的信息富矿
这是我最喜欢的一个技巧,也是绝大多数人完全忽略的。任何一份由办公软件导出的 PDF、Word、Excel、PPT,内部都带着一份元数据:作者名、创建时间、修改时间、最后保存者、软件版本、公司名称、甚至修订历史。这些东西不在正文里,但信息密度极高。
提取工具用 ExifTool,跨平台、命令行、一行搞定:
# 提取单个文档的全部元数据,按组分类输出 exiftool -a -u -g1 某产品说明书.pdf # 批量处理一个目录,只输出关心的字段 exiftool -csv -Author -Creator -CreateDate -ModifyDate -Producer -CompanyName ./docs > meta.csv-a表示显示重复标签,-u表示显示未知标签,-g1按组分类,这三件套一起用,输出最全。导出成 CSV 之后可以直接进表格做透视,比如统计"哪个作者产出的文档最多""哪批文件的创建时间集中在同一个晚上"。
这个技巧在自查场景下的价值是:你会发现很多对外发布的文件里,带出了内部人员姓名、内部机器名、内网路径、甚至旧版本的项目代号。这些信息本身不算漏洞,但拼起来就是一张组织架构图。处理办法也很简单,对外发布前统一跑一遍元数据清理,ExifTool 一条命令就能批量抹掉:
exiftool -all= -overwrite_original ./publish/*注意:
-overwrite_original会直接覆盖原文件,操作前务必先备份。我一般是先复制一份到临时目录,确认没问题再覆盖正式文件。
3. 技巧四到六:从域名到服务,把资产画出轮廓
3.1 技巧四:子域名枚举,字典和证书两条路并行
主域名只有一个,子域名可能有几百个,真正的资产往往藏在这些子域名后面。枚举方法主流是两条:字典爆破和证书透明度日志反查。前者靠词表穷举,覆盖面取决于词表质量;后者利用的是公开的证书签发记录——任何为某个域名签发的证书都会留一条公开记录,里面包含完整的域名,这条路的准确率极高,而且完全被动。
我的实际做法是两条路并行,结果取并集再验证。证书日志这条先跑,因为它能拿到一些字典里根本想不到的命名,比如带业务代号、带地区缩写的子域名;字典爆破作为补充,词表我一般准备三份:通用词(www、mail、api、test、dev)、业务词(从目标公开信息里提取的产品名)、缩写词(地区、部门缩写)。三份叠加,命中率明显比单一通用词表高。
给一段可以直接跑的脚本,逻辑是读取词表、并发解析、只输出有解析结果的:
import concurrent.futures import socket BASE = "example.com" # 换成自有或已授权域名 WORDS = ["www", "mail", "api", "test", "dev", "admin", "static", "cdn"] def resolve(word): host = f"{word}.{BASE}" try: return host, socket.gethostbyname(host) except socket.gaierror: return host, None if __name__ == "__main__": with concurrent.futures.ThreadPoolExecutor(max_workers=20) as pool: for host, ip in pool.map(resolve, WORDS): if ip: print(f"{host}\t{ip}")并发数别开太大,20 到 30 足够,开太大对本地 DNS 压力大,反而容易误判成"不存在"。另外一定要区分"解析失败"和"解析超时",前者是真的没有,后者是网络问题,混在一起会把有效资产漏掉。我在脚本里加了个重试逻辑,超时的单独重试两次再判定,误判率降得很明显。
3.2 技巧五:端口与服务,先确定范围再谈细节
资产清单有了,下一步是看每个资产对外提供了什么服务。这一步的争议最大,因为它属于主动探测,必须严格限定在授权范围内。我的做法是先定一个小范围验证跑通,再逐步扩面:先挑 3 到 5 个资产做全端口扫描,摸清这个环境的端口分布规律;然后根据规律确定一份常用端口清单(比如 80、443、8080、8443、22、3306 这种),对全量资产做定向扫描,速度快、噪音小。
命令示例,只扫常见端口、只显示开放的、带版本探测:
# 仅限自有或已授权资产 nmap -sV -Pn --open -p 80,443,8080,8443,22,3306 -iL assets.txt -oX result.xml-sV做版本探测,-Pn跳过主机存活判断(很多设备禁 ping),--open只输出开放端口,-iL从文件读目标,-oX输出 XML 方便后面写脚本解析。这几个参数是我反复试出来的组合,比默认参数省一半时间。
扫描结果不要只看"开了哪些端口",重点看三件事:不该开的开了没有(比如内部管理端口暴露在公网)、版本是不是明显偏旧(旧版本往往意味着缺少安全更新)、同一服务在不同资产上的版本是否一致(不一致说明更新不同步,运维有盲区)。这三点比端口列表本身有价值得多。
3.3 技巧六:指纹识别与版本比对,把"是什么"变成"差在哪"
端口告诉你"这里有个服务",指纹告诉你"这个服务是什么、什么版本"。指纹识别的方法很多,最直接的是看 HTTP 响应头里的Server、X-Powered-By字段,其次是看页面特征(特定路径、特定静态资源命名、特定 Cookie 名),再次是看报错页面的特征字符串。三层叠加,准确率很高。
拿到指纹之后真正有价值的是比对。我会维护一份"当前主流稳定版本"的对照表,把扫到的版本往里一套,立刻能看出哪些偏旧。这一步的意义在于把技术语言翻译成业务语言——"某框架 1.x"这种描述没人听得懂,"这个版本已经停止维护两年,社区不再发布安全更新"这种描述,业务方一听就懂,优先级立刻排上来了。
指纹信息还有个用法是做资产归类。同一个框架、同一套静态资源命名规则,往往意味着同一个开发团队或同一套模板。把几百个资产按指纹分组,能快速看出"哪些是自研的、哪些是采购的、哪些是历史遗留的",后面做整改排期的时候,按组处理比按个处理效率高一个量级。
4. 技巧七到九:代码、人员与关系的三维拼图
4.1 技巧七:公开代码仓库的泄露自查
代码托管平台是信息泄露的高发区,也是最容易被忽略的地方。常见的问题有几类:配置文件里写死了访问密钥、注释里留了内部地址、测试代码里带了真实数据、提交记录里出现了内部项目名。这些内容一旦公开,价值比一个端口开放大得多。
自查的方法:先在平台上按组织名搜一遍所有公开仓库,再用关键词扫一遍代码内容。关键词清单我一般准备这些:password、secret、token、apikey、access_key、jdbc:、mongodb://、redis://、内部域名后缀、内网 IP 段前缀。搜到之后逐条人工确认,是测试用的占位符还是真实凭据。
# 克隆下来的仓库里做一次粗糙的敏感词扫描,仅用于自有仓库自查 grep -rniE "(secret|token|apikey|access_key|password)\s*[:=]" ./repo \ --include="*.py" --include="*.js" --include="*.yaml" --include="*.properties" \ | grep -viE "(example|placeholder|your_|xxxx|<.*>)"最后那个grep -v是过滤掉明显的占位符,不然结果里全是password: your_password_here这种噪音,看几百条也看不到真东西。这个过滤规则是我踩了几次坑才总结出来的,能砍掉八成无效命中。
还要注意提交历史。很多人只清理了当前版本的代码,忘了历史提交里还留着。查历史用git log -p配合关键词搜,或者用git log -S"关键词"精确查找引入和删除某段内容的提交。这块工作量不小,但真查出过东西,值得做。
4.2 技巧八:人员与组织的公开信息梳理
这条要格外小心,我只讲公开、合规的部分。组织层面,公开渠道能拿到的信息包括:官方发布的组织架构说明、公开的招聘岗位(岗位描述往往透露技术栈和业务方向)、公开的新闻稿和行业会议资料。这些信息拼起来,能大致还原一个组织的业务布局和技术偏好。
人员层面,我只做"角色级"梳理,不做"个人级"挖掘。也就是说,我关心的是"这个项目由哪个团队负责",而不是"某个具体的人住哪、用什么账号"。这个界限必须守住,越过这条线,技术问题就变成了伦理问题。实操上,招聘信息是最好的切入点:连续几个月在招同一个岗位,说明这个方向在扩张;岗位描述里点名某个技术栈,说明现有系统在往那个方向迁。
A 同学之前做过一次很典型的分析:把某公司一年内发布的招聘岗位按时间排序,能清楚看到他们的技术栈从一套方案切到另一套方案的完整过程,中间有大约三个月的重叠期,正好对应系统迁移窗口。这个结论完全来自公开信息,没有任何越界操作,但信息价值非常高。
4.3 技巧九:图谱化,把一百条碎片压成一张图
信息收集到后期,最大的痛苦不是找不到,而是太多、太散、理不清。这时候必须做图谱化:把每条信息抽象成"节点"或"边",节点是实体(域名、IP、组织、产品),边是关系(解析到、属于、使用、关联)。做完之后你会发现,原本一百条孤立记录,其实只有十几个核心实体和二十几条关系。
工具上不用追求复杂,一张白纸加笔就能开始画,规模大了再用图形化工具。关键是养成"每收集一条信息,立刻问它连到谁"的习惯。比如拿到一个新子域名,立刻问:它解析到哪个 IP?这个 IP 上还有别的域名吗?这个 IP 属于哪个网段?网段里还有哪些资产?四个问题问完,一条信息就变成了一个小网络。
图谱化还有个隐藏好处:它能帮你发现"信息缺口"。图上某个节点只有一条边连进来,说明这个实体的信息还不完整,值得再挖一轮;某个区域节点密集但边很少,说明这里的信息都是孤立的,需要找关联线索。这种"看图找洞"的方式,比自己拍脑袋想"还该查什么"高效得多。
5. 技巧十:持续监控,让信息自己长出来
5.1 监控脚本:把一次性采集变成周期性对比
信息是有保质期的,今天扫出来的端口列表,一个月后可能就过时了。所以最后一个技巧是把前面的采集动作自动化,定期跑一遍,只输出"变化的部分"。核心思路很简单:每次采集结果带时间戳存一份,跟上一份做 diff,差异就是你要关注的。
一段可以直接用的对比脚本,先做归一化排序再比,避免因为输出顺序不同产生假差异:
import sys def load(path): with open(path, encoding="utf-8") as f: return sorted(line.strip() for line in f if line.strip()) old = set(load(sys.argv[1])) new = set(load(sys.argv[2])) for item in sorted(new - old): print(f"[新增] {item}") for item in sorted(old - new): print(f"[消失] {item}")归一化和排序这两步千万别省。我最早没做排序,每次 diff 出来几百条"变化",逐条看完发现全是顺序差异,白折腾一晚上。加上排序之后,真正的变化通常只有个位数,一眼就能看完。
监控频率看资产的重要程度,核心资产一周一次,边缘资产一月一次。告警阈值也要设,比如"单次新增超过 20 条"就触发人工复查,因为突然大量新增往往意味着环境变动或者采集出错,两种情况都值得看一眼。
5.2 报告怎么写才有人看
收集了一堆信息,最后交付如果是一份流水账,等于白干。我的报告结构固定四段:结论先行、证据在后、风险分级、建议可执行。第一段永远是最重要的三五条结论,用业务语言写,不用技术黑话;第二段放支撑证据,每条结论对应哪几条信息,标注来源和采集时间;第三段按影响面分级,高优先级的不超过五条;第四段给具体动作,写清楚谁在什么时间做什么。
有个细节特别重要:每条信息都要标来源和采集时间。这不是形式主义,是为了让别人能复核。我见过太多报告,结论写得斩钉截铁,一问"这个数据哪来的",答不上来,整份报告的可信度就没了。标注来源还有个好处,当信息过期时,你能快速定位到需要重新采集的那几条。
报告长度控制在五页以内,超过五页没人看。详细的原始数据放附件,正文只放结论和关键证据。这个取舍我调整过很多次,最后发现"薄正文 + 厚附件"是唯一可行的结构。
6. 踩过的坑和一张速查表
6.1 十个典型问题与处理办法
下面这张表是我这些年实际遇到过的坑,按出现频率排序,遇到问题先查这张表,能省不少时间:
| 现象 | 常见原因 | 处理办法 |
|---|---|---|
| 搜索语法没结果 | 引擎不支持该语法组合 | 换引擎重试,拆分条件逐个验证 |
| 子域名枚举漏掉很多 | 只用了通用词表 | 补证书日志反查,加业务词词表 |
| 端口扫描结果忽多忽少 | 目标有防护设备限速 | 降低并发,分时段多次采集取并集 |
| 指纹识别不准 | 响应头被改过或为空 | 叠加页面特征和报错页判断 |
| 元数据提取为空 | 文件已被清理过 | 找早期版本或归档版本再试 |
| 差异对比全是噪音 | 没做归一化排序 | 排序后比对,固定输出格式 |
| 快照信息误导判断 | 把历史状态当现状 | 一律标注采集时间,只作旁证 |
| 敏感词扫描误报多 | 过滤规则不够 | 加占位符过滤,人工二次确认 |
| 信息太多理不清 | 没做图谱化 | 抽实体抽关系,先画后补 |
| 报告没人看 | 结论埋在细节里 | 结论前置,正文压到五页内 |
6.2 几个能立刻提升效率的小习惯
第一个习惯:每采集一条信息,立刻记下"来源 + 时间 + 可信度"。可信度分三档:直接观测(自己跑出来的)、公开声明(官方发布)、间接推断(从别的信息推出来的)。这三档在报告里的分量完全不同,混在一起写会出事。
第二个习惯:建一个"待验证"清单。收集过程中一定会遇到互相矛盾的信息,比如两个来源对同一个 IP 的归属说法不一致。别急着下结论,丢进待验证清单,等有第三个来源再判。我现在的清单里常年躺着十几条,有些过了半年才被证实,但证实的那一刻价值极大。
第三个习惯:工具输出一律存原始文件。不管是扫描结果、搜索结果还是脚本输出,都存一份原始的,别只留处理后的。原因很简单,你永远不知道后面会不会需要换个角度重新分析同一批数据,有原始文件就能重跑,没有就得重新采集。
注意:所有采集到的原始数据都要按敏感级别管理,涉及内部资产的信息不要随手丢在公共网盘或聊天群里。这条看起来是常识,但实际出事的大部分都是这一类。
最后分享一个我自己一直在用的取舍标准:当你不确定某条信息该不该收、某个操作该不该做的时候,问自己一句"如果这件事被完整地公开说明,我能不能坦然解释"。能,就做;犹豫,就先放一放,去找更合规的替代路径。信息收集这门手艺,技术上限决定你能挖多深,边界感决定你能走多远,后者比前者重要得多。