经常有甲方客户只丢一个主域名过来要求在最短时间内摸清资产暴露面。很多人的第一反应是上扫描器、跑子域探测结果往往跑了一晚上出来一堆“疑似资产”还得人工核对。我自己的习惯是先别急着上工具把搜索引擎和代码托管平台当作第一层侦察入口。Google/GitHub Hacking这套东西听起来像上古老技术但它依然是信息收集阶段性价比最高的路径之一尤其适合把“一次性查询”升级成“自动化监控”让自己从临时打工的信息猎人变成持续盯梢的资产哨兵。这篇文章想聊的就是这条完整的进化路线先讲清楚为什么搜索语法能当侦察工具再分别拆解搜索引擎和代码托管平台的高频语法与实战组合然后用一个最小可落地的自动化监控方案把前面所有查询串起来。最后讲讲我在实操里踩过的坑、反复遇到的问题以及几条关于合规与边界的硬经验。适合正在做授权安全测试、SRC漏洞挖掘、企业资产梳理或者单纯想了解OSINT信息收集思路的朋友参考。1. 信息狩猎的核心逻辑搜索引擎和代码平台为什么能成为侦察入口1.1 搜索引擎替你提前做完了全网索引搜索引擎的本质是一个“已经帮你把全世界网页抓过一遍并建立索引”的数据库。Google Hacking能生效的基础逻辑是无论一个系统藏得多深只要它曾在互联网上以HTML、文件、接口、登录页等形式暴露过且被搜索引擎爬虫收录就能通过特定指纹反查出来。这有点像你去图书馆查资料不用进入每一本书的正文只需要通过目录卡片就能判断哪些书里可能包含你要的信息。对于目标资产来说常见的可识别指纹包括路径结构/admin、/login、/api、页面标题后台、管理、控制台、文件类型.env、.json、.xml、.sql、正文特征password、token、内网地址。只要目标系统出现过这些指纹并且没有被robots协议完全封锁我们就有机会通过搜索引擎反查定位它。这也是为什么很多老牌渗透测试教材里Google Hacking永远是信息收集章节的第一个主题——它成本低、速度快、覆盖面广且不直接触碰目标服务器非常适合做“被动侦查”。1.2 信息猎人与资产哨兵的本质区别“信息猎人”和“资产哨兵”两种模式对应的是两种完全不同的工作方式。信息猎人是单次查询根据一个已知目标构造一组搜索语句收集一批结果然后人工筛选。它的特点是“快而浅”适合项目启动前的快速摸底。资产哨兵则是持续监控把相同的查询语句封装成自动化任务定期执行记录基线检测增量变化一旦出现新的资产、新的泄露信息或新开放的入口立刻通知你。我举一个场景对比某企业在一次授权巡检中团队用一条site:某主域名 inurl:api搜出一批接口路径其中有一个老旧的测试环境还带Swagger文档这就是“猎人模式”的成果。但如果只搜一次就结束三个月后这个测试环境可能又变了、新的测试页面可能又上线了你却不知道。而“哨兵模式”会每天定时跑同样的语句把结果与昨天对比任何新增的URL都会触发告警。所以从信息猎人到资产哨兵的进化核心不是搜索能力变了而是“数据使用方式”变了——从人工看一次结果变成机器持续对比差异。2. 搜索引擎高级语法实战把公开索引变成资产探测雷达2.1 高频语法清单与组合逻辑搜索引擎里的高级语法其实不多真正重要的是组合方式。下面这张表是我自己日常最常用的一组基础语法每个都给出适用场景方便直接照抄。语法作用典型示例site:限制结果来源站点或域site:example.cominurl:匹配URL中出现的关键词inurl:adminintitle:匹配页面标题关键词intitle:后台管理filetype:限定文件后缀类型filetype:envintext:匹配正文关键词intext:password-排除某个关键词site:example.com -www关键词精确匹配完整短语inurl:api/v1AND/OR逻辑与 / 或inurl:login OR inurl:portal组合逻辑的核心原则是“先收窄再扩展”。一开始用site:把范围固定到目标域名这是最稳妥的起手式。然后叠加inurl:或intitle:来定位具体功能模块再通过filetype:筛查文件类型的暴露面。如果结果太少就把条件放宽比如去掉site:换成intext:某产品名看看是否有其他域名下的同款系统。如果结果太多就叠加排除规则把明显无关的内容过滤掉。2.2 典型资产指纹检索示例直接给几条我实际用过、效果不错的语句模板业务类型不同时需要调整关键词但思路是通用的site:example.com inurl:admin定位后台入口国内系统经常有admin.do、admin.jsp、admin.php这类特征。site:example.com intitle:登录 intitle:后台通过标题锁定后台登录页适合目标域名下存在大量低版本OA系统的情况。site:example.com filetype:xml往往能搜出会暴露系统版本、数据库配置、目录结构信息的XML文件。site:example.com filetype:json常见于接口返回结构泄漏某些接口文档或配置备份也喜欢用json格式存放。site:example.com filetype:env这是我一直很看重的一条因为.env文件经常包含数据库口令、应用密钥、第三方服务Token。一旦被收录价值极高。site:example.com inurl:swagger OR inurl:api-docs快速定位接口文档入口拿到接口文档等于拿到目标系统的API地图。搜索时有一点值得注意很多路径特征会同时出现在多个前缀下比如oa.example.com和demo.example.com。搜完之后不要只看结果列表还需要对每条结果做存活性验证。我通常会把结果批量提取出来请求一次HTTP状态码200的标记为有效403/404的暂时放到“潜在资产”队列里等待进一步验证。这个操作看起来不起眼但能过滤掉大量搜索索引里的死链接和缓存旧数据。2.3 搜索结果污染与提纯技巧搜索结果的污染问题可能比想象中严重。常见污染源包括内容农场站、SEO聚合站、第三方平台转载、以及搜索引擎自身的缓存快照过期。搜同一个关键词前10页里可能混杂大量不相干的页面。提纯有几个实操向的技巧第一用多重否定把已知的干扰域名排除。比如-site:baidu.com -site:zhihu.com这类规则虽然看起来原始但在摸某个小众产品的暴露面时非常有效因为这些平台会大量转载相关页面。第二关注结果URL中“看起来不正常”的部分。搜索结果的标题可能被SEO优化过但URL里的目录结构往往最真实。比如一个标题写着“系统登录”的页面URL却是/test/demo/login.php合理猜测这是开发人员的测试模块风险等级要调高。第三利用搜索引擎自带的“时间筛选”功能。很多搜索引擎支持按“过去24小时、过去一周”过滤结果我会在监控巡检时专门跑“近一周新增”的语句因为新上传的文件往往是配置最随意、暴露风险最高的。3. 代码托管平台检索语法在公开代码中定位暴露风险3.1 代码搜索语法速查代码托管平台的搜索语法和搜索引擎不同它面向的是“代码仓库、文件路径、文件内容”这三个维度。以常见的代码托管平台为例高频语法包括语法作用典型示例repo:限定搜索某个具体仓库repo:某开源项目path:把搜索范围限制到某个路径path:.envextension:通过文件扩展名过滤extension:jsonlanguage:限定代码语言类型language:python关键词组合直接搜索文件内容里的关键字aws_access_key_id path:.env用的时候我会把账号的登录态保持住因为未登录状态下代码托管的搜索接口通常只能返回比较浅的结果登录后能搜到的范围明显更大、排序也更合理。同时建议在搜索时做“登录前后对比”如果你发现登录前和登录后的结果数量差异很大说明大量代码仓库对未授权访问做了默认隐藏这是好现象但也意味着搜索结果天然不完整——不要因为搜不到就断定“不存在”。3.2 高危敏感信息检索链在授权安全审计和自身资产暴露面排查里以下几条检索链我重复使用频率最高。每条都是组合语法直接套用再替换成目标特征即可aws_access_key_id aws_secret_access_key extension:json定位直接以明文存放AWS密钥对的JSON文件。搜到之后不要急着“验证有效”先看代码上下文和文件名确认是否属于甲方资产。BEGIN RSA PRIVATE KEY 目标域名搜索私钥文本特征。私钥文件泄露比普通密码泄露严重得多因为一旦私钥匹配到对外开放的服务可能直接导致未授权访问。password 目标域名 extension:yaml常见于各类部署配置、Docker Compose、CI/CD配置文件。mysql:// OR postgres:// 目标域名直接搜数据库连接串包含用户名密码和主机地址能快速定位高风险数据库账号泄露。path:.env 目标域名搜索代码仓库中的.env文件这是在代码托管平台里最值得优先关注的目标。判断信息是否真实有效我需要强调一个原则搜索命中不代表可利用更不代表可以随意使用。正确的判定流程是“看上下文、比对格式、识别归属、再决定是否上报”。比如搜到一个password123456它可能只是测试用例里的占位符但如果你在一个生产仓库的根目录找到了.env且里面包含真实云厂商AccessKey和数据库主机地址那基本可以确认是高危泄露事件。3.3 代码平台搜索的几个翻车点代码托管平台的搜索远没有搜索引擎那么“宽容”实测中常遇到这些问题第一搜索结果上限问题。大多数平台不会把全量匹配结果一次性返回很多查询只显示前100条甚至更少。解决办法是把一个宽泛查询拆成多个细粒度查询比如把password拆成password db_host、password server等多个子查询并行跑降低单条语句匹配量换来更全的结果覆盖。第二内容缩略与定位困难。搜索结果里通常只显示关键词周围的几行代码没法直接看完整文件。我的做法是先把命中的文件路径记下来再通过平台的文件浏览接口单独拉取完整内容而不是停留在搜索页面里猜上下文。第三API限速问题。代码托管平台的API一般都有访问频率限制批量查询时经常遇到429。我自己的处理方式是在轮询脚本里加入随机间隔并把请求错峰打散同时保证每次查询之间至少间隔数秒。不要在同一秒并发几十条查询这样既容易被封限流也拿不到更全的数据。4. 从单次查询到自动化监控搭建自己的资产哨兵4.1 先拆需求哨兵系统到底在哨什么在写任何脚本之前先想清楚“哨兵要监控什么变化”。我习惯把监控对象分成三类搜索索引新增的URL、代码平台新增的敏感文件、以及已有敏感结果的状态变化。对应到具体问题就是目标域名下是不是又多了个登录后台是不是有人新上传了包含密钥的代码文件已发现的泄露配置是否仍然有效监控频率也需要根据场景区分。搜索引擎的爬虫更新相对较慢一天一次或两天一次已经足够代码平台的搜索结果更新较快特别是公开仓库的新提交几乎实时出现对重点目标可以做到每小时一次。不需要追求秒级监控因为信息收集的最终目的是“尽早发现变化”而不是“实时拦截攻击”过高的频率只会带来告警疲劳和被限流封禁的风险。4.2 用Python搭一个最小哨兵轮询快照与差异比对自动化监控的核心思路很简单定期执行查询把结果序列化计算指纹然后与上一次的指纹做比对。指纹相同说明没有变化指纹不同说明出现了新增或消失的结果。下面是一个最小实现骨架真正使用时需要按自身业务替换数据获取逻辑。import hashlib import json import time from pathlib import Path BASELINE_FILE baseline.json def fetch_results(query: str) - list[str]: 执行搜索查询返回结果URL列表。 这里需要替换为搜索引擎或代码托管平台的实际数据获取逻辑 授权范围内使用时注意控制请求频率。 # 示例results search_api(query) results [] return results def snapshot_fingerprint(results: list[str]) - str: 对结果列表生成快照指纹用于后续比对。 sorted_results sorted(set(results)) joined_text \n.join(sorted_results) return hashlib.sha256(joined_text.encode(utf-8)).hexdigest() def load_baseline(): if Path(BASELINE_FILE).exists(): return json.loads(Path(BASELINE_FILE).read_text(encodingutf-8)) return {} def save_baseline(data): Path(BASELINE_FILE).write_text( json.dumps(data, ensure_asciiFalse, indent2), encodingutf-8 ) def notify(query: str, results: list[str]): 自定义告警通知打印、写日志或推送Webhook。 print(f[监测到变化] query{query}, new_results{results}) def watch(query: str, interval_seconds: int 3600): baseline load_baseline() while True: try: results fetch_results(query) current_hash snapshot_fingerprint(results) old_hash baseline.get(query) if current_hash ! old_hash: notify(query, results) baseline[query] current_hash save_baseline(baseline) except Exception as exc: # 捕获异常避免单次失败导致整个监控中断 print(f[任务异常] query{query}, error{exc}) time.sleep(interval_seconds)这个骨架里有三个关键点值得展开说明。第一指纹策略。这里用的是“URL列表排序后整体哈希”。好处是零额外存储、实现简单但缺点是无法区分“新增一条”和“消失一条”。如果要区分增量和减量就把基线改为“结果集合”每次与上一次的结果做差集输出新增列表和消失列表。第二数据持久化。不要把基线只存在内存里否则脚本一旦重启就失去所有历史记录。好习惯是把基线数据落盘为JSON或SQLite文件脚本重启后自动加载继续与旧基线做对比。第三任务编排。上面只写了单个查询词的循环实际工作中至少会有几十个查询词。我在工程化时会把所有查询词放到一个配置列表里循环执行每一个并在两次查询之间加入time.sleep随机延迟既有助于减少对目标搜索服务的压力也能有效规避限流。4.3 告警去重与严重程度标记当监控的查询词慢慢变多告警消息会变得非常多非常容易“狼来了”。我的做法是引入三个去重手段第一结果白名单。把已经确认的问题结果例如某条泄露已经处理完毕或明显不相关的平台结果加入本地白名单比对时直接过滤掉。白名单要允许手动维护因为同一个URL可能会反复触发不同查询词命中。第二多级严重程度。定义三个等级红色包含密钥、明文口令、数据库连接串等直接可利用的信息、黄色后台入口、接口文档、内网地址等中风险信息、蓝色仅包含技术名词、产品名等低风险线索。在通知消息里直接携带等级标签便于人工判断是否立即处理。第三每日聚合。对于黄色和蓝色等级的告警我倾向于合并为每日摘要只有红色等级才实时通知。这样可以大幅减少告警疲劳让真正的高危问题不会被淹没在大量噪声里。5. 边界感与防护视角把狩猎能力反哺给防守方5.1 授权永远是底线讲再多语法和脚本也得先把这条红线摆到最前面。面向公开互联网的信息收集本身是合规的OSINT手段但如果把检索到的敏感信息用于未授权的访问、测试或利用性质就完全不同了。无论是在企业做授权评估、在众测平台提交漏洞还是自己做防御自查都必须确保自己处于明确的授权范围内。我在实际工作中有一条执行守则所有外部目标的查询只做“公开信息层面”的收集与整理任何需要主动连接目标服务器的验证动作都必须先确认书面授权或平台授权允许的范围。所有搜索语法、监控脚本、指纹库都是从“识别暴露与风险”的角度出发而不是从“绕过和入侵”的角度出发。这个边界一旦乱掉再好的技术也是隐患。5.2 用同一套语法做自我暴露面巡检如果你是企业的运维或安全负责人完全可以反向利用这套方法做自我排查。不需要等到外部攻击者通过Google Hacking搜到你家的敏感文件你完全可以自己先搜一遍。做法是把自己的域名、公司关键字、产品名称、代码仓库名全部收集起来套用前面的语法清单定期自查。自查时关注的常见问题包括是否存在未下线但已被索引的测试环境、是否存在包含密钥的公开配置仓库、是否有人私自把内部文档传到公开代码库、旧系统的后台入口是否仍然可被搜索到。这些问题在大量巡检案例中都真实发生过。把监控脚本部署在内部服务器上每周生成一份“外部可见资产面变化”报告同时把白名单和处置记录持续更新进去时间越长这套体系的价值越大。5.3 关键词维护是持续演进的过程关键字库不是一次建完就结束的。新的框架、新的中间件、新的第三方服务会不断出现对应的敏感关键词也要跟着更新。我自己的关键词库结构分两层一层是通用关键词密钥格式、变量名、文件后缀、数据库连接串前缀另一层是专属关键词目标产品的名称、域名缩写、特有的参数名。专属关键词需要从每次巡检结果里反向提炼比如在一次排查中发现了某个系统特有的Session参数名我会把它单独记录用于后续更精细化的查询。6. 常见问题与高价值经验6.1 搜索总是被限流或结果不稳定怎么办搜索引擎和代码托管平台都会对高频自动查询做风控最常见的表现就是某一天还能正常返回大量结果第二天同一语句就只剩少量结果甚至直接出现验证码校验。我的经验是不要在一个IP下用同一个UA高频轮询给每个查询任务设置合理的间隔并用多个查询角度去摸同一类资产而不是盯着一个语句反复刷。还有一个很实用的办法是错峰执行把大规模查询分散到不同时段而不是固定在凌晨同一个点全部跑完。另外结果不稳定还有一个原因是搜索引擎的索引更新本身有延迟。一条新上线的URL可能几天后才被收录一条已删除的URL也可能继续残留在索引里数周。所以看到搜索结果里出现与预期不符的“历史资产”时不必一上来就怀疑关键词写错先做存活性验证再做结论。6.2 代码平台搜不到数据是真的没有还是没搜对代码托管平台的搜索结果比搜索引擎更依赖“关键词的准确性”。我经常遇到新人说“搜不到目标相关数据”结果一看用的是公司简称去搜而代码里的关联信息往往以域名、产品代号、技术栈名称、创始人拼写等形式出现。解决办法就是扩充“搜索词扩展表”把目标域名的不同后缀、目标系统对应的技术关键字、目标产品的英文代号全部作为候选词。很多时候用域名和产品代号能搜到截然不同的结果。另一个常见问题是平台默认搜索的是代码、仓库还是Issues不同标签页的搜索结果差异很大。配置文件、密钥泄露通常在“代码”页里最集中而团队讨论里可能出现的账号信息、调试信息往往在Issues或Discussions里。不要只盯一个入口多个入口都应该纳入监控范围。6.3 告警疲劳怎么治从结果分级开始我再强调一次告警治理的重要性。监控脚本运行一段时间后真正推送的告警里可能80%都是重复信息或低价值信息。如果不去治理过不了两周人就不再看告警了这时候高价值告警也会被一并忽略。我用来缓解告警疲劳最有效的三个手段是结果白名单过滤、严重程度分流、每日摘要兜底。低风险问题每天汇总一次中风险问题每小时汇总一次高风险问题实时推送。同时每两周复盘一次已经处理的问题把“已处置”、“已确认误报”、“属于测试数据”三类结果统一纳入白名单。我个人在实际操作中的体会是这类自动化监控的价值不会在第一天体现出来而是在持续运行三四周之后才真正显现。前面几周几乎都是噪声和数据积累到了第五周突然出现一条新增密钥文件告警并且一眼看过去就知道是真实泄露你会意识到前面所有的磨刀都没有白费。最后分享一个我从这段经验里沉淀下来的习惯每次巡检完把“哪些搜索词命中了、哪些结果被判定为误报、哪些特征值得长期跟踪”更新到自己的关键词管理文件里。这套系统不是一次性项目而是一个持续生长的资产。今天你用半小时搭起来的最小哨兵三个月后会比很多重金采购的商业平台更懂你的目标资产长什么样。