Appearance
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
Popular Social Media Platforms
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
- Sherlock GitHub Repository
- Sherlock Documentation
- OSINT Framework
- Social Media OSINT Guide
- Username Investigation Techniques
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.