da7oom20/The-Leopard
GitHub: da7oom20/The-Leopard
面向 SOC 分析师的多 SIEM 统一 IOC 搜索与威胁狩猎自托管平台,支持并行查询多个 SIEM 并聚合 18 个威胁情报源进行一键狩猎。
Stars: 0 | Forks: 0
# Leopard
**多 SIEM 失陷指标搜索与威胁狩猎平台。**
_将其指向你的 SIEM。丢入 IOC。获取结果——或者得到证明你系统安全的寂静。_
[](#更新日志)
[](LICENSE)
[](docker-compose.yml)
[](docs/OFFLINE_INSTALL.md)
## 它是什么
The Leopard 是一个自托管控制台,它将跨主要 SIEM 平台的 IOC 搜索统一起来。你只需放入一个指标文件(或粘贴它们),选择一个或多个客户端,它会将查询并行分发到每个 SIEM,收集命中结果,并将结果归档到一个可搜索的存储库中。它还从 18 个威胁情报源提取实时指标,用于一键狩猎;并为默认字段映射与你使用的 schema 不匹配的部署提供字段发现工作流。
它是为不希望每个 SIEM 都使用单独操作面板的 SOC 分析师和威胁狩猎者构建的。使用 Node + React 编写,作为三个 Docker 容器发布。源代码树和所有运行时组件均采用 MIT 许可,并由操作员完全控制。
## 支持的 SIEM
| SIEM | 状态 | 单 SIEM 范围 |
| ---- | ------ | -------------- |
| **LogRhythm** | 已测试 | 单独的日志源 (queryLogSources),根实体分组 |
| **Splunk** | 已测试 | 索引 |
| **IBM QRadar** | 已测试 | 日志源 ID (`logsourceid IN (...)`) |
| **Elastic / ELK** | 实验性 | 索引模式 |
| **Wazuh** | 实验性 | 代理 (indexer DSL + manager alerts API) |
| **ManageEngine EventLog Analyzer** | 实验性 | `log_source_ids` |
每个适配器都接受相同的 `logSources: [...]` 选项,并在管理面板中按(客户端,IOC 类型)进行存储。留空映射将在每个适配器上回退为“扫描所有内容”。
## 支持的 IOC 类型
IP · 哈希 (MD5/SHA1/SHA256) · 域名 · URL · 电子邮件 · 文件名。解析器支持内联、逗号分隔的 IOC,支持从 PDF/XLSX/CSV/TXT 上传,以及反混淆形式(`hxxps://`、`evil[.]com` 等)。
## 威胁情报源
| 类别 | 平台 |
| -------- | --------- |
| API 平台 | AlienVault OTX, MISP, PhishTank |
| abuse.ch | ThreatFox, URLhaus, MalwareBazaar, Feodo Tracker, SSL Blacklist |
| IP 封锁列表 | Blocklist.de, Emerging Threats, Spamhaus DROP, FireHOL L1, Cisco Talos, CrowdSec |
| C2 与恶意软件 | C2 Intel Feeds, Bambenek C2, DigitalSide |
| 钓鱼 | OpenPhish |
## 屏幕截图
完整的屏幕截图集位于 [`screenshots/`](screenshots/)。
## 互联网、代理和三种安装路径
这是在企业环境中部署时被问得最多的问题,因此放在最前面。
### The Leopard 何时需要互联网?
- **在安装时**,Docker 构建需要连接到以下三处:
1. **Docker Hub** — 拉取 `mysql:8.0`、`node:20-slim`、`nginx:alpine`
2. **npm registry** — 在后端和前端构建阶段执行 `npm ci`
3. **Debian + Alpine 软件包镜像** — `apt-get install netcat-openbsd`(后端)和 `apk add openssl`(前端)
- **在运行时**,一旦堆栈运行起来,后端需要连接的唯一外部主机就是 **你的 SIEM 的 API**。如果 SIEM 与 The Leopard 位于同一管理 VLAN,则完全不需要互联网。从公共来源(OTX、abuse.ch 等)拉取的威胁情报源是可选的——如果你完全处于物理隔离环境中,可以在 Admin → TI Sources 下将其关闭。
### 三种安装路径,每种只需一条命令
选择与你的网络相匹配的路径。三种方式最终都会在 `https://
:3000` 启动。
#### 1. 直连互联网
主机可以直接访问 Docker Hub、npm 和 OS 包镜像。
```
make install
```
相当于 `scripts/install.sh --direct`,它封装了 `docker compose up -d --build`,并带有健康状态等待和清晰的最终状态行。首次构建需要几分钟,之后只需几秒钟。
#### 2. 通过 HTTP 代理(仅限安装时)
主机只能通过企业 HTTP 代理访问互联网。
```
make install-proxy PROXY=http://proxy.example.com:8080
# 如果需要,附带额外的 bypass 列表:
make install-proxy PROXY=http://proxy.example.com:8080 NO_PROXY=10.0.0.0/8,.corp.local
```
该代理**仅在**安装期间使用——用于镜像拉取和构建时的软件包安装。堆栈启动后,代理会在三个独立的位置被主动移除,因此它不会在运行时拦截 SIEM 请求或容器健康检查:
1. 一个**临时的 systemd drop-in** 被写入 `/etc/systemd/system/docker.service.d/leopard-install-proxy.conf`,以便 Docker 守护进程可以拉取基础镜像。构建完成后它会被删除并重启守护进程。
2. 代理作为显式的 `--build-arg` 标志传递给 `docker compose build`,以便 `npm ci` / `apt-get` / `apk add` 能够访问其仓库。这些构建参数仅保留在构建阶段——它们不会出现在最终镜像的运行时环境中。
3. `~/.docker/config.json` 中任何持久的 `proxies` 块都会**被备份并移除**——该块会导致 Docker 自动将代理环境变量注入到每个正在运行的容器中,这之前会导致后端的 SIEM 请求返回 `501 Not Implemented`,以及前端的 busybox-wget 健康检查命中 `503`。
为了双保险,`docker-compose.yml` 中的 `backend-v5` 和 `frontend-v5` 服务显式地将 `HTTP_PROXY` / `HTTPS_PROXY` / `http_proxy` / `https_proxy` 设置为空字符串,并声明了合理的 `NO_PROXY`。即使未来发生将代理泄漏到容器运行时的更改,也会在这里被覆盖。
安装后的验证(记录在 [`docs/OFFLINE_INSTALL.md`](docs/OFFLINE_INSTALL.md) 中):
```
systemctl show --property=Environment docker # must not contain the proxy
cat ~/.docker/config.json # must have no "proxies" key
docker exec ioc-backend-v5 env | grep -i proxy # must show empty HTTP_PROXY/http_proxy
```
#### 3. 完全物理隔离
目标主机在任何时候都没有互联网。只需在任何一台可以访问 Docker Hub 的机器上构建一个可移植的捆绑包,将压缩包传送到目标机器上,然后在那里运行安装程序即可。
```
# 在 online staging box 上:
make bundle
# -> dist/leopard-v-.tar.gz (+ .sha256 sidecar)
# 拷贝过来 (scp, USB, data diode),然后在离线目标上:
tar -xzf leopard-v-.tar.gz
cd leopard-v-
./install.sh
```
该捆绑包包含 `docker save` 生成的 `mysql:8.0`、后端和前端镜像的副本,以及 compose 文件、`.env.example`、完整的 `docs/` 文件夹和一个捆绑包内部的安装程序。在安装期间的任何时候,目标主机都不需要任何出站网络访问权限。
完整的参考资料、升级过程和单向数据二极管传输说明位于 [`docs/OFFLINE_INSTALL.md`](docs/OFFLINE_INSTALL.md)。
## 首次运行设置
首次启动时,`https://:3000` 会重定向到一个包含六个步骤的向导:
1. **欢迎** — 选择部署模式(单个 SIEM 或 MSSP/多客户端)。
2. **数据库** — 测试 MySQL 连接。默认配置开箱即用。
3. **SIEM 设置** — 添加你的第一个 SIEM 客户端:类型、API 主机、凭据、SSL 验证开关(对于自签名证书请保持关闭)。
4. **日志源** — 选择每种 IOC 类型应该查询哪些索引 / 日志源 / 代理。可选;可以跳过,但会有警告提示搜索将扫描所有源(速度较慢)。
5. **管理员用户** — 创建第一个支持 MFA 的管理员账户。
6. **完成** — 选择是否需要登录才能运行搜索,然后开始使用。
设置完成后,向导是幂等的——可以从 Admin → Setup Wizard 重新打开,并且会保留现有配置。
## 架构
三个 Docker 服务,一个内部网络,一个用于 MySQL 的共享卷。
```
┌────────────────────┐ ┌───────────────────┐ ┌──────────────┐
│ frontend-v5 │──────│ backend-v5 │──────│ mysql-v5 │
│ nginx + CRA build │ │ Node + Express │ │ mysql:8.0 │
│ :3000 (HTTPS) │ │ :4000 (internal) │ │ :3316→3306 │
│ :3080 (HTTP/health)│ │ │ │ (localhost) │
└────────────────────┘ └─────────┬─────────┘ └──────────────┘
│
outbound HTTPS (only to
your configured SIEMs
+ optional TI feeds)
```
- **前端**:React UI(Tailwind,IBM Plex + Fraunces 排版,编辑风格的深色 + 浅色主题),由 nginx 提供服务,并在首次启动时生成自签名证书。
- **后端**:REST API(`/api/auth`、`/api/setup`、`/api/admin`、`/api/recon`、`/api/hunt`、`/api/upload` 等)、单 SIEM 适配器、MsgSource 映射、结果存储、CSV/JSON 导出、结构化日志。
- **数据库**:MySQL 8,绑定到 localhost,启动时自动同步 schema。
完整 REST 接口请参见 [`docs/API.md`](docs/API.md)。
## 亮点
- **七个 SIEM 适配器**具有统一的查询约定。同一个 IOC 列表会生成 LogRhythm 的搜索任务、Splunk 的 SPL 作业、QRadar 的 AQL 搜索、Elastic DSL、Wazuh 索引器查询或 ManageEngine v2 搜索——无需针对特定适配器的 UI。
- **跨所有 SIEM 的日志源范围界定**。一个管理 UI,按(客户端,IOC 类型)进行复选框选择,并使用针对特定 SIEM 的术语(索引 / 日志源 / 代理)。留空映射依然有效——它只是意味着“扫描所有内容”。
- **LogRhythm 的实体根分组。** 72 个实体在过滤器中折叠为 16 个逻辑根(“HRC”标签涵盖了 HRC + HRC-Linux Devices + HRC-Security Controls + …)。
- **狩猎模式**:只需点击一下——选择一个 TI 源和 IOC 类型,选择客户端,它就会拉取最新的 IOC 并展开狩猎。
- **字段发现 (Recon)**:分析来自你 SIEM 的原始日志,以发现你的 schema 中实际包含 IOC 的字段,然后批准这些映射用于搜索。
- **结构化日志 + 故障排除手册**。每个生命周期事件(启动、设置过渡、狩猎分发、单 SIEM 查询、关闭)都会发出带有 `key=value` 上下文、带时间戳、带级别标签、带区域标签的日志行。Grep 技巧参见 [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md)。
- **内置安全性**:带有静默刷新的 JWT 会话、TOTP MFA、备份代码、加密凭据存储 (AES-256)、RBAC 权限、审计日志、速率限制、会话失效、helmet/CSP 标头、可选的用户提供的 TLS 证书。
- **浅色 + 深色编辑主题**,带有固定位置的切换开关——持久化到 localStorage,首次加载时遵循 `prefers-color-scheme` 设置。
- **三种安装路径**(直连、代理、离线捆绑包)——已在上面介绍。
## 配置
仓库中附带了一个 `.env.example`。你至少需要 `JWT_SECRET`(一个长随机字符串——如果你运行 `scripts/install.sh` 或 `scripts/install-from-bundle.sh`,安装程序会自动生成一个)。其他所有设置都有合理的默认值。
| 变量 | 默认值 | 用途 |
| -------- | ------- | ------- |
| `JWT_SECRET` | — (必填) | 会话令牌的 HMAC 密钥。至少 16 个字符。 |
| `ENCRYPTION_KEY` | 从 `JWT_SECRET` 派生 | 如果你希望将轮换与会话密钥解耦,可使用单独的密钥进行凭据加密。 |
| `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASSWORD` / `DB_NAME` | `mysql-v5` / 3306 / root / password / iocdb | 数据库连接。请在生产环境中进行更改。 |
| `DB_POOL_MAX` / `DB_POOL_MIN` | 50 / 5 | Sequelize 连接池大小设置。 |
| `PORT` | 4000 | 后端监听端口(容器内部)。 |
| `LOG_LEVEL` | `info` | 设置为 `debug` 以获取详细的适配器级别日志。别名 `DEBUG_LOG=1`。 |
| `CORS_ORIGIN` | 开发环境为 `*` | 在生产环境中限制来源。 |
完整表格:[`docs/USER_GUIDE.md`](docs/USER_GUIDE.md#configuration)。
### 默认端口
| 服务 | 端口 | 暴露情况 |
| ------- | ---- | ------- |
| 应用 (HTTPS) | 3000 | `0.0.0.0` |
| 应用 (HTTP 健康检查 + 重定向) | 3080 | `0.0.0.0` |
| MySQL | 3316 → 3306 | 仅 `127.0.0.1` |
| 后端 | 4000 | 内部 (compose 网络) |
## 运维
**日志**(所有容器写入标准输出;`docker compose logs` 是唯一的入口点):
```
docker compose logs -f backend-v5 # live tail
docker logs ioc-backend-v5 | grep '\[ERROR\]' # errors only
docker logs -f ioc-backend-v5 | grep -E 'hunt|SIEM search' # one hunt end-to-end
```
**状态**:每个容器都声明了原生的 Docker 健康检查;`docker compose ps` 会显示当前状态。后端暴露了 `/api/health`(公开)和 `/api/health?detail=true`(需管理员认证,返回进行中的请求计数 + 连接池状态)。
**常见问题**:症状 → 日志特征 → 修复表格位于 [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md)。涵盖了与代理相关的 501/503 错误、LogRhythm entity-API 400 错误、没有日志源映射的无声搜索、自签名 SIEM 上的 SSL 证书错误、关闭超时等问题。
**捆绑包更新**:在在线机器上构建新捆绑包,复制到目标机器,重新运行 `./install.sh`。镜像将重新加载,compose 会重新创建容器,不会丢失数据。
## 文档
- [`docs/USER_GUIDE.md`](docs/USER_GUIDE.md) — 最终用户工作流、功能演示、安全参考
- [`docs/API.md`](docs/API.md) — 完整的 REST 参考、请求 ID、错误类别
- [`docs/OFFLINE_INSTALL.md`](docs/OFFLINE_INSTALL.md) — 物理隔离 + 代理辅助安装、验证命令
- [`docs/PROXY_SETUP.md`](docs/PROXY_SETUP.md) — 历史代理/SSL/SIEM 映射修复日志(如果遇到边缘情况时的有用参考)
- [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) — 日志阅读指南 + 症状表格
## 开发
```
git clone https://github.com/da7oom20/The-Leopard.git
cd The-Leopard
make install # or scripts/install.sh --direct
# dev loops
docker compose logs -f # tail all services
docker compose build # rebuild after code changes
docker compose up -d # recreate containers
# clean rebuild
docker compose down -v # drops MySQL volume — wipes data!
docker compose up -d --build
```
后端代码是普通的 CommonJS Node 配合 Sequelize。前端是 CRA + React Router + Tailwind(扩展了编辑风格令牌——参见 `frontend/tailwind.config.js`)。没有使用 TypeScript,除了 `react-scripts` 和 Dockerfiles 处理的内容之外,没有其他构建步骤的复杂性。
### 添加 SIEM 适配器
1. 继承 `server/siem-adapters/base.adapter.js` — 实现 `testConnection`、`buildQuery`、`executeSearch`、`pollResults`(异步 SIEM)、`getLogSources`、`buildReconQuery`、`normalizeResults`。
2. 在 `buildQuery` 选项中接受 `logSources: [{id, listId, name}]`,并据此界定查询范围。
3. 在 `server/siem-adapters/index.js` 中注册适配器。
4. 在 `frontend/src/pages/AdminPage.jsx` 的 `SIEM_CONFIGS` 中添加针对该 SIEM 的配置块(字段、标签、占位符)。
5. 如果你需要模板化功能,请在 `admin.js` 的 `siem-defaults` 处理程序中添加一个默认查询模板行。
现有的六个适配器是你的参考实现。
## 安全
完整模型请参见 [`docs/USER_GUIDE.md#security`](docs/USER_GUIDE.md)。摘要如下:
- JWT 会话 (HS256),60 分钟过期,在过期前 5 分钟静默刷新。
- TOTP MFA,带有兼容 Google-Authenticator 的二维码设置和八个一次性备份码。
- 所有存储的凭据(SIEM API 密钥、TI 密钥、MFA 密钥)均使用从 `JWT_SECRET`(或单独设置的 `ENCRYPTION_KEY`)派生的密钥通过 AES-256-GCM 加密。
- RBAC:九项细粒度权限(搜索、狩猎、导出、查看仓库、管理 SIEM/TI/映射/用户/安全)。
- 每个管理员操作的审计日志。
- 对登录、搜索和狩猎端点进行速率限制。
- nginx 上的 helmet + CSP + X-Frame-Options DENY + HSTS。
- 可选的自定义 TLS 证书上传,用于前端(放入 .crt + .key;无需重新构建)。
请通过 GitHub 私下向仓库所有者报告漏洞。
## 许可证
在 MIT 许可证下发布。参见[许可证](LICENSE)。
简而言之:只要你保留版权声明,你可以对代码做任何你想做的事,包括商业用途。无任何担保。
## 致谢
由 **Abdulrahman Almahameed** ([@da7oom20](https://github.com/da7oom20)) 开发和维护。
欢迎提交 Pull requests、Issues 和建议。标签:AMSI绕过, Docker容器化, GNU通用公共许可证, IOC搜索, IP 地址批量处理, IT运维安全, LogRhythm, ManageEngine, MITM代理, MIT协议, Node.js, QRadar, React, SOC分析平台, Syscalls, Wazuh, 多SIEM集成, 失陷标示分析, 威胁情报, 威胁检测, 安全分析平台, 安全运营, 库, 应急响应, 开发者工具, 开源安全工具, 扫描框架, 插件系统, 无线安全, 离线部署, 网络安全, 自动化安全分析, 自定义脚本, 自托管平台, 请求拦截, 逆向工程平台, 隐私保护