Python Web安全工具开发(十一):信息收集之高级子域名枚举(搜索引擎篇
摘要:在本文中,我们将利用地球上最强大的信息索引——搜索引擎,来为我们的子域名枚举工具增添“情报搜集”能力。我们将深入探讨“Google Hacking”技术,特别是利用site:搜索操作符来挖掘一个主域名下所有被搜索引擎索引到的子域名。我们将使用googlesearch-python这个第三方库来自动化地执行搜索查询,并编写一个Python模块来解析搜索结果,从中提取出宝贵的子域名信息。这是一种极其高效的被动侦察方法,能够发现大量在公开网络上活跃的、有真实业务的子域名。
关键词:Python, 子域名枚举, 搜索引擎, Google Hacking, site:, 被动侦察, Web安全, Scrapy
正文
到目前为止,我们已经拥有了两种发现子域名的武器:
-
字典爆破:主动猜测,可能发现未公开的域名,但有流量特征。
-
证书透明度日志:被动查询,能发现申请过证书的域名,非常隐蔽。
现在,我们将引入第三种,也是信息量最大的一种被动侦察技术——利用搜索引擎。像Google、Bing这样的搜索引擎,它们的爬虫(Crawlers)夜以继日地在互联网上爬取和索引网页。如果一个子域名下的任何一个页面被这些爬虫访问过,那么这个子域名就很可能被记录在了搜索引擎庞大的数据库中。
1. 核心技术:“Google Hacking” 与 site: 操作符
“Google Hacking”(或更广义的“Search Engine Hacking”)并非指攻击Google本身,而是指利用搜索引擎高级的搜索语法,来发现普通搜索无法找到的敏感信息。
对于子域名枚举,我们最核心的武器就是site:操作符。
-
site:example.com: 告诉搜索引擎,只返回域名为example.com的结果。 -
site:*.example.com: 这是我们的“魔法咒语”。星号*作为通配符,它会告诉搜索引擎,返回所有example.com的子域名下的结果。 -
组合使用: 我们还可以排除主域名,以获得更纯净的子域名列表:
site:*.example.com -site:www.example.com
2. 技术选型:googlesearch-python 库
直接用Python的requests库去爬取Google的搜索结果页面非常困难,因为Google有极其强大的反爬虫机制(如验证码、IP封锁)。为了简化这个过程,我们使用一个第三方库googlesearch-python,它封装了模拟浏览器行为、处理Cookie等复杂操作。
环境准备:
Bash
pip install googlesearch-python
重要提示:这类非官方的爬取库非常脆弱,随时可能因为搜索引擎更新其页面结构或反爬机制而失效。此外,频繁地使用它可能会导致你的IP被Google临时封禁。在专业的、大规模的应用中,应该使用官方提供的、付费的搜索引擎API。
3. 完整代码实现 (search_engine_enum.py)
我们将编写一个脚本,它能接收一个目标域名,自动构造搜索查询,然后从返回的URL中解析出所有不重复的子域名。
Python
# search_engine_enum.py
import argparse
from googlesearch import search
from urllib.parse import urlparse
import time
class SearchEngineEnum:
def __init__(self, domain, num_results=100, delay=2):
self.domain = domain
self.num_results = num_results
self.delay = delay
self.found_subdomains = set()
def run(self):
"""
通过搜索引擎查询子域名。
"""
print(f"[*] 正在使用搜索引擎查询 '{self.domain}' 的子域名...")
# 构造Google Hacking查询语句
query = f"site:*.{self.domain}"
try:
# 执行搜索
# tld: 顶级域名
# num: 一次请求的结果数量
# stop: 总共获取的结果数量
# pause: 每次HTTP请求之间的延迟(秒),这是避免被封禁的关键!
search_results = search(query, num=10, stop=self.num_results, pause=self.delay)
for url in search_results:
try:
# 使用urlparse来解析URL
parsed_url = urlparse(url)
hostname = parsed_url.hostname
# 确保提取出的主机名是目标域名的子域名,且不重复
if hostname and hostname.endswith(self.domain):
self.found_subdomains.add(hostname)
except Exception:
continue # 忽略无法解析的URL
except Exception as e:
print(f"[!] 搜索时发生错误: {e}")
print("[!] 这可能是由于被搜索引擎临时封禁。请尝试增加延迟(--delay)或更换IP。")
return sorted(list(self.found_subdomains))
def main():
parser = argparse.ArgumentParser(description="一个通过搜索引擎发现子域名的工具。")
parser.add_argument("-d", "--domain", required=True, help="目标域名。")
parser.add_argument("-n", "--num", type=int, default=100, help="要获取的搜索结果数量。")
parser.add_argument("--delay", type=float, default=2.0, help="每次HTTP请求之间的延迟(秒)。")
args = parser.parse_args()
scanner = SearchEngineEnum(args.domain, args.num, args.delay)
found_domains = scanner.run()
print("\n" + "="*50)
print("[*] 查询完成。")
if found_domains:
print(f"[+] 共发现 {len(found_domains)} 个子域名:")
for domain in found_domains:
print(f" - {domain}")
else:
print("[-] 未发现任何子域名。")
print("="*50)
if __name__ == "__main__":
main()
四、 如何使用
这个工具的命令行参数非常直观。
Bash
# 查询 tesla.com 的子域名,获取前200条搜索结果,每次请求间隔3秒
python search_engine_enum.py -d tesla.com -n 200 --delay 3
关键参数 --delay:这是使用这类爬取工具的“护身符”。将延迟设置得长一些(2-5秒),可以极大地降低被搜索引擎判定为机器人而封禁的风险。
总结与展望
我们成功地将搜索引擎这一强大的信息源,整合进了我们的子域名枚举工作流。通过Google Hacking,我们能够以一种完全被动的方式,发现大量已被互联网索引的、具有真实业务价值的子域名。
至此,我们的子域名枚举工具已经拥有了三种不同维度的侦察能力:
-
主动猜测(字典爆破)
-
证书历史(CT日志)
-
公开索引(搜索引擎)
一个完整的侦察流程,就是将这三种(以及未来将学的更多)方法的结果进行汇总和去重。
更多推荐
所有评论(0)