Sherlock.Net
0.16.0
dotnet add package Sherlock.Net --version 0.16.0
NuGet\Install-Package Sherlock.Net -Version 0.16.0
<PackageReference Include="Sherlock.Net" Version="0.16.0" />
<PackageVersion Include="Sherlock.Net" Version="0.16.0" />
<PackageReference Include="Sherlock.Net" />
paket add Sherlock.Net --version 0.16.0
#r "nuget: Sherlock.Net, 0.16.0"
#:package Sherlock.Net@0.16.0
#addin nuget:?package=Sherlock.Net&version=0.16.0
#tool nuget:?package=Sherlock.Net&version=0.16.0
<p align="center"> <br> <img src="https://user-images.githubusercontent.com/27065646/53551960-ae4dff80-3b3a-11e9-9075-cef786c69364.png" width="200"/> <br> <b>Sherlock.Net</b> <br> <i>Hunt down social media accounts by username across 400+ social networks</i> <br> <i>A .NET port of the <a href="https://github.com/sherlock-project/sherlock">Sherlock Project</a></i> <br> </p>
<p align="center"> <a href="https://dotnet.microsoft.com/download/dotnet/10.0"><img src="https://img.shields.io/badge/.NET-10.0-512BD4?logo=dotnet" alt=".NET 10.0"></a> <a href="https://github.com/totpero/Sherlock.Net/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue" alt="License: Apache 2.0"></a> <a href="https://totpero.github.io/Sherlock.Net/"><img src="https://img.shields.io/badge/docs-GitHub%20Pages-brightgreen" alt="Documentation"></a> </p>
About
Sherlock.Net is a cross-platform .NET rewrite of the popular Sherlock Python tool. It searches for usernames across 400+ social networks simultaneously, using parallel async HTTP requests for fast results.
Why .NET?
- Native cross-platform binary (Windows, Linux, macOS)
- High-performance async I/O with
IAsyncEnumerablestreaming - Connection pooling via
IHttpClientFactory(no socket exhaustion) - Clean architecture: use as a CLI tool or reference
Sherlock.Net.Coreas a library
Installation
Prerequisites
- .NET 10.0 SDK or later
Install as .NET tool (recommended)
Install globally as a .NET tool — this makes the sherlock command available everywhere in your terminal:
dotnet tool install --global Sherlock.Net.Cli
After installation, simply run:
sherlock user123
To update to the latest version:
dotnet tool update --global Sherlock.Net.Cli
To uninstall:
dotnet tool uninstall --global Sherlock.Net.Cli
Note: Make sure
~/.dotnet/tools(Linux/macOS) or%USERPROFILE%\.dotnet\tools(Windows) is in yourPATH. The .NET SDK adds this automatically on first tool install, but you may need to restart your terminal.
Build from source
git clone https://github.com/totpero/Sherlock.Net.git
cd Sherlock.Net
dotnet build
Run directly from source (without installing):
dotnet run --project src/Sherlock.Net.Cli -- <username>
Publish as single executable
dotnet publish src/Sherlock.Net.Cli -c Release -r win-x64 --self-contained
dotnet publish src/Sherlock.Net.Cli -c Release -r linux-x64 --self-contained
dotnet publish src/Sherlock.Net.Cli -c Release -r osx-arm64 --self-contained
Quick Start
# Install the tool globally
dotnet tool install --global Sherlock.Net.Cli
# Search for a username across 400+ sites
sherlock johndoe
# Search multiple usernames and export to CSV
sherlock --csv johndoe janedoe
# Search only on GitHub and Twitter
sherlock --site GitHub --site Twitter johndoe
Usage
Search for a single username
sherlock user123
Search for multiple usernames
sherlock user1 user2 user3
Limit to specific sites
sherlock --site GitHub --site Twitter user123
Export results
sherlock --txt user123 # Save to user123.txt
sherlock --csv user123 # Save to user123.csv
sherlock --json-export user123 # Save to user123.json
Use a proxy or Tor
sherlock --proxy socks5://127.0.0.1:9050 user123
Username wildcards
Use {?} to try common separator variants (_, -, .):
sherlock john{?}doe
# Searches: john_doe, john-doe, john.doe
Command-Line Options
USAGE:
sherlock <USERNAMES> [OPTIONS]
ARGUMENTS:
<USERNAMES> One or more usernames to search for
OPTIONS:
DEFAULT
-h, --help Prints help information
-v, --version Prints version information
--timeout <SECONDS> 60 Time in seconds to wait for response
--proxy <URL> Proxy URL (e.g., socks5://127.0.0.1:9050 for Tor)
--site <NAME> Limit search to specific site(s)
--json <PATH_OR_URL> Custom data.json file path or URL
--csv Export results as CSV
--txt Export results as TXT
--json-export Export results as JSON
-o, --output <DIR> Output directory for export files
--print-all Show all results, not just found accounts
--nsfw Include NSFW sites in search
-b, --browse Open found URLs in default browser
--no-color Disable colored output
--concurrency <COUNT> 20 Maximum concurrent requests
Project Structure
Sherlock.Net/
├── src/
│ ├── Sherlock.Net.Core/ # Class library (models, services, exporters)
│ │ ├── Models/ # SiteData, QueryResult, QueryStatus, SherlockOptions
│ │ ├── Serialization/ # JSON converters for data.json quirks
│ │ ├── Services/ # SiteChecker, SherlockService, WafDetector
│ │ └── Resources/ # Embedded data.json (400+ sites)
│ │
│ └── Sherlock.Net.Cli/ # Console app (thin CLI layer)
│ ├── Commands/ # SearchCommand, SearchCommandSettings
│ └── Rendering/ # Spectre.Console colored output
│
└── tests/
└── Sherlock.Net.Core.Tests/ # xUnit tests + JSON Schema validation
Architecture
| Component | Responsibility |
|---|---|
SiteDataProvider |
Loads site definitions from embedded resource, URL, or file |
SiteChecker |
Executes HTTP requests and applies detection logic per site |
SherlockService |
Orchestrates parallel checks with Channel<T> + SemaphoreSlim |
WafDetector |
Identifies WAF blocks (Cloudflare, PerimeterX, Akamai) |
IResultExporter |
Exports results to TXT, CSV, or JSON |
Detection Mechanisms
Each site in data.json uses one of three detection strategies:
| Type | How it works |
|---|---|
| StatusCode | HTTP 404 or specific error code = username not found |
| Message | Response body contains error string(s) = username not found |
| ResponseUrl | Server redirects to a different URL = username not found |
Using as a Library
Reference Sherlock.Net.Core in your project to integrate username searching programmatically:
dotnet add package Sherlock.Net.Core
Minimal usage (no DI container)
The simplest way — one static call, no ServiceCollection, no setup:
using Sherlock.Net.Core;
using Sherlock.Net.Core.Models;
// Search across all 400+ sites with a single call
await foreach (var result in SherlockFactory.SearchAsync("johndoe"))
{
if (result.Status == QueryStatus.Claimed)
Console.WriteLine($"[+] {result.SiteName}: {result.ProfileUrl}");
}
With options:
await foreach (var result in SherlockFactory.SearchAsync("johndoe", options =>
{
options.Timeout = TimeSpan.FromSeconds(30);
options.MaxConcurrency = 10;
options.SiteFilter = ["GitHub", "Twitter", "Instagram"];
}))
{
if (result.Status == QueryStatus.Claimed)
Console.WriteLine($"[+] {result.SiteName}: {result.ProfileUrl}");
}
If you need more control (e.g., custom data.json source), use SherlockFactory.Create():
var (sherlock, siteProvider) = SherlockFactory.Create();
var sites = await siteProvider.LoadSitesAsync("path/to/custom-data.json");
await foreach (var result in sherlock.SearchAsync("johndoe", sites, new SherlockOptions()))
{
// ...
}
With DI container (AddSherlock)
Register all services with a single call to AddSherlock():
using Microsoft.Extensions.DependencyInjection;
using Sherlock.Net.Core;
using Sherlock.Net.Core.Models;
using Sherlock.Net.Core.Services;
var services = new ServiceCollection();
services.AddSherlock();
var provider = services.BuildServiceProvider();
var siteDataProvider = provider.GetRequiredService<ISiteDataProvider>();
var sherlockService = provider.GetRequiredService<ISherlockService>();
var sites = await siteDataProvider.LoadSitesAsync();
var options = new SherlockOptions { MaxConcurrency = 20 };
await foreach (var result in sherlockService.SearchAsync("johndoe", sites, options))
{
if (result.Status == QueryStatus.Claimed)
Console.WriteLine($"[+] {result.SiteName}: {result.ProfileUrl}");
}
Custom configuration
Use the lambda overload to configure defaults:
services.AddSherlock(options =>
{
options.UserAgent = "MyApp/1.0";
options.Timeout = TimeSpan.FromSeconds(30);
options.MaxConcurrency = 10;
options.ProxyUrl = "socks5://127.0.0.1:9050";
options.IncludeNsfw = false;
});
ASP.NET Core / Hosted services
AddSherlock() integrates with standard .NET dependency injection:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSherlock(options =>
{
options.Timeout = TimeSpan.FromSeconds(15);
options.MaxConcurrency = 5;
});
var app = builder.Build();
app.MapGet("/search/{username}", async (string username,
ISiteDataProvider siteDataProvider, ISherlockService sherlockService) =>
{
var sites = await siteDataProvider.LoadSitesAsync();
var results = new List<object>();
await foreach (var result in sherlockService.SearchAsync(username, sites, new SherlockOptions()))
{
if (result.Status == QueryStatus.Claimed)
results.Add(new { result.SiteName, result.ProfileUrl });
}
return Results.Ok(results);
});
app.Run();
Running Tests
dotnet test
Tests include JSON Schema validation of data.json against the upstream data.schema.json.
Acknowledgements
This project is a .NET port of Sherlock, originally created by Siddharth Dushantha and maintained by the Sherlock Project community. The site database (data.json) is sourced directly from the upstream project.
License
Apache 2.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.14)
- Microsoft.Extensions.Http (>= 9.0.14)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.16.0 | 46 | 4/7/2026 |