nodirsafarov/userhunt
GitHub: nodirsafarov/userhunt
一个基于 Go 的高性能跨平台用户名枚举工具,可在 180+ 平台快速定位目标数字足迹,速度远超同类 Python 工具。
Stars: 0 | Forks: 0
userhunt
跨 180+ 平台的快速 OSINT 用户名枚举工具。
单个 Go 二进制文件。10 秒内完成安装。精美的彩色输出。Go 版 Sherlock。
$ userhunt torvalds --only-found
[+] GitHub https://github.com/torvalds
[+] GitLab https://gitlab.com/torvalds
[+] HackerNews https://news.ycombinator.com/user?id=torvalds
[+] Reddit https://www.reddit.com/user/torvalds
[+] Keybase https://keybase.io/torvalds
...
Found: 80+ / 180+ platforms — under 15s
## 为什么选择 userhunt?
| | [Sherlock](https://github.com/sherlock-project/sherlock) | **userhunt** |
|---|---|---|
| 语言 | Python | **Go** |
| 安装 | `pip install` + Python 运行时 | `go install` 或单个二进制文件,**零依赖** |
| 并发 | 线程 (较慢) | **Goroutines,500+ 并行** |
| 速度 (100 个站点) | 约 4–6 分钟 | **约 15–25 秒** (快 10 倍以上) |
| 检测方式 | 仅状态码 | **状态码 + 内容标记 + 智能启发式** |
| 输出 | 纯文本 | **彩色 TUI + 进度条** |
| 导出 | TXT | **JSON,CSV,Markdown** |
| 多目标 | 每次一个 | **单次运行批量查询用户名** |
| 过滤器 | 无 | **类别,NSFW 开关** |
| 重试 | 无 | **指数退避** |
| 代理 / UA | 有限 | **完整的 HTTP(S) 代理 + UA 轮换** |
## 安装
### Go (推荐)
```
go install github.com/nodirsafarov/userhunt/cmd/userhunt@latest
```
### 预编译二进制文件
从 [releases 页面](https://github.com/nodirsafarov/userhunt/releases) 获取适合您操作系统/架构的二进制文件。
```
# Linux x86_64
curl -L https://github.com/nodirsafarov/userhunt/releases/latest/download/userhunt_Linux_x86_64.tar.gz | tar xz
sudo mv userhunt /usr/local/bin/
```
### 从源码构建
```
git clone https://github.com/nodirsafarov/userhunt
cd userhunt
make build
./bin/userhunt --help
```
## 快速开始
```
# 在所有 100+ 平台中搜寻单个用户名
userhunt torvalds
# 仅显示找到的账号(用于报告的简洁输出)
userhunt torvalds --only-found
# 单次运行多个用户名
userhunt torvalds linus linus_torvalds --only-found
# 导出为 JSON / CSV / Markdown
userhunt torvalds -o report.json
userhunt torvalds -o report.csv
userhunt torvalds -o report.md
userhunt torvalds -o "{user}_report.json" # template: {user} -> username
# 按类别过滤 (tech, social, gaming, security, music, video, ...)
userhunt torvalds --category security
# 在快速网络中提高并发数
userhunt torvalds --concurrency 200 --timeout 5s
# 通过代理 (Burp / mitmproxy) 进行管道传输
userhunt torvalds --proxy http://127.0.0.1:8080
```
### 列出所有平台和类别
```
userhunt --list
```
## 示例输出
```
Hunting @torvalds across 103 platforms...
[+] GitHub https://github.com/torvalds
[+] GitLab https://gitlab.com/torvalds
[+] HackerNews https://news.ycombinator.com/user?id=torvalds
[+] Reddit https://www.reddit.com/user/torvalds
[+] Keybase https://keybase.io/torvalds
[+] Medium https://medium.com/@torvalds
[+] Last.fm https://www.last.fm/user/torvalds
[+] Steam https://steamcommunity.com/id/torvalds
...
──────────────────────────────────────────────
Target: torvalds
Found: 55 / 103 platforms
Errors: 15
Time: 17.0s
──────────────────────────────────────────────
```
## 参数说明
| 参数 | 缩写 | 默认值 | 描述 |
|---|---|---|---|
| `--timeout` | `-t` | `15s` | 单次请求超时时间 |
| `--concurrency` | `-c` | `50` | 并行 worker 数量 |
| `--retries` | | `1` | 每个平台的重试次数 |
| `--user-agent` | | rotating | 自定义 User-Agent |
| `--proxy` | | | HTTP(S) 代理 URL |
| `--output` | `-o` | | 将报告写入文件 |
| `--format` | `-f` | inferred | `json`、`csv` 或 `md` |
| `--only-found` | | `false` | 隐藏未找到/错误的行 |
| `--category` | | | 限制为单一类别 |
| `--list` | | | 列出平台 / 类别 |
| `--include-nsfw` | | `false` | 包含 NSFW 平台 |
| `--no-color` | | `false` | 禁用彩色输出 |
| `--no-banner` | | `false` | 隐藏 ASCII banner |
| `--silent` | `-s` | `false` | 无 banner、无进度条、无实时输出行 |
| `--fail-if-not-found` | | `false` | 如果未找到任何账户则退出码为 `2` |
## 使用场景
- **OSINT** — 调查数字足迹,绘制目标在线存在情况。
- **Bug 赏金 / 渗透测试侦察** — 在项目期间快速发现攻击面。
- **CTF** — 在涉及 OSINT 的挑战赛中寻找跨平台突破口。
- **个人审计** — 在推出品牌之前,查看您自己的用户名已在哪些平台注册。
## 检测原理
对于每个平台,userhunt 会选择以下两种策略之一(在 [`internal/platforms/platforms.json`](internal/platforms/platforms.json) 中声明):
- **`status`** — `200 OK` ⇒ 存在,`404` / `410` ⇒ 不存在,其他 ⇒ 错误。
- **`content`** — 获取页面并查找标记子串。如果存在 `exists_content` 标记 ⇒ 存在。如果存在 `not_exists_content` 标记 ⇒ 不存在。这对于始终返回 `200` 的 SPA 页面非常有用。
这两种策略都可以与 **`not_exists_final_url`** 结合使用 —— 如果响应的最终 URL(重定向后)包含任何配置的子串(`/login`、`/sorry`、`/404` 等),则将该账户视为未找到。这可以消除大量因网站静默重定向不存在用户而产生的误报。
HTTP 客户端使用 HTTP/2、keep-alive、连接池、带指数退避的重试以及一组不断轮换的真实浏览器 User-Agent。每次探测最多读取 256 KiB 的主体内容,因此即使对 SPA 密集型站点也能保持高速。
## 添加新平台
编辑 [`internal/platforms/platforms.json`](internal/platforms/platforms.json) 并添加新对象:
```
{
"name": "Example",
"url": "https://example.com/u/{}",
"category": "social",
"check_type": "status"
}
```
对于 SPA / JS 密集型站点,建议使用 `content` 模式:
```
{
"name": "MySPA",
"url": "https://myspa.com/{}",
"category": "social",
"check_type": "content",
"not_exists_content": ["User not found", "404"]
}
```
对于静默将缺失用户重定向(至登录页或主页)而不返回 `404` 的站点,可结合 `not_exists_final_url` 使用:
```
{
"name": "RedirectorSite",
"url": "https://example.com/profile/{}",
"category": "social",
"check_type": "status",
"not_exists_final_url": ["/login", "/sorry", "/404"]
}
```
欢迎提交 PR —— 参见 [贡献指南](#contributing)。
## 作为库使用
userhunt 也可以在 Go 程序中导入使用:
```
import (
"context"
"github.com/nodirsafarov/userhunt/internal/checker"
"github.com/nodirsafarov/userhunt/internal/platforms"
)
func scan(username string) error {
list, err := platforms.Load()
if err != nil {
return err
}
chk, err := checker.New(checker.Options{Concurrency: 100})
if err != nil {
return err
}
for r := range chk.Run(context.Background(), username, list) {
if r.Status == checker.StatusFound {
// r.URL holds the matched profile URL
}
}
return nil
}
```
## 路线图
- [ ] `--watch` 持续监控并输出差异报告
- [ ] Avatar / 头像提取
- [ ] 带有屏幕截图的 HTML 报告
- [ ] 更多平台 (目标: 250+)
- [ ] 域名 / 邮箱模式 (`userhunt-domain`,`userhunt-email`)
- [ ] 用于自定义检查器的 Plugin API
## 法律与道德声明
userhunt 旨在用于**合法的 OSINT、安全研究和个人侦察**。您有责任遵守每个平台的服务条款以及您所在地的法律。请勿使用 userhunt 进行骚扰、跟踪或在未授权的情况下针对个人的任何活动。
## 致谢
- 灵感来源于 [Sherlock](https://github.com/sherlock-project/sherlock)。
- 使用 [cobra](https://github.com/spf13/cobra)、[fatih/color](https://github.com/fatih/color) 和 [progressbar](https://github.com/schollz/progressbar) 构建。
## 许可证
[MIT](LICENSE) © Nodir Safarov
标签:ESC4, ESC8, EVTX分析, Go语言, OSINT, Sherlock替代, 信息 footprint, 并发爬虫, 数据包嗅探, 数据导出, 日志审计, 用户名枚举, 社会工程学, 程序破解, 网络安全, 账户发现, 跨平台查询, 隐私保护, 黑盒测试