Skip to content

Sherlock Social Media Username Hunter Cheat Sheet

Overview

Sherlock is a powerful OSINT tool that hunts down social media accounts by username across 400+ social networks. It's designed to find usernames across a large number of social networks very quickly, making it an essential tool for digital investigations, background checks, and cybersecurity research. Sherlock uses a combination of HTTP requests and response analysis to determine if a username exists on various platforms.

⚠️ Legal Notice: Only use Sherlock for legitimate OSINT investigations, authorized security testing, or personal research. Respect platform terms of service and applicable privacy laws.

Installation

Python pip Installation

bash
# Install via pip
pip3 install sherlock-project

# Verify installation
sherlock --help

# Alternative: Install from GitHub
pip3 install git+https://github.com/sherlock-project/sherlock.git

# Install with all dependencies
pip3 install sherlock-project[all]

Docker Installation

bash
# Pull official Docker image
docker pull sherlockproject/sherlock

# Run with Docker
docker run --rm -t sherlockproject/sherlock username

# Run with output directory
docker run --rm -t -v $(pwd)/results:/opt/sherlock/results sherlockproject/sherlock username

# Build from source
git clone https://github.com/sherlock-project/sherlock.git
cd sherlock
docker build -t sherlock .

Manual Installation

bash
# Clone repository
git clone https://github.com/sherlock-project/sherlock.git
cd sherlock

# Install dependencies
pip3 install -r requirements.txt

# Run directly
python3 sherlock username

# Make executable
chmod +x sherlock
./sherlock username

Virtual Environment Setup

bash
# Create virtual environment
python3 -m venv sherlock-env
source sherlock-env/bin/activate

# Install Sherlock
pip install sherlock-project

# Verify installation
sherlock --version

Basic Usage

Command Line Interface

bash
# Basic username search
sherlock username

# Search multiple usernames
sherlock user1 user2 user3

# Search with output to file
sherlock username --output results.txt

# Search with CSV output
sherlock username --csv

# Search with JSON output
sherlock username --json results.json

# Verbose output
sherlock username --verbose

# Print only found results
sherlock username --print-found

Advanced Search Options

bash
# Search specific sites only
sherlock username --site GitHub --site Twitter

# Exclude specific sites
sherlock username --exclude Instagram --exclude Facebook

# Use proxy
sherlock username --proxy http://proxy:8080

# Set custom timeout
sherlock username --timeout 10

# Disable SSL verification
sherlock username --no-ssl-verify

# Use Tor proxy
sherlock username --tor

# Foldering output by username
sherlock username --folderoutput results/

Site-Specific Searches

bash
# Search major social networks
sherlock username --site Twitter --site Instagram --site Facebook --site LinkedIn

# Search professional networks
sherlock username --site LinkedIn --site GitHub --site GitLab --site Behance

# Search gaming platforms
sherlock username --site Steam --site Twitch --site Discord --site Xbox

# Search dating platforms
sherlock username --site Tinder --site Bumble --site Match

# Search forums and communities
sherlock username --site Reddit --site HackerNews --site StackOverflow

Technology and Development Platforms

bash
# Developer platforms
sherlock username --site GitHub --site GitLab --site Bitbucket --site SourceForge

# Tech communities
sherlock username --site StackOverflow --site HackerNews --site DeviantArt

# Code sharing platforms
sherlock username --site Pastebin --site Gist --site CodePen

# Documentation platforms
sherlock username --site GitBook --site Notion --site Confluence

Content and Media Platforms

bash
# Video platforms
sherlock username --site YouTube --site Vimeo --site TikTok --site Dailymotion

# Photo platforms
sherlock username --site Instagram --site Flickr --site 500px --site Imgur

# Blogging platforms
sherlock username --site Medium --site WordPress --site Blogger --site Tumblr

# Music platforms
sherlock username --site Spotify --site SoundCloud --site Bandcamp

Output Formats and Analysis

Text Output

bash
# Basic text output
sherlock username > results.txt

# Verbose text output
sherlock username --verbose > detailed_results.txt

# Only found accounts
sherlock username --print-found > found_accounts.txt

# With timestamps
sherlock username --verbose | tee "results_$(date +%Y%m%d_%H%M%S).txt"

Structured Data Output

bash
# CSV format
sherlock username --csv --output results.csv

# JSON format
sherlock username --json results.json

# Both CSV and JSON
sherlock username --csv --json results.json --output results.csv

# Folder output (organized by username)
sherlock user1 user2 --folderoutput investigation_results/

Custom Output Processing

python
#!/usr/bin/env python3
# sherlock-output-processor.py

import json
import csv
import sys
from datetime import datetime

def process_sherlock_json(json_file):
    """Process Sherlock JSON output"""
    try:
        with open(json_file, 'r') as f:
            data = json.load(f)
        
        results = []
        for username, sites in data.items():
            for site, info in sites.items():
                if info.get('status') == 'Claimed':
                    results.append({
                        'username': username,
                        'site': site,
                        'url': info.get('url_user', ''),
                        'response_time': info.get('response_time_s', 0),
                        'status': info.get('status', '')
                    })
        
        return results
    
    except Exception as e:
        print(f"Error processing JSON: {e}")
        return []

def generate_summary_report(results):
    """Generate summary report from results"""
    if not results:
        return "No results to process"
    
    # Count by platform
    platform_counts = {}
    for result in results:
        platform = result['site']
        platform_counts[platform] = platform_counts.get(platform, 0) + 1
    
    # Generate report
    report = f"""
Sherlock Investigation Summary
Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}

Total Accounts Found: {len(results)}
Unique Platforms: {len(platform_counts)}

Platform Distribution:
"""
    
    for platform, count in sorted(platform_counts.items(), key=lambda x: x[1], reverse=True):
        report += f"  {platform}: {count}\n"
    
    report += "\nDetailed Results:\n"
    for result in results:
        report += f"  {result['site']}: {result['url']}\n"
    
    return report

def export_to_csv(results, filename):
    """Export results to CSV"""
    if not results:
        return
    
    with open(filename, 'w', newline='') as csvfile:
        fieldnames = ['username', 'site', 'url', 'response_time', 'status']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        
        writer.writeheader()
        for result in results:
            writer.writerow(result)

def main():
    if len(sys.argv) != 2:
        print("Usage: python3 sherlock-output-processor.py <sherlock_json_file>")
        sys.exit(1)
    
    json_file = sys.argv[1]
    results = process_sherlock_json(json_file)
    
    if results:
        # Generate summary
        summary = generate_summary_report(results)
        print(summary)
        
        # Save summary to file
        with open('sherlock_summary.txt', 'w') as f:
            f.write(summary)
        
        # Export to CSV
        export_to_csv(results, 'sherlock_results.csv')
        
        print(f"\nSummary saved to: sherlock_summary.txt")
        print(f"CSV export saved to: sherlock_results.csv")
    else:
        print("No valid results found in JSON file")

if __name__ == "__main__":
    main()

Automation and Batch Processing

Batch Username Investigation

bash
#!/bin/bash
# sherlock-batch-investigation.sh

USERNAMES_FILE="$1"
OUTPUT_DIR="$2"

if [ $# -ne 2 ]; then
    echo "Usage: $0 <usernames_file> <output_directory>"
    echo "Example: $0 usernames.txt investigation_results/"
    exit 1
fi

if [ ! -f "$USERNAMES_FILE" ]; then
    echo "Error: Usernames file not found: $USERNAMES_FILE"
    exit 1
fi

# Create output directory
mkdir -p "$OUTPUT_DIR"

echo "Starting batch Sherlock investigation"
echo "Usernames file: $USERNAMES_FILE"
echo "Output directory: $OUTPUT_DIR"
echo "=================================="

# Process each username
while IFS= read -r username; do
    # Skip empty lines and comments
    if [[ -z "$username" || "$username" =~ ^#.* ]]; then
        continue
    fi
    
    echo "Investigating username: $username"
    
    # Create individual output files
    TEXT_OUTPUT="$OUTPUT_DIR/${username}_results.txt"
    JSON_OUTPUT="$OUTPUT_DIR/${username}_results.json"
    CSV_OUTPUT="$OUTPUT_DIR/${username}_results.csv"
    
    # Run Sherlock with multiple output formats
    sherlock "$username" \
        --output "$TEXT_OUTPUT" \
        --json "$JSON_OUTPUT" \
        --csv \
        --timeout 15 \
        --print-found \
        --verbose
    
    # Move CSV file to proper location
    if [ -f "${username}.csv" ]; then
        mv "${username}.csv" "$CSV_OUTPUT"
    fi
    
    echo "Results saved for $username"
    echo "  Text: $TEXT_OUTPUT"
    echo "  JSON: $JSON_OUTPUT"
    echo "  CSV: $CSV_OUTPUT"
    echo ""
    
    # Add delay to avoid rate limiting
    sleep 2
    
done < "$USERNAMES_FILE"

echo "Batch investigation completed"
echo "Results saved in: $OUTPUT_DIR"

# Generate combined summary
echo "Generating combined summary..."
python3 << 'PYTHON_SCRIPT'
import os
import json
import sys
from collections import defaultdict

output_dir = sys.argv[1] if len(sys.argv) > 1 else "investigation_results"

all_results = defaultdict(list)
total_accounts = 0

# Process all JSON files
for filename in os.listdir(output_dir):
    if filename.endswith('_results.json'):
        username = filename.replace('_results.json', '')
        filepath = os.path.join(output_dir, filename)
        
        try:
            with open(filepath, 'r') as f:
                data = json.load(f)
            
            for site, info in data.get(username, {}).items():
                if info.get('status') == 'Claimed':
                    all_results[username].append({
                        'site': site,
                        'url': info.get('url_user', ''),
                        'response_time': info.get('response_time_s', 0)
                    })
                    total_accounts += 1
        
        except Exception as e:
            print(f"Error processing {filename}: {e}")

# Generate summary report
summary_file = os.path.join(output_dir, 'investigation_summary.txt')
with open(summary_file, 'w') as f:
    f.write("Sherlock Batch Investigation Summary\n")
    f.write("===================================\n\n")
    f.write(f"Total usernames investigated: {len(all_results)}\n")
    f.write(f"Total accounts found: {total_accounts}\n\n")
    
    for username, accounts in all_results.items():
        f.write(f"Username: {username}\n")
        f.write(f"Accounts found: {len(accounts)}\n")
        for account in accounts:
            f.write(f"  {account['site']}: {account['url']}\n")
        f.write("\n")

print(f"Combined summary saved to: {summary_file}")
PYTHON_SCRIPT "$OUTPUT_DIR"

Automated Monitoring Script

python
#!/usr/bin/env python3
# sherlock-monitor.py

import subprocess
import json
import time
import smtplib
from email.mime.text import MimeText
from email.mime.multipart import MimeMultipart
from datetime import datetime
import os

class SherlockMonitor:
    def __init__(self, config_file="monitor_config.json"):
        self.config = self.load_config(config_file)
        self.previous_results = {}
        self.load_previous_results()
    
    def load_config(self, config_file):
        """Load monitoring configuration"""
        default_config = {
            "usernames": [],
            "check_interval": 3600,  # 1 hour
            "email_notifications": False,
            "email_config": {
                "smtp_server": "smtp.gmail.com",
                "smtp_port": 587,
                "username": "",
                "password": "",
                "to_email": ""
            },
            "output_directory": "monitoring_results"
        }
        
        try:
            with open(config_file, 'r') as f:
                config = json.load(f)
            
            # Merge with defaults
            for key, value in default_config.items():
                if key not in config:
                    config[key] = value
            
            return config
        
        except FileNotFoundError:
            print(f"Config file not found, creating default: {config_file}")
            with open(config_file, 'w') as f:
                json.dump(default_config, f, indent=2)
            return default_config
    
    def load_previous_results(self):
        """Load previous monitoring results"""
        results_file = os.path.join(self.config["output_directory"], "previous_results.json")
        
        try:
            with open(results_file, 'r') as f:
                self.previous_results = json.load(f)
        except FileNotFoundError:
            self.previous_results = {}
    
    def save_results(self, results):
        """Save current results"""
        os.makedirs(self.config["output_directory"], exist_ok=True)
        results_file = os.path.join(self.config["output_directory"], "previous_results.json")
        
        with open(results_file, 'w') as f:
            json.dump(results, f, indent=2)
        
        self.previous_results = results
    
    def run_sherlock(self, username):
        """Run Sherlock for a specific username"""
        output_file = os.path.join(self.config["output_directory"], f"{username}_latest.json")
        
        try:
            cmd = [
                "sherlock", username,
                "--json", output_file,
                "--timeout", "15",
                "--print-found"
            ]
            
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
            
            if result.returncode == 0 and os.path.exists(output_file):
                with open(output_file, 'r') as f:
                    return json.load(f)
            else:
                print(f"Sherlock failed for {username}: {result.stderr}")
                return None
        
        except Exception as e:
            print(f"Error running Sherlock for {username}: {e}")
            return None
    
    def compare_results(self, username, current_results, previous_results):
        """Compare current and previous results"""
        changes = {
            "new_accounts": [],
            "removed_accounts": [],
            "username": username,
            "timestamp": datetime.now().isoformat()
        }
        
        current_sites = set()
        previous_sites = set()
        
        # Extract claimed accounts
        if username in current_results:
            for site, info in current_results[username].items():
                if info.get('status') == 'Claimed':
                    current_sites.add(site)
        
        if username in previous_results:
            for site, info in previous_results[username].items():
                if info.get('status') == 'Claimed':
                    previous_sites.add(site)
        
        # Find changes
        changes["new_accounts"] = list(current_sites - previous_sites)
        changes["removed_accounts"] = list(previous_sites - current_sites)
        
        return changes
    
    def send_notification(self, changes):
        """Send email notification about changes"""
        if not self.config["email_notifications"]:
            return
        
        if not changes["new_accounts"] and not changes["removed_accounts"]:
            return
        
        try:
            msg = MimeMultipart()
            msg['From'] = self.config["email_config"]["username"]
            msg['To'] = self.config["email_config"]["to_email"]
            msg['Subject'] = f"Sherlock Monitor Alert - {changes['username']}"
            
            body = f"""
Sherlock monitoring detected changes for username: {changes['username']}
Timestamp: {changes['timestamp']}

New accounts found: {len(changes['new_accounts'])}
{chr(10).join(changes['new_accounts'])}

Removed accounts: {len(changes['removed_accounts'])}
{chr(10).join(changes['removed_accounts'])}

This is an automated message from Sherlock Monitor.
"""
            
            msg.attach(MimeText(body, 'plain'))
            
            server = smtplib.SMTP(
                self.config["email_config"]["smtp_server"],
                self.config["email_config"]["smtp_port"]
            )
            server.starttls()
            server.login(
                self.config["email_config"]["username"],
                self.config["email_config"]["password"]
            )
            
            text = msg.as_string()
            server.sendmail(
                self.config["email_config"]["username"],
                self.config["email_config"]["to_email"],
                text
            )
            server.quit()
            
            print(f"Notification sent for {changes['username']}")
        
        except Exception as e:
            print(f"Failed to send notification: {e}")
    
    def monitor_usernames(self):
        """Monitor all configured usernames"""
        print(f"Starting Sherlock monitoring at {datetime.now()}")
        print(f"Monitoring {len(self.config['usernames'])} usernames")
        
        current_results = {}
        all_changes = []
        
        for username in self.config["usernames"]:
            print(f"Checking username: {username}")
            
            # Run Sherlock
            results = self.run_sherlock(username)
            
            if results:
                current_results.update(results)
                
                # Compare with previous results
                changes = self.compare_results(username, results, self.previous_results)
                
                if changes["new_accounts"] or changes["removed_accounts"]:
                    print(f"Changes detected for {username}:")
                    print(f"  New accounts: {changes['new_accounts']}")
                    print(f"  Removed accounts: {changes['removed_accounts']}")
                    
                    all_changes.append(changes)
                    self.send_notification(changes)
                else:
                    print(f"No changes for {username}")
            
            # Delay between checks
            time.sleep(5)
        
        # Save current results
        self.save_results(current_results)
        
        # Save change log
        if all_changes:
            change_log_file = os.path.join(
                self.config["output_directory"],
                f"changes_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
            )
            with open(change_log_file, 'w') as f:
                json.dump(all_changes, f, indent=2)
            
            print(f"Change log saved: {change_log_file}")
        
        print(f"Monitoring cycle completed at {datetime.now()}")
    
    def run_continuous_monitoring(self):
        """Run continuous monitoring with configured interval"""
        print("Starting continuous Sherlock monitoring")
        print(f"Check interval: {self.config['check_interval']} seconds")
        
        while True:
            try:
                self.monitor_usernames()
                print(f"Sleeping for {self.config['check_interval']} seconds...")
                time.sleep(self.config["check_interval"])
            
            except KeyboardInterrupt:
                print("\nMonitoring stopped by user")
                break
            except Exception as e:
                print(f"Error in monitoring cycle: {e}")
                time.sleep(60)  # Wait 1 minute before retrying

def main():
    import sys
    
    if len(sys.argv) > 1 and sys.argv[1] == "--continuous":
        monitor = SherlockMonitor()
        monitor.run_continuous_monitoring()
    else:
        monitor = SherlockMonitor()
        monitor.monitor_usernames()

if __name__ == "__main__":
    main()

Integration with Other OSINT Tools

Maltego Integration

python
#!/usr/bin/env python3
# sherlock-maltego-integration.py

import json
import csv
import xml.etree.ElementTree as ET
from datetime import datetime

def sherlock_to_maltego(sherlock_json, output_file="maltego_import.csv"):
    """Convert Sherlock results to Maltego CSV format"""
    
    try:
        with open(sherlock_json, 'r') as f:
            data = json.load(f)
        
        maltego_data = []
        
        for username, sites in data.items():
            # Add username entity
            maltego_data.append({
                'Entity Type': 'maltego.Username',
                'Entity Value': username,
                'Additional Fields': '',
                'Notes': f'Investigated with Sherlock on {datetime.now().strftime("%Y-%m-%d")}'
            })
            
            for site, info in sites.items():
                if info.get('status') == 'Claimed':
                    # Add website entity
                    maltego_data.append({
                        'Entity Type': 'maltego.Website',
                        'Entity Value': info.get('url_user', ''),
                        'Additional Fields': f'Platform={site}',
                        'Notes': f'Username: {username}, Response time: {info.get("response_time_s", 0)}s'
                    })
        
        # Write to CSV
        with open(output_file, 'w', newline='') as csvfile:
            fieldnames = ['Entity Type', 'Entity Value', 'Additional Fields', 'Notes']
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            
            writer.writeheader()
            for row in maltego_data:
                writer.writerow(row)
        
        print(f"Maltego import file created: {output_file}")
        return output_file
    
    except Exception as e:
        print(f"Error creating Maltego import: {e}")
        return None

def create_maltego_transform_config():
    """Create Maltego transform configuration"""
    config = """
<?xml version="1.0" encoding="UTF-8"?>
<MaltegoTransform>
    <Name>Sherlock Username Search</Name>
    <UIName>Sherlock Username Search</UIName>
    <Author>OSINT Investigator</Author>
    <Description>Search for username across social media platforms using Sherlock</Description>
    <Version>1.0</Version>
    <InputEntity>maltego.Username</InputEntity>
    <OutputEntity>maltego.Website</OutputEntity>
    <TransformSettings>
        <Property name="cmdline" type="string">python3 sherlock_transform.py</Property>
        <Property name="cmdparms" type="string">%value%</Property>
        <Property name="working-directory" type="string">.</Property>
    </TransformSettings>
</MaltegoTransform>
"""
    
    with open('sherlock_transform.mtz', 'w') as f:
        f.write(config)
    
    print("Maltego transform configuration created: sherlock_transform.mtz")

OSINT Framework Integration

python
#!/usr/bin/env python3
# osint-framework-sherlock.py

import subprocess
import json
import requests
from datetime import datetime
import os

class OSINTFrameworkIntegration:
    def __init__(self):
        self.results = {}
        self.tools_used = []
    
    def run_sherlock(self, username):
        """Run Sherlock investigation"""
        print(f"Running Sherlock for: {username}")
        
        output_file = f"sherlock_{username}.json"
        
        try:
            cmd = ["sherlock", username, "--json", output_file, "--timeout", "15"]
            result = subprocess.run(cmd, capture_output=True, text=True)
            
            if result.returncode == 0 and os.path.exists(output_file):
                with open(output_file, 'r') as f:
                    sherlock_data = json.load(f)
                
                self.results['sherlock'] = sherlock_data
                self.tools_used.append('Sherlock')
                return sherlock_data
            else:
                print(f"Sherlock failed: {result.stderr}")
                return None
        
        except Exception as e:
            print(f"Error running Sherlock: {e}")
            return None
    
    def run_theharvester(self, domain):
        """Run theHarvester for email enumeration"""
        print(f"Running theHarvester for: {domain}")
        
        try:
            cmd = ["theharvester", "-d", domain, "-l", "100", "-b", "google,bing"]
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
            
            if result.returncode == 0:
                # Parse theHarvester output
                emails = []
                hosts = []
                
                for line in result.stdout.split('\n'):
                    if '@' in line and domain in line:
                        emails.append(line.strip())
                    elif domain in line and not '@' in line:
                        hosts.append(line.strip())
                
                harvester_data = {
                    'emails': emails,
                    'hosts': hosts,
                    'domain': domain
                }
                
                self.results['theharvester'] = harvester_data
                self.tools_used.append('theHarvester')
                return harvester_data
        
        except Exception as e:
            print(f"Error running theHarvester: {e}")
            return None
    
    def check_haveibeenpwned(self, email):
        """Check Have I Been Pwned for email"""
        print(f"Checking Have I Been Pwned for: {email}")
        
        try:
            url = f"https://haveibeenpwned.com/api/v3/breachedaccount/{email}"
            headers = {
                'User-Agent': 'OSINT-Investigation-Tool',
                'hibp-api-key': 'YOUR_API_KEY_HERE'  # Replace with actual API key
            }
            
            response = requests.get(url, headers=headers, timeout=10)
            
            if response.status_code == 200:
                breaches = response.json()
                self.results['haveibeenpwned'] = {
                    'email': email,
                    'breaches': breaches,
                    'breach_count': len(breaches)
                }
                self.tools_used.append('Have I Been Pwned')
                return breaches
            elif response.status_code == 404:
                print(f"No breaches found for {email}")
                return []
            else:
                print(f"HIBP API error: {response.status_code}")
                return None
        
        except Exception as e:
            print(f"Error checking Have I Been Pwned: {e}")
            return None
    
    def comprehensive_investigation(self, target):
        """Run comprehensive OSINT investigation"""
        print(f"Starting comprehensive investigation for: {target}")
        
        # Determine if target is username, email, or domain
        if '@' in target:
            # Email investigation
            email = target
            domain = target.split('@')[1]
            username = target.split('@')[0]
            
            # Run investigations
            self.run_sherlock(username)
            self.run_theharvester(domain)
            self.check_haveibeenpwned(email)
        
        elif '.' in target and len(target.split('.')) > 1:
            # Domain investigation
            domain = target
            
            self.run_theharvester(domain)
            # Could also run Sherlock on domain name as username
            self.run_sherlock(domain.split('.')[0])
        
        else:
            # Username investigation
            username = target
            
            self.run_sherlock(username)
            # Could also check common email patterns
            common_domains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com']
            for domain in common_domains:
                email = f"{username}@{domain}"
                self.check_haveibeenpwned(email)
        
        return self.generate_comprehensive_report()
    
    def generate_comprehensive_report(self):
        """Generate comprehensive investigation report"""
        report = {
            'investigation_timestamp': datetime.now().isoformat(),
            'tools_used': self.tools_used,
            'results_summary': {},
            'detailed_results': self.results,
            'recommendations': []
        }
        
        # Summarize results
        if 'sherlock' in self.results:
            sherlock_accounts = 0
            for username, sites in self.results['sherlock'].items():
                for site, info in sites.items():
                    if info.get('status') == 'Claimed':
                        sherlock_accounts += 1
            
            report['results_summary']['sherlock'] = {
                'accounts_found': sherlock_accounts,
                'platforms_checked': len(sites) if 'sites' in locals() else 0
            }
        
        if 'theharvester' in self.results:
            harvester_data = self.results['theharvester']
            report['results_summary']['theharvester'] = {
                'emails_found': len(harvester_data.get('emails', [])),
                'hosts_found': len(harvester_data.get('hosts', []))
            }
        
        if 'haveibeenpwned' in self.results:
            hibp_data = self.results['haveibeenpwned']
            report['results_summary']['haveibeenpwned'] = {
                'breaches_found': hibp_data.get('breach_count', 0)
            }
        
        # Generate recommendations
        if report['results_summary'].get('sherlock', {}).get('accounts_found', 0) > 5:
            report['recommendations'].append("High social media presence detected - verify account authenticity")
        
        if report['results_summary'].get('haveibeenpwned', {}).get('breaches_found', 0) > 0:
            report['recommendations'].append("Email found in data breaches - recommend password changes")
        
        # Save report
        report_file = f"osint_investigation_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
        with open(report_file, 'w') as f:
            json.dump(report, f, indent=2)
        
        print(f"Comprehensive report saved: {report_file}")
        return report

def main():
    import sys
    
    if len(sys.argv) != 2:
        print("Usage: python3 osint-framework-sherlock.py <target>")
        print("Target can be: username, email, or domain")
        sys.exit(1)
    
    target = sys.argv[1]
    
    investigation = OSINTFrameworkIntegration()
    report = investigation.comprehensive_investigation(target)
    
    print("\nInvestigation Summary:")
    print("=" * 50)
    for tool, summary in report['results_summary'].items():
        print(f"{tool.upper()}:")
        for key, value in summary.items():
            print(f"  {key}: {value}")
    
    if report['recommendations']:
        print("\nRecommendations:")
        for rec in report['recommendations']:
            print(f"  - {rec}")

if __name__ == "__main__":
    main()

Best Practices and OPSEC

Operational Security

bash
#!/bin/bash
# sherlock-opsec-setup.sh

echo "Sherlock OPSEC Configuration"
echo "============================"

# Network security
echo "1. Network Security:"
echo "   □ Use VPN or proxy"
echo "   □ Rotate IP addresses"
echo "   □ Monitor for rate limiting"
echo "   □ Use Tor for sensitive investigations"

# Data security
echo -e "\n2. Data Security:"
echo "   □ Encrypt investigation results"
echo "   □ Use secure file permissions"
echo "   □ Regular cleanup of temporary files"
echo "   □ Secure storage of findings"

# Legal compliance
echo -e "\n3. Legal Compliance:"
echo "   □ Verify investigation authorization"
echo "   □ Document methodology"
echo "   □ Respect platform terms of service"
echo "   □ Follow local privacy laws"

# Technical measures
echo -e "\n4. Technical Measures:"
echo "   □ Use isolated investigation environment"
echo "   □ Monitor system resources"
echo "   □ Implement logging"
echo "   □ Regular tool updates"

Rate Limiting and Stealth

python
import time
import random
import subprocess

def stealth_sherlock_search(username, delay_range=(5, 15)):
    """Run Sherlock with stealth measures"""
    
    # Random delay before starting
    delay = random.uniform(delay_range[0], delay_range[1])
    print(f"Waiting {delay:.1f} seconds before search...")
    time.sleep(delay)
    
    # Run Sherlock with timeout and limited sites
    cmd = [
        "sherlock", username,
        "--timeout", "20",
        "--json", f"{username}_stealth.json",
        "--print-found"
    ]
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=600)
        
        if result.returncode == 0:
            print(f"Stealth search completed for {username}")
            return True
        else:
            print(f"Search failed: {result.stderr}")
            return False
    
    except subprocess.TimeoutExpired:
        print("Search timed out")
        return False
    except Exception as e:
        print(f"Error: {e}")
        return False

def batch_stealth_investigation(usernames, delay_range=(10, 30)):
    """Run batch investigation with stealth measures"""
    results = {}
    
    for i, username in enumerate(usernames):
        print(f"Processing {i+1}/{len(usernames)}: {username}")
        
        success = stealth_sherlock_search(username, delay_range)
        results[username] = success
        
        # Longer delay between users
        if i < len(usernames) - 1:
            delay = random.uniform(delay_range[0], delay_range[1])
            print(f"Waiting {delay:.1f} seconds before next user...")
            time.sleep(delay)
    
    return results

Troubleshooting

Common Issues and Solutions

bash
# Issue: No results returned
# Solution: Check internet connection and site availability
sherlock username --verbose

# Issue: Timeout errors
# Solution: Increase timeout value
sherlock username --timeout 30

# Issue: SSL/TLS errors
# Solution: Disable SSL verification (use with caution)
sherlock username --no-ssl-verify

# Issue: Proxy connection errors
# Solution: Verify proxy configuration
sherlock username --proxy http://proxy:8080 --verbose

# Issue: JSON output not generated
# Solution: Check file permissions and disk space
sherlock username --json results.json --verbose

Debug and Logging

python
import subprocess
import logging

# Enable debug logging
logging.basicConfig(level=logging.DEBUG)

def debug_sherlock_run(username):
    """Run Sherlock with debug information"""
    
    cmd = ["sherlock", username, "--verbose", "--debug"]
    
    try:
        result = subprocess.run(
            cmd, 
            capture_output=True, 
            text=True, 
            timeout=300
        )
        
        print("STDOUT:")
        print(result.stdout)
        print("\nSTDERR:")
        print(result.stderr)
        print(f"\nReturn code: {result.returncode}")
        
        return result.returncode == 0
    
    except Exception as e:
        print(f"Debug run failed: {e}")
        return False

Performance Optimization

bash
# Use specific sites for faster results
sherlock username --site GitHub --site Twitter --site Instagram

# Reduce timeout for faster scanning
sherlock username --timeout 5

# Use multiple processes for batch operations
parallel -j 4 sherlock {} --json {}.json ::: user1 user2 user3 user4

# Monitor system resources
htop  # Monitor CPU and memory usage during large investigations

Resources


This cheat sheet provides comprehensive guidance for using Sherlock for username investigations and social media OSINT. Always ensure proper authorization and legal compliance before conducting any investigations.