直接说结论这是个让我又爱又恨的话题。爱的是一套搜素语法配合自动化脚本就能在几分钟内完成平时需要一整天的人工排查恨的是很多人误以为它是什么“黑客神器”把方向带偏了。实际上Google Dorking也叫Google Hacking就是利用搜索引擎的高级搜索指令对互联网上公开可访问的信息做定向检索——仅此而已。它的价值在于信息收集阶段帮你精准定位目标无论你是做渗透测试、资产梳理还是企业安全自查这套技能都属于基本功里的基本功。这篇文章我不讲虚的直接说清楚三件事一是这些搜素语法背后的原理是什么二是怎么把一个重复性的人工搜索过程封装成自动化工具三是真正落地部署时会遇到哪些坑、该怎么解决。适合正在学习安全测试的入门者、负责企业资产梳理的运维同学以及想提升自查效率的安全工程师参考。1. 整体设计与思路拆解1.1 为什么需要自动化而不是手动搜索很多人第一次接触Google Dorking是在搜索引擎里手动输入类似inurl:admin或filetype:sql这样的指令。手动搜索的问题很明显一次只能执行一个查询要换关键词就得重新输入、重新翻页而且搜索结果会动态变化同样的语法过两个小时再搜结果页可能完全不同。真正需要批量做信息收集的时候比如给某公司做资产梳理要检测几十个域名下是否有暴露的管理后台、敏感配置文件、测试环境入口手动操作能让人直接崩溃。这时候自动化的价值就体现出来了把搜索任务写成配置文件脚本按照既定规则逐个执行查询再对结果做去重、分类、标记最后输出结构化的报告。整个过程不需要人为干预速度也远超手动操作。我见过一些团队的自动化方案本质上就是一个Python脚本不断调用搜索接口。但这里有个需要提前说明的问题非官方接口并不可靠而且容易触发风控。更稳的做法是用官方提供的API或者干脆结合爬虫框架自己抓取结果页并做解析。下面我会逐个对比这些方案的优劣。1.2 工具的核心组成一个完整的自动化工具至少要包含以下模块第一是查询规则管理模块。你需要把常用的Dork语法整理成可配置的规则文件比如JSON格式每条规则包含查询语句、适用域名、优先级、备注说明。这样团队里的成员共享规则时不需要改代码改配置就行。第二是查询执行引擎。这个模块负责接收规则拼接搜索请求发送HTTP请求并获取结果页面。这里需要处理的关键细节包括请求头伪装、超时控制、重试策略以及结果页面的编码识别。第三是结果解析与清洗模块。从搜索结果页提取URL、标题、摘要信息并过滤掉明显无意义的结果比如搜索引擎自家的页面链接、广告位。这一步考验的是对HTML结构解析的熟练程度不同搜索引擎的页面结构差异很大解析规则往往需要单独适配。第四是报告生成模块。把清洗后的结果按规则分类、去重生成便于阅读的报告可以是纯文本、CSV也可以是简单的HTML页面。报告里最好包含命中规则的说明和建议的处理方案方便直接分发给业务方。1.3 技术选型Python是首选做这类工具Python几乎是共识性选择。原因有三点一是生态成熟requests、BeautifulSoup、lxml这些库把HTTP请求和解析工作简化了不少二是胶水特性好后续想接入企业微信通知、定时任务或者数据库存储都不需要换技术栈三是调试方便交互式环境里直接跑片段就能验证逻辑。有些人会纠结要不要用Go或者Node.js。Go的并发能力强适合大规模并发查询场景但这类工具受限于目标搜索接口的风控策略并发太高反而容易被封所以Go的性能优势在这里发挥不出来。Node.js的异步模型也适合爬取但Python在数据处理和文本清洗上的便利性更强。所以结论很简单老老实实用Python除非你有极其特殊的需求。2. 核心语法解析与工具设计细节2.1 高频Dork语法逐个拆解网上流传的Dork语法清单数量巨大但大部分人连核心的十几个指令都没吃透。我按使用频率和重要性把最常涉及的那批语法整理成了表格并补充了使用时的注意点指令作用典型场景常见误区site:限定搜索域名或子域名检查某域名下被搜索引擎收录的页面容易忽略端口非标准的情况site:无法覆盖非80端口页面inurl:匹配URL中包含的关键词查找目录路径特征明显的页面如inurl:admin过于宽泛的关键词会引入大量噪声intitle:匹配页面标题中的关键词查找标题特征明显的页面如前台上传组件中文站点的标题乱码会影响命中率filetype:限定文件扩展名查找配置文件、数据库备份、日志文件搜索引擎对部分扩展名支持有限intext:匹配页面正文文本查找包含特定敏感字符串的页面和网站关键词叠加时容易漏结果cache:查看搜索引擎缓存版本分析已下线页面曾经的内容该指令在部分搜索引擎中已经失效link:查找指向某URL的外部链接辅助评估外链情况该指令在Google已基本停止服务说几个容易被忽略的细节。第一site:和非标准端口的关系——很多内网管理系统通过8080、8443端口对外提供服务但搜索引擎默认只收录80端口的页面所以光用site:example.com是搜不到https://example.com:8443/admin这种页面的。想覆盖这部分资产需要配合目标IP的网段搜索或者改用证书透明性日志来收集。第二filetype:的搜索结果是被搜索引擎主动收录的文件如果服务器配置了爬虫排除协议禁止收录敏感目录那么filetype:sql就搜不到对应文件——这本身是一个防御性信号说明对方运维水平在线。2.2 搜索结果页面结构分析与解析策略自动化工具绕不开的问题就是处理搜索结果页的HTML结构。这里有个所有做爬虫的人都懂的道理页面结构随时可能变解析代码的生命周期永远比预期短。以Google的搜索结果页为例触发布局调整后整个HTML结构和类名可能完全改变。一次搜索页面里通常包含搜索结果区、右侧知识面板、顶部的推荐链接还有一些非搜索内容。解析时建议遵循的原则是优先定位结果容器不要试图逐条解析而是找到包含所有结果的父节点再遍历子节点提取链接和标题。提取链接时注意去除搜索引擎的跳转包裹参数避免拿到一串带跳转参数的URL。结果的摘要部分往往包含关键信息但HTML结构相对复杂建议使用lxml的XPath而不是正则字符串匹配抗干扰能力更强。如果使用选择器定位失败第一时间检查页面是否返回了验证码页面或者要求登录的页面这是被风控的典型信号。不少初学者会把搜索结果解析做得过于脆弱依赖某个特定的类名。我的建议是做一个多级降级策略优先用最新已知的选择器解析失败时尝试用特征链接片段定位再不行就把整页文本抓出来用正则粗略匹配链接。虽然不够优雅但能保住可用性。2.3 查询规则的配置与版本管理规则文件是整个工具的灵魂。设计规则文件时我推荐这种结构{ task_name: example_asset_review, target: example.com, rules: [ { id: R001, description: 检测暴露的管理后台入口, dork: site:{domain} inurl:admin, risk_level: high, handler_note: 如果命中请及时联系系统管理员确认是否需要登录保护 }, { id: R002, description: 检测数据库配置文件, dork: site:{domain} filetype:env, risk_level: critical, handler_note: 环境变量文件泄露可能导致大量密钥外泄 } ] }规则里用占位符模板执行时动态替换成实际的目标域名。这个设计最大的好处是规则可以在不同目标之间复用不用每个资产都复制一份配置。规则文件的版本管理也很重要。我见过有人把规则直接写在代码里后来规则越加越多代码已经没法看了。正确做法是把规则文件单独放入Git仓库管理每次更新都记录变更原因执行的时候锁定特定版本保证结果可回溯。这一点在多人协作的时候特别有价值——你自己改了规则别人不知道跑出来的结果对不上排查半天才发现是规则不同。3. 自动化工具部署与实操实现3.1 环境准备与基础依赖部署环境以Linux为主Ubuntu或CentOS均可。Python要求3.8以上版本太老的话一些类型注解和特性用起来会受限。依赖库方面我会先建一个虚拟环境避免污染系统Python环境python3 -m venv dorkenv source dorkenv/bin/activate pip install requests beautifulsoup4 lxml python-dateutil需要说明的是如果通过常规渠道无法顺利安装这些库可以配置国内或本地镜像源来加速或者使用离线安装包这些都属于常规运维操作就不展开讲了。3.2 查询执行引擎的实现思路执行引擎是整个工具的核心。我写了一个简化版的实现思路重点不在于代码本身而在于理解请求调度和异常处理的逻辑import time import requests from bs4 import BeautifulSoup class DorkEngine: def __init__(self, delay2, timeout15): self.delay delay self.timeout timeout self.session requests.Session() self.session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36, Accept-Language: zh-CN,zh;q0.9,en;q0.8 }) def search(self, query, domainNone): if domain: query query.replace({domain}, domain) params {q: query, num: 20} try: resp self.session.get( https://www.example-search.example/search, paramsparams, timeoutself.timeout ) resp.raise_for_status() except requests.exceptions.RequestException as e: print(f查询 {query} 失败: {e}) return [] return self._parse_results(resp.text) def _parse_results(self, html): soup BeautifulSoup(html, lxml) results [] # 定位搜索结果容器 for item in soup.select(div.result-item): link_tag item.select_one(a.result-link) if not link_tag: continue title link_tag.get_text(stripTrue) url link_tag.get(href) # 去除跳转包裹参数保留真实链接 url self._clean_url(url) if url: results.append({title: title, url: url, source: dork_search}) return results def _clean_url(self, url): # 避免带上搜索跳转中间层 if url.startswith(/url?q): url url.split()[0].replace(/url?q, ) return url注意上面代码里我使用了“example-search.example”作为占位域名实际部署时需要替换为真正使用的搜索引擎地址。不要纠结于具体URL因为不同搜索引擎的结构差异很大重点是理解思路通过构造请求参数发送查询、用解析库提取结构化数据、处理异常和反爬策略。3.3 并发与限速的平衡策略这是自动化工具里最容易被低估的部分。很多人觉得脚本跑得越快越好结果跑不了多久IP就被封了甚至影响同网段的其他业务。我自己踩过几次坑之后总结出一套比较稳妥的限速策略单任务并发线程数控制在3个以内过多的并发只会换来更快的风控响应。请求间隔至少设置2秒宁可慢一点也不要冒进。同一个线程循环执行查询时建议每次查询后随机睡眠0.5到2秒增加请求时间间隔的自然度。如果检测到返回的页面结构异常立即停止当前任务并等待5分钟以上再重试不要继续硬扛。这个策略看起来保守但考虑到这类工具通常属于内网安全常态化运营的一部分稳定比速度重要。真正需要大规模查询时可以通过分布式定时任务把查询分散到一天之内完成而不是一次性打完所有子弹。3.4 结果去重与风险评估输出搜索结果必然存在大量重复项尤其是当多个规则查出来的页面有重叠时。去重逻辑要做好两层一是URL级别的去重去掉协议、末尾斜杠、锚点等干扰因素二是内容级别的去重通过页面标题和摘要的相似度判断是否是同一资源的不同入口。风险评估输出方面规则配置里的risk_level字段就是用来做排序和分流的。命中critical级别的结果比如数据库备份文件、环境变量配置直接生成高优告警high级别的整理成待办列表medium及以下级别按月汇总即可。我在实际项目中会把输出格式设计成CSV方便安全团队直接导入工单系统。CSV字段建议包含规则ID、规则描述、命中URL、页面标题、时间戳、风险等级、备注说明。4. 常见问题与排查技巧实录4.1 搜索请求返回异常或者无法访问这是所有爬取类工具都会遇到的问题。排查思路如下第一步确认目标搜索服务是否可达。用浏览器直接访问一下看看是全面不可用还是只是对当前出口IP不可用。如果浏览器正常但脚本异常大概率是请求头或请求参数的问题。第二步检查请求头。部分搜索服务会校验User-Agent、Accept-Language、Cookie等信息。用浏览器开发者模式复制自己正常的请求头信息逐项比对。第三步查看返回内容。如果返回的是一个要求人机验证的页面说明当前IP已经被风控。处理办法包括更换出口IP、降低请求频率、等待风控解除。这里需要多说一句出口IP属于网络基础设施层面的问题不同环境的解决方案差异较大建议根据自己所在网络的实际情况处理。4.2 解析结果为空但浏览器搜索有结果这种情况比较隐蔽代码没报错请求也成功了就是拿不到任何数据。原因通常是页面结构变化或者搜索引擎针对脚本请求返回了一个不同的页面变体。我的排查经验是先把返回的HTML文本保存到本地文件然后用浏览器打开这个文件看看实际页面内容和代码解析的目标是否一致。我遇到过的情况是页面里确实有结果但结果被包裹在一个动态加载的容器中必须通过额外的JavaScript请求才能获取。这种情况就不是单纯的静态解析能解决的了需要分析接口并模拟后续请求。4.3 规则命中的结果太少或者噪声太大结果太少通常是查询语句过窄。比如site:example.com intitle:index of这种组合如果目标站点是单页应用搜索引擎收录的页面本来就不多结果当然少。这时可以拆开查询分别看site:、intitle:各自的命中情况再逐步组合。噪声太大一般是关键词太宽泛。比如inurl:login不加域名限定能匹配出几万个页面大部分跟目标毫无关系。优化手段就是叠加限制条件用site:先框定范围或者用intext:配合业务特征词来收窄。另外规则里的关键词尽量使用目标企业域名、系统名称、开发框架特征等专有信息而不是通用词汇。4.4 定时任务的坑与持续运营维护工具写好了不代表完了持续运营才是重点。做定时任务时我建议直接在Linux上用cron实现配置简单且足够可靠。使用cron有几个需要注意的地方。一是环境变量差异cron执行时的环境比交互式shell精简很多脚本里用到的PATH必须显式设置。二是日志输出要重定向到文件方便排查执行失败的原因。三是配合flock或类似机制防止任务重叠如果上一个任务还没执行完下一个任务不应该并发启动。# 每天凌晨3点执行资产扫描锁定防止重叠 0 3 * * * /usr/bin/flock -n /tmp/dorkscan.lock /opt/dorkenv/bin/python /opt/dorkscan/main.py /var/log/dorkscan.log 21flock -n的含义是如果锁文件被占用就不执行本次任务这样即使某次扫描因为网络问题耗时超过了24小时也不会出现多个进程互相打架的情况。5. 合法合规使用与防御视角5.1 可以做什么不可以做什么展开讲讲边界问题这一点极其重要。利用搜索引擎收集公开信息是安全行业的常见做法但这套技术同时也可以被用于恶意目的。以下行为属于典型的不可接受用途未经授权扫描并尝试登录他人系统、收集并利用他人泄露的凭证信息、对非本人或非授权范围内的系统进行大规模探测、用收集到的信息进行钓鱼攻击。从我个人的建议来说这套自动化工具最适合的使用场景是对自己负责的业务系统做常态化的暴露面自查、在获得明确书面授权的前提下对目标系统进行安全评估、配合法务合规团队进行数据暴露风险监测。其他用途都不要碰。5.2 企业如何防御Dork层面的信息暴露既然聊到了防御面我把常见的信息暴露场景和对应的检查、修复手段也整理一下风险类型典型Dork示例修复思路管理后台暴露site:example.com inurl:admin管理后台增加IP白名单限制非办公网络不可访问备份文件泄露site:example.com filetype:bak禁止备份文件存放在Web根目录使用独立的备份存储区域配置文件泄露site:example.com filetype:env敏感配置放入环境变量或保密管理系统禁止写入公开目录错误页面泄露site:example.com intitle:index of关闭目录浏览功能配置默认页面测试环境暴露site:test.example.com测试环境必须与生产环境隔离禁止对外网开放每个企业的情况不一样单纯的清单并不能覆盖所有问题。但自动化工具的价值恰恰在于持续监测——你不需要一次性解决所有风险只需要定期扫描、增量对比、跟踪修复进度。安全是一个持续过程不是一次性的交付。5.3 引入团队协作与流程规范工具单机跑和团队协作跑完全是两回事。如果你负责安全团队的基础工具建设建议在设计阶段就考虑好以下问题查询结果是否需要持久化存储我建议把历史结果存入SQLite或MySQL这样月度对比、趋势分析和问题回溯都有据可查。多人同时跑同一个任务如何避免重复且浪费资源引入任务状态机制同一任务在同一时间段只允许一个执行实例其他成员可以查看历史结果。命中高优规则后的通知路径是什么可以对接即时通讯机器人或邮件服务第一时间通知相关责任人而不是等人手动来看报告。规则的更新审核机制怎么做建议专人负责规则库的维护和更新每次变更记录原因和影响范围避免误报和漏报被忽视。这些看起来是工程管理问题实际上直接影响工具价值的发挥。一个成熟的安全团队工具必须是可追溯的、可协作的、可验证的而不是某个人电脑角落里的一个脚本而已。6. 扩展方向与个人体会6.1 从Dork工具到资产测绘平台我最早做这类工具只是为了不用手动复制粘贴搜索多轮语法。后来做了一段时间发现单纯的搜索结果已经不能满足需求因为搜索索引存在滞后很多重要资产根本不会被收录。于是我把工具扩展成了资产测绘小平台通过证书透明度日志、子域名枚举、爬虫外链分析等方式结合Dork搜索最终构建出一个相对完整的暴露面视图。这个过程让我深刻体会到一个原则工具是死的思路是活的。Dork自动化的本质是做信息的定向聚合那么所有能产生目标信息的来源都可以接入进来。搜索引擎能提供一部分数据被动DNS、证书日志、自己搭建的爬虫任务都能提供另一部分数据。把这些数据源统一清洗、去重、汇总价值远大于任何一个单一来源。6.2 我踩过的几个坑写这类工具的过程中有几个坑印象特别深刻分享出来供参考第一个坑是死磕解析器。早期我想把一种搜索结果的解析做到极致不断调整选择器来匹配页面结构的每次变化。后来想通了页面结构随时变解析器再健壮也赶不上前端改版的速度。不如把精力放在合理的降级策略和人工复核流程上自动化帮你完成80%的工作剩下20%交给人工判断效率和稳定性反而是最好的。第二个坑是忽略数据存储早期工具跑完结果打印在控制台里就完了复盘的时候根本找不到之前的扫描结果用于对比。后来强迫自己养成每次执行都落库的习惯哪怕只是存成CSV文件也胜过没有历史数据。现在再做任何自动化扫描工具存储设计一定是第一步就规划好。第三个坑是没有考虑规则变更的影响。规则一处更新前后结果没有可比性追踪修复进度时陷入混乱。现在的做法是执行时记录规则文件的哈希值或版本号这样任何结果的差异都能追溯到规则变更问题定位就清晰了。6.3 写在最后的操作建议如果你是一个刚接触这个领域的新人我建议你先不要急着写自动化脚本。把常用的Dork语法挨个手动搜索一遍理解每一种语法的搜索意图、结果特征和局限性。这个过程会为你后面设计规则提供很好的直觉。等手动操作熟练了再开始自动化你会发现很多设计上的问题不再需要琢磨测试因为你对结果预期已经有了清晰的判断。甚至对于一些中小型项目手动操作加一个简单的脚本去解析结果页可能比一上来就搞一个完整框架更实用。工具复杂度应该跟实际需求匹配过度设计往往带来的是更重的维护负担。最后再分享一个小技巧做这类工具时一定要把日志做扎实。请求的目标查询、返回状态码、解析结果条数、耗时、失败原因这些都记下来。调试和排查问题的时候日志就是你的眼睛。我之前排查一个解析为零的问题就是靠着返回页面的大小变化正常页面大约60KB被风控时只有4KB左右发现是安全验证拦截而不是解析代码的问题。有些经验只能从真实反馈里获得日志就是最快帮助你得到反馈的渠道。
阅读完成 · 觉得有帮助?