user-scanner

命令行工具

kaifcodec/user-scanner

深度邮箱与用户名 OSINT 套件,支持 465+ 扫描向量。

项目简介

User Scanner 是一款基于 Python 的 OSINT 套件,面向安全研究与调查。可扫描 465+ 个活跃平台,提取元数据、验证账号注册,并通过句柄与邮箱自动关联扩展。支持交叉扫描、代理轮换、多格式报告以及用于 AI 代理集成的 MCP 服务器。

README 预览

# User Scanner\n\n\n  \n\n\n\n  \n  \n  \n  \n  \n  \n  \n     \n  \n\n\n\n  \n    \n  \n\n\n---\n\nA powerful **2-in-1 OSINT suite** engineered for deep **Email and Username Intelligence**.\n\nWith **465+ total scan vectors**—including **175+ email-integrated sites** and **290+ username platforms**—you can map digital footprints, analyze target behavior, uncover interests, full metadata of usernames and verify account registrations in seconds.\n\n---\n\n## 💖 Sponsored by\n\n\n  \n    \n  \n  \n  Go beyond account enumeration. WebVetted turns an email or username into a complete identity investigation with deep OSINT enrichment, breach intel, AI analysis, and an interactive identity graph.\n  \n  Start an Investigation →\n\n\n---\n\n\n  \n    \n  \n  \n  Comprehensive OSINT platform for professional investigators and analysts. Reverse email, phone number, and username search across 250+ modules. Automate your intelligence gathering with our powerful tools.\n  \n  Get Started →\n\n\n---\n\n## ✨ Key Features\n\n- 🔎 **Deep Email & Username OSINT:** Look up email registrations and perform advanced username profiling across 465+ platforms.\n- 👤 **Rich Metadata Scraping:** Scrapes avatars, bio descriptions, follower counts, UID numbers, seller statuses, and account attributes.\n- 🔀 **Cross-Scan & Pivot Engine:** Mines handles, profile links, and exposed email addresses from initial scans, automatically pivoting across secondary target vectors.\n- 🤖 **Model Context Protocol (MCP) Server:** Native AI agent integration for Claude Desktop, Cursor, Antigravity, and LLMs to run autonomous OSINT scans and recursive pivots.\n- 🛡️ **Hudson Rock Infostealer Breach Intel:** Query infostealer malware breach logs using the `--hudson` flag for high-priority target correlation.\n- ⚡ **High-Throughput Parallel Engine:** Powered by `httpx` and `curl_cffi` for maximum concurrency with automated TLS fingerprint impersonation.\n- 🔀 **Permutation & Alias Generator:** Wildcard-based use

常见问题 (5)

故障排除
当用户名或电子邮件中包含 &、#、%、+、空格或非 ASCII 字符时,如何修复 Python URL 查询字符串中损坏或不正确的 API 请求?

不要将原始的用户可控值直接插入 f-string URL 中。使用 urllib.parse.quote 对每个查询值进行百分号编码:

from urllib.parse import quote

url = f"{base_url}{endpoint}?{param}={quote(target, safe='')}"
api_url = f"https://www.instagram.com/api/v1/users/web_profile_info/?username={quote(user, safe='')}"

对于多个参数,优先使用 urlencode:

from urllib.parse import urlencode

params = {"username": user, "email": email}
url = f"{base_url}{endpoint}?{urlencode(params)}"

审计所有 f-string 查询 URL,包括 core/、email_scan/ 和 user_scan/ 下的模块,并对每个插值的 user、username、email、target 或类似值进行编码。仅对参数值进行编码,而不是对整个 URL 编码。添加回归测试,使用包含 &、#、%、+、空白字符和非 ASCII 字符的输入。现有的 leetcode.py 中 urllib.parse.quote() 的用法可作为参考模式。

来源 Issue #574
故障排除
为什么当并发数设置为 0 并配合 -C 或 MCP 使用时,user-scanner 会挂起?

将并发数设置为 0 会创建 asyncio.Semaphore(0),导致每个模块在其各自的超时计时开始之前无限期等待。在 MCP 模式下,这还会持有扫描锁并阻塞队列。作为受影响版本(包括 1.5.2.1)的临时解决方案,请以正的并发值运行扫描,例如 -C 1,或设置 MAX_CONCURRENT_REQUESTS=1;请勿使用 0 或负值。该修复在 CLI/MCP 边界以及 orchestrator.set_concurrency 和 email_orchestrator.set_concurrency 两处均添加了验证,对小于 1 的值抛出 ValueError,并在 MCP schema 中加入 minimum: 1。请升级到包含该修复的版本,以便对用户名和电子邮件扫描实现早期且一致的验证。

来源 Issue #690
故障排除
如何修复 user-scanner 中 PDF 媒体下载绕过通过 `-P`/`--proxy-file` 配置的代理的问题?

此问题已在 PR #692 中修复。在版本 1.5.2.1(提交 780d077a468035c6afd6b4a0f987317db651528b)中,pdf_generator.fetch_and_resize_image() 直接调用 httpx.get()。在 httpx 0.28.1 下,这会创建一个 proxy=None 的客户端,因此通过 get_proxy()/set_proxy_manager() 配置的代理不会被使用,PDF 图像请求可能会泄露操作者的 IP。

升级到包含 PR #692 的版本,或从源代码应用该补丁:

git fetch origin pull/692/head:pr-692
git checkout pr-692
python -m pip install -e ".[pdf]"

该补丁通过 get_proxy() 路由 PDF 媒体下载,遵循 get_global_timeout(),并且在代理失败时不会静默回退到直接连接。通过设置一个不可达的代理(例如 http://127.0.0.1:1)来验证修复:媒体下载应当失败或被跳过,且目标服务器不得收到任何直接请求。如果维护一个 fork,请将 user_scanner/core/pdf_generator.py 中直接调用的 httpx.get() 替换为扫描器共享的代理请求辅助函数,或使用 get_proxy() 和 get_global_timeout() 的显式客户端。

来源 Issue #688
故障排除
如何修复多站点 user-scanner 扫描中 warmup_url 仅在第一个站点运行的问题?

此问题影响 commit 780d077a468035c6afd6b4a0f987317db651528b 对应的 user-scanner 1.5.2.1。_warmed 缓存仅以 (impersonate, proxy) 作为键,因此针对某一个 origin 的成功预热会将共享会话标记为对所有其他 origin 均已预热,尽管 clearance cookie 是特定于站点的。

修复方法:升级到包含 PR #680 的 main 分支版本,该 PR 在受影响的 commit 之后两个 commit 处被合并:

python -m pip install -U git+https://github.com/kaifcodec/user-scanner.git@main

如果是基于 checkout 进行操作:

git pull origin main
python -m pip install -e .

如果无法升级,请 cherry-pick 或合并 PR #680。修复必须将会话/浏览器加上 warmup_url 或 origin 特定的 clearance 上下文作为预热状态的作用域,而不能仅按浏览器/代理划分。失败的预热必须保持可重试,且不得清除其他站点的状态。作为临时变通方案,可在独立的进程中分别运行每个 origin,使共享的 _warmed 集合不会跨站点复用。

验证方法:使用同一浏览器且不使用代理,请求两个不同的 origin:每个 origin 应在其正常请求之前各自发送一次自己的预热请求;重复请求应复用已预热的状态;并发或失败的预热应能被安全处理。

来源 Issue #689
故障排除
如何修复 user-scanner Screener 对每个电子邮件地址都返回“Unexpected response body structure”的问题?

在 v1.5.1 中,screener.in 将其错误标记从 <ul class="errorlist"> 更改为 <ul class="errorlist" id="id_password_error">,因此 email_scan/other/screener.py 中的精确字符串检查会失败。请将第 68 行附近的标记检查替换为可容忍额外属性的正则表达式:

import re

_REQUIRED = re.compile(r'<ul class="errorlist"[^>]*>\s*<li>This field is required\.</li>')

if _REQUIRED.search(res_text):
    return Result.available(url=show_url)

之前的检查是:

if '<ul class="errorlist"><li>This field is required.</li>' in res_text:
    return Result.available(url=show_url)

修补已安装的包文件后,重新运行:

user-scanner -e john.smith.4471@gmail.com -m screener --all

taken 分支很可能不受影响,因为它匹配的是纯文本 User account with this Email already exists。如果要维护该模块,还应针对缺失 CSRF/token 和无法分类的 POST 响应使用单独的错误消息,以便将来更容易诊断标记更改。

来源 Issue #611