TheHarvester使用教程#

软件介绍#

TheHarvester是一款强大的电子邮件、子域名和主机名收集工具,专为渗透测试人员和安全研究人员设计。它能够通过多种搜索引擎、PGP密钥服务器和SHODAN数据库收集目标的相关信息,为情报收集和安全评估提供重要支持。

主要功能#

  • 多搜索引擎支持(Google、Bing、Yahoo、Ask等)
  • 电子邮件地址收集
  • 子域名枚举
  • 主机名发现
  • PGP密钥服务器查询
  • SHODAN数据库查询
  • 支持代理设置
  • 支持结果保存
  • 支持DNS爆破
  • 支持虚拟主机枚举

适用场景#

  • 渗透测试前的情报收集
  • 电子邮件安全评估
  • 子域名发现
  • 域名信息收集
  • 开源情报(OSINT)收集
  • 网络安全研究

入门级使用#

安装TheHarvester#

TheHarvester是一个Python工具,可以通过以下步骤安装:

# 克隆仓库
git clone https://github.com/laramies/theHarvester.git

# 进入目录
cd theHarvester

# 安装依赖
pip install -r requirements.txt

# 安装TheHarvester
python setup.py install

基本电子邮件收集#

使用TheHarvester进行基本的电子邮件收集:

# 基本电子邮件收集
theHarvester -d example.com -l 100 -b google

# 收集example.com域名的电子邮件
# -d: 指定域名
# -l: 限制结果数量
# -b: 指定搜索引擎

查看帮助信息#

查看TheHarvester的所有可用选项:

# 查看帮助信息
theHarvester -h

初级使用#

使用多个搜索引擎#

使用多个搜索引擎进行电子邮件收集:

# 使用Bing搜索引擎
theHarvester -d example.com -l 100 -b bing

# 使用Yahoo搜索引擎
theHarvester -d example.com -l 100 -b yahoo

# 使用多个搜索引擎
theHarvester -d example.com -l 100 -b google,bing,yahoo

子域名枚举#

使用TheHarvester进行子域名枚举:

# 子域名枚举
theHarvester -d example.com -l 100 -b google -h

# -h: 同时收集主机名

结果保存#

将收集结果保存到文件:

# 保存结果到文件
theHarvester -d example.com -l 100 -b google -f results.txt

# -f: 指定输出文件

中级使用#

使用代理#

使用代理进行收集,保护隐私:

# 使用单个代理
theHarvester -d example.com -l 100 -b google -p http://127.0.0.1:8080

# 使用代理列表
theHarvester -d example.com -l 100 -b google -p proxies.txt

PGP密钥服务器查询#

查询PGP密钥服务器获取电子邮件:

# 查询PGP密钥服务器
theHarvester -d example.com -l 100 -b pgp

# 使用多个数据源
theHarvester -d example.com -l 100 -b google,pgp

SHODAN数据库查询#

查询SHODAN数据库获取主机信息:

# 查询SHODAN数据库
theHarvester -d example.com -l 100 -b shodan

# 需要SHODAN API密钥

中上级使用#

DNS爆破#

使用DNS爆破技术发现子域名:

# DNS爆破
theHarvester -d example.com -l 100 -b dns

# 使用自定义字典
theHarvester -d example.com -l 100 -b dns -e dnslist.txt

虚拟主机枚举#

枚举虚拟主机:

# 虚拟主机枚举
theHarvester -d example.com -l 100 -b vhost

# 需要指定IP地址
theHarvester -d example.com -l 100 -b vhost -i 192.168.1.100

结果分析和验证#

对收集结果进行分析和验证:

# 收集结果
theHarvester -d example.com -l 100 -b google,bing,yahoo -f results.txt

# 分析结果
# 提取电子邮件地址
grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' results.txt > emails.txt

# 去重
sort emails.txt | uniq > unique_emails.txt

# 验证电子邮件有效性
# 可以使用电子邮件验证工具

高级使用#

自定义搜索引擎#

添加自定义搜索引擎:

# 修改TheHarvester源代码添加自定义搜索引擎
# 在theHarvester/lib/core.py中添加新的搜索引擎类

class CustomSearchEngine:
    def __init__(self, word, limit, start):
        self.word = word
        self.results = ""
        self.total_results = ""
        self.server = "custom.engine.com"
        self.limit = limit
        self.start = start
    
    def process(self):
        # 实现搜索逻辑
        pass

自动化脚本集成#

将TheHarvester集成到自动化脚本中:

# 自动化脚本示例
import subprocess
import json

def harvest_emails(domain, engines=['google', 'bing', 'yahoo'], limit=100):
    results = {
        'domain': domain,
        'emails': [],
        'hosts': [],
        'subdomains': []
    }
    
    for engine in engines:
        # 运行TheHarvester
        cmd = ['theHarvester', '-d', domain, '-l', str(limit), '-b', engine]
        result = subprocess.run(cmd, capture_output=True, text=True)
        
        # 解析结果
        output = result.stdout
        
        # 提取电子邮件
        emails = extract_emails(output)
        results['emails'].extend(emails)
        
        # 提取主机名
        hosts = extract_hosts(output)
        results['hosts'].extend(hosts)
        
        # 提取子域名
        subdomains = extract_subdomains(output)
        results['subdomains'].extend(subdomains)
    
    # 去重
    results['emails'] = list(set(results['emails']))
    results['hosts'] = list(set(results['hosts']))
    results['subdomains'] = list(set(results['subdomains']))
    
    return results

def extract_emails(text):
    # 提取电子邮件地址
    import re
    pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
    return re.findall(pattern, text)

def extract_hosts(text):
    # 提取主机名
    import re
    pattern = r'Host: ([a-zA-Z0-9.-]+)'
    return re.findall(pattern, text)

def extract_subdomains(text):
    # 提取子域名
    import re
    pattern = r'([a-zA-Z0-9.-]+\.' + domain + ')'
    return re.findall(pattern, text)

# 使用示例
domain = "example.com"
results = harvest_emails(domain, engines=['google', 'bing', 'yahoo'], limit=100)

print(f"Found {len(results['emails'])} emails")
print(f"Found {len(results['hosts'])} hosts")
print(f"Found {len(results['subdomains'])} subdomains")

# 保存结果
with open(f'{domain}_results.json', 'w') as f:
    json.dump(results, f, indent=2)

批量域名收集#

批量收集多个域名的信息:

# 批量收集脚本
import subprocess
import json
from concurrent.futures import ThreadPoolExecutor

def harvest_domain(domain):
    cmd = ['theHarvester', '-d', domain, '-l', '100', '-b', 'google,bing,yahoo']
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    # 解析结果
    emails = extract_emails(result.stdout)
    hosts = extract_hosts(result.stdout)
    subdomains = extract_subdomains(result.stdout)
    
    return {
        'domain': domain,
        'emails': list(set(emails)),
        'hosts': list(set(hosts)),
        'subdomains': list(set(subdomains))
    }

def batch_harvest(domains, max_workers=5):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        results = list(executor.map(harvest_domain, domains))
    
    return results

# 使用示例
domains = open('domains.txt').read().splitlines()
results = batch_harvest(domains, max_workers=10)

# 统计结果
total_emails = sum(len(r['emails']) for r in results)
total_hosts = sum(len(r['hosts']) for r in results)
total_subdomains = sum(len(r['subdomains']) for r in results)

print(f"Harvested {total_emails} emails across {len(domains)} domains")
print(f"Harvested {total_hosts} hosts")
print(f"Harvested {total_subdomains} subdomains")

# 保存结果
with open('batch_results.json', 'w') as f:
    json.dump(results, f, indent=2)

大师级使用#

情报收集平台#

构建完整的情报收集平台:

# 情报收集平台
import subprocess
import json
from datetime import datetime
from collections import defaultdict

class IntelligencePlatform:
    def __init__(self, config_file):
        self.config = self.load_config(config_file)
        self.intelligence = defaultdict(dict)
    
    def load_config(self, config_file):
        with open(config_file, 'r') as f:
            return json.load(f)
    
    def collect_intelligence(self, domain):
        # 收集电子邮件
        emails = self.harvest_emails(domain)
        
        # 收集子域名
        subdomains = self.harvest_subdomains(domain)
        
        # 收集主机信息
        hosts = self.harvest_hosts(domain)
        
        # 存储情报
        self.intelligence[domain] = {
            'emails': emails,
            'subdomains': subdomains,
            'hosts': hosts,
            'collected_at': datetime.now().isoformat()
        }
        
        return self.intelligence[domain]
    
    def harvest_emails(self, domain):
        emails = set()
        
        for engine in self.config['engines']:
            cmd = ['theHarvester', '-d', domain, '-l', '100', '-b', engine]
            result = subprocess.run(cmd, capture_output=True, text=True)
            
            # 提取电子邮件
            extracted_emails = extract_emails(result.stdout)
            emails.update(extracted_emails)
        
        return list(emails)
    
    def harvest_subdomains(self, domain):
        subdomains = set()
        
        # 使用DNS爆破
        cmd = ['theHarvester', '-d', domain, '-l', '100', '-b', 'dns']
        result = subprocess.run(cmd, capture_output=True, text=True)
        
        # 提取子域名
        extracted_subdomains = extract_subdomains(result.stdout)
        subdomains.update(extracted_subdomains)
        
        return list(subdomains)
    
    def harvest_hosts(self, domain):
        hosts = set()
        
        for engine in self.config['engines']:
            cmd = ['theHarvester', '-d', domain, '-l', '100', '-b', engine, '-h']
            result = subprocess.run(cmd, capture_output=True, text=True)
            
            # 提取主机
            extracted_hosts = extract_hosts(result.stdout)
            hosts.update(extracted_hosts)
        
        return list(hosts)
    
    def analyze_intelligence(self, domain):
        if domain not in self.intelligence:
            return None
        
        intel = self.intelligence[domain]
        
        analysis = {
            'domain': domain,
            'email_patterns': self.analyze_email_patterns(intel['emails']),
            'subdomain_patterns': self.analyze_subdomain_patterns(intel['subdomains']),
            'host_patterns': self.analyze_host_patterns(intel['hosts']),
            'risk_assessment': self.assess_risks(intel)
        }
        
        return analysis
    
    def analyze_email_patterns(self, emails):
        # 分析电子邮件模式
        patterns = {
            'total': len(emails),
            'by_domain': defaultdict(int),
            'by_prefix': defaultdict(int)
        }
        
        for email in emails:
            # 按域名统计
            domain = email.split('@')[1]
            patterns['by_domain'][domain] += 1
            
            # 按前缀统计
            prefix = email.split('@')[0]
            patterns['by_prefix'][prefix] += 1
        
        return patterns
    
    def analyze_subdomain_patterns(self, subdomains):
        # 分析子域名模式
        patterns = {
            'total': len(subdomains),
            'by_prefix': defaultdict(int),
            'by_suffix': defaultdict(int)
        }
        
        for subdomain in subdomains:
            # 按前缀统计
            parts = subdomain.split('.')
            if len(parts) > 2:
                prefix = parts[0]
                patterns['by_prefix'][prefix] += 1
            
            # 按后缀统计
            if len(parts) > 1:
                suffix = '.'.join(parts[1:])
                patterns['by_suffix'][suffix] += 1
        
        return patterns
    
    def analyze_host_patterns(self, hosts):
        # 分析主机模式
        patterns = {
            'total': len(hosts),
            'by_ip': defaultdict(int),
            'by_service': defaultdict(int)
        }
        
        for host in hosts:
            # 按IP统计
            if 'ip' in host:
                patterns['by_ip'][host['ip']] += 1
            
            # 按服务统计
            if 'service' in host:
                patterns['by_service'][host['service']] += 1
        
        return patterns
    
    def assess_risks(self, intel):
        # 评估风险
        risks = {
            'email_risks': [],
            'subdomain_risks': [],
            'host_risks': []
        }
        
        # 评估电子邮件风险
        for email in intel['emails']:
            if 'admin' in email.lower() or 'root' in email.lower():
                risks['email_risks'].append({
                    'email': email,
                    'risk': 'high',
                    'reason': 'Sensitive email address'
                })
        
        # 评估子域名风险
        for subdomain in intel['subdomains']:
            if 'dev' in subdomain.lower() or 'test' in subdomain.lower():
                risks['subdomain_risks'].append({
                    'subdomain': subdomain,
                    'risk': 'medium',
                    'reason': 'Development or test subdomain'
                })
        
        return risks
    
    def generate_report(self, domain, output_file):
        intel = self.collect_intelligence(domain)
        analysis = self.analyze_intelligence(domain)
        
        report = {
            'intelligence': intel,
            'analysis': analysis,
            'generated_at': datetime.now().isoformat()
        }
        
        with open(output_file, 'w') as f:
            json.dump(report, f, indent=2)
        
        return report

# 使用示例
# config.json内容:
# {
#     "engines": ["google", "bing", "yahoo", "pgp"],
#     "domains": ["example.com", "test.com"]
# }

platform = IntelligencePlatform('config.json')

# 收集情报
for domain in platform.config['domains']:
    report = platform.generate_report(domain, f'{domain}_report.json')
    print(f"Generated report for {domain}")

自动化监控系统#

构建自动化监控系统,持续收集情报:

# 自动化监控系统
import time
import json
from datetime import datetime
import smtplib
from email.mime.text import MIMEText

class MonitoringSystem:
    def __init__(self, config_file):
        self.config = self.load_config(config_file)
        self.previous_intelligence = {}
        self.platform = IntelligencePlatform(config_file)
    
    def load_config(self, config_file):
        with open(config_file, 'r') as f:
            return json.load(f)
    
    def monitor(self):
        while True:
            timestamp = datetime.now().isoformat()
            
            for domain in self.config['domains']:
                # 收集当前情报
                current_intel = self.platform.collect_intelligence(domain)
                
                # 比较情报
                if domain in self.previous_intelligence:
                    changes = self.compare_intelligence(
                        self.previous_intelligence[domain],
                        current_intel
                    )
                    
                    if changes:
                        self.send_alert(domain, changes, timestamp)
                
                self.previous_intelligence[domain] = current_intel
            
            time.sleep(self.config['monitor_interval'])
    
    def compare_intelligence(self, previous, current):
        # 比较前后情报
        changes = {
            'new_emails': set(current['emails']) - set(previous['emails']),
            'removed_emails': set(previous['emails']) - set(current['emails']),
            'new_subdomains': set(current['subdomains']) - set(previous['subdomains']),
            'removed_subdomains': set(previous['subdomains']) - set(current['subdomains']),
            'new_hosts': set(current['hosts']) - set(previous['hosts']),
            'removed_hosts': set(previous['hosts']) - set(current['hosts'])
        }
        
        return changes
    
    def send_alert(self, domain, changes, timestamp):
        # 发送告警
        message = f"""
        Intelligence Alert for {domain}
        Time: {timestamp}
        
        New Emails: {len(changes['new_emails'])}
        Removed Emails: {len(changes['removed_emails'])}
        New Subdomains: {len(changes['new_subdomains'])}
        Removed Subdomains: {len(changes['removed_subdomains'])}
        New Hosts: {len(changes['new_hosts'])}
        Removed Hosts: {len(changes['removed_hosts'])}
        """
        
        msg = MIMEText(message)
        msg['Subject'] = f"Intelligence Alert: {domain}"
        msg['From'] = self.config['email']['from']
        msg['To'] = ', '.join(self.config['email']['recipients'])
        
        # 发送邮件
        # smtplib.SMTP(self.config['email']['smtp']).send_message(msg)
        print(f"Alert sent for {domain}")

# 使用示例
# config.json内容:
# {
#     "domains": ["example.com", "test.com"],
#     "engines": ["google", "bing", "yahoo"],
#     "monitor_interval": 3600,
#     "email": {
#         "smtp": "smtp.example.com",
#         "from": "monitor@example.com",
#         "recipients": ["admin@example.com"]
#     }
# }

system = MonitoringSystem('config.json')
system.monitor()

实战案例#

案例一:企业电子邮件收集#

场景:渗透测试团队需要收集某企业的电子邮件地址,为后续的社会工程学测试做准备。

解决方案:使用TheHarvester全面收集企业的电子邮件地址。

实施步骤

  1. 电子邮件收集

    # 使用多个搜索引擎收集
    theHarvester -d example.com -l 500 -b google,bing,yahoo -f emails.txt
    
    # 使用PGP密钥服务器
    theHarvester -d example.com -l 100 -b pgp -f pgp_emails.txt
    
    # 合并结果
    cat emails.txt pgp_emails.txt | sort | uniq > all_emails.txt
  2. 结果分析

    • 分析电子邮件命名模式
    • 识别关键人物的电子邮件
    • 评估电子邮件的有效性
  3. 测试准备

    • 基于收集的电子邮件制定测试计划
    • 准备社会工程学测试材料
    • 设置测试环境

结果

  • 收集了企业200多个电子邮件地址
  • 识别出15个关键人物的电子邮件
  • 分析出电子邮件命名模式
  • 为社会工程学测试提供了充分的准备

案例二:子域名发现#

场景:安全研究人员需要发现目标域名的所有子域名,为后续的安全评估做准备。

解决方案:使用TheHarvester进行全面的子域名枚举。

实施步骤

  1. 子域名枚举

    # 使用搜索引擎枚举
    theHarvester -d example.com -l 500 -b google,bing,yahoo -h -f subdomains.txt
    
    # 使用DNS爆破
    theHarvester -d example.com -l 500 -b dns -f dns_subdomains.txt
    
    # 合并结果
    cat subdomains.txt dns_subdomains.txt | sort | uniq > all_subdomains.txt
  2. 结果验证

    • 验证子域名的有效性
    • 检查子域名的DNS解析
    • 分析子域名的用途
  3. 安全评估

    • 对发现的子域名进行安全扫描
    • 评估子域名的安全风险
    • 提供安全加固建议

结果

  • 发现了目标域名的100多个子域名
  • 验证了80个有效的子域名
  • 识别出15个潜在的敏感子域名
  • 提供了详细的子域名安全评估报告

案例三:开源情报收集#

场景:情报分析师需要收集目标组织的开源情报,了解其在线存在和活动。

解决方案:使用TheHarvester收集目标组织的电子邮件、子域名和主机信息。

实施步骤

  1. 情报收集

    # 收集电子邮件
    theHarvester -d example.com -l 500 -b google,bing,yahoo,pgp -f emails.txt
    
    # 收集子域名
    theHarvester -d example.com -l 500 -b google,bing,yahoo,dns -h -f subdomains.txt
    
    # 收集主机信息
    theHarvester -d example.com -l 500 -b google,bing,yahoo,shodan -f hosts.txt
  2. 情报分析

    • 分析电子邮件模式
    • 分析子域名结构
    • 分析主机分布
    • 构建组织画像
  3. 情报报告

    • 生成开源情报报告
    • 提供情报分析结论
    • 制定后续行动计划

结果

  • 收集了目标组织的全面开源情报
  • 分析了组织的在线存在和活动
  • 构建了详细的组织画像
  • 提供了有价值的情报分析报告

总结#

TheHarvester是一款功能强大的电子邮件、子域名和主机名收集工具,通过本教程的学习,您已经掌握了从入门到大师级的使用方法。

主要功能回顾#

  • 多搜索引擎:支持Google、Bing、Yahoo等多个搜索引擎
  • 电子邮件收集:收集目标域名的电子邮件地址
  • 子域名枚举:枚举目标域名的子域名
  • 主机名发现:发现目标的主机名和IP地址
  • PGP查询:查询PGP密钥服务器获取信息
  • SHODAN查询:查询SHODAN数据库获取主机信息
  • DNS爆破:使用DNS爆破技术发现子域名
  • 虚拟主机枚举:枚举虚拟主机
  • 结果保存:支持将结果保存到文件

最佳实践#

  1. 多源收集:使用多个搜索引擎和数据源,提高收集效率
  2. 结果验证:对收集到的结果进行验证,确保准确性
  3. 定期收集:定期进行情报收集,及时发现新的信息
  4. 结果分析:对收集到的结果进行深度分析,提取有价值的信息
  5. 数据保护:妥善保护收集到的数据,避免泄露
  6. 合法使用:确保在法律和授权范围内使用TheHarvester

注意事项#

  1. 搜索引擎限制:频繁使用搜索引擎可能会被限制访问,建议使用代理
  2. 数据准确性:搜索引擎结果可能存在误报,需要进行验证
  3. API限制:SHODAN等服务的API可能有使用限制,需要注意配额
  4. 网络影响:大规模收集可能会对网络造成一定影响
  5. 法律合规:使用TheHarvester进行收集时,需要遵守相关法律法规
  6. 道德考量:确保获得目标的授权后再进行情报收集

通过合理使用TheHarvester,您可以有效地收集电子邮件、子域名和主机名等情报,为渗透测试、安全评估和情报研究提供有价值的信息。同时,务必在法律和伦理允许的范围内使用该工具,确保情报收集的合法性和负责任性。