摘要:在本文中,我们将利用地球上最强大的信息索引——搜索引擎,来为我们的子域名枚举工具增添“情报搜集”能力。我们将深入探讨“Google Hacking”技术,特别是利用site:搜索操作符来挖掘一个主域名下所有被搜索引擎索引到的子域名。我们将使用googlesearch-python这个第三方库来自动化地执行搜索查询,并编写一个Python模块来解析搜索结果,从中提取出宝贵的子域名信息。这是一种极其高效的被动侦察方法,能够发现大量在公开网络上活跃的、有真实业务的子域名。

关键词:Python, 子域名枚举, 搜索引擎, Google Hacking, site:, 被动侦察, Web安全, Scrapy


正文

到目前为止,我们已经拥有了两种发现子域名的武器:

  1. 字典爆破:主动猜测,可能发现未公开的域名,但有流量特征。

  2. 证书透明度日志:被动查询,能发现申请过证书的域名,非常隐蔽。

现在,我们将引入第三种,也是信息量最大的一种被动侦察技术——利用搜索引擎。像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,我们能够以一种完全被动的方式,发现大量已被互联网索引的、具有真实业务价值的子域名。

至此,我们的子域名枚举工具已经拥有了三种不同维度的侦察能力:

  1. 主动猜测(字典爆破)

  2. 证书历史(CT日志)

  3. 公开索引(搜索引擎)

一个完整的侦察流程,就是将这三种(以及未来将学的更多)方法的结果进行汇总和去重。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐