JehanPatel/Palantir-OSINT
GitHub: JehanPatel/Palantir-OSINT
一个无状态的实时 OSINT/CTI 聚合平台,将多源公开情报数据统一为交互式实体关系图以辅助安全调查分析。
Stars: 1 | Forks: 0
# 🔍 Palantir OSINT
**一个受 Palantir Gotham 启发的无状态、实时安全调查平台。**
实时处理非结构化数据,将其链接为交互式实体关系图,并将地理空间发现投影到 3D 地球仪上 —— 全程使用免费的开源数据节点且无需任何数据库存储。
## 目录
1. [功能](#features)
2. [架构](#architecture)
3. [技术栈](#tech-stack)
4. [项目结构](#project-structure)
5. [安装说明](#setup-instructions)
- [后端 (Python/FastAPI)](#backend-pythonfastapi)
- [前端 (React/Vite)](#frontend-reactvite)
6. [使用指南](#usage-guide)
7. [API 参考](#api-reference)
8. [数据结构](#data-schema)
9. [使用的外部 API](#external-apis-used)
10. [无状态设计理念](#stateless-design-philosophy)
11. [故障排除](#troubleshooting)
## 功能
### 🔬 多源 OSINT 聚合
只需输入一个查询条件,即可**并发**向五个免费的公共 API 发起请求:
| 来源 | 提供的数据 | Endpoint |
|--------|--------------|----------|
| **GDELT DOC API v2** | 全球新闻事件、主题、组织、位置 | `gdeltproject.org/api/v2/doc/doc` |
| **AlienVault OTX** | 威胁 pulse、攻击者组织、恶意软件家族、IOC | `otx.alienvault.com/api/v1/pulses/subscribed` |
| **Pulsedive** | 指标威胁评分、风险等级、威胁情报源 | `pulsedive.com/api/indicators.php` |
| **AbuseIPDB** | IP 信誉、滥用置信度评分、报告历史 | `api.abuseipdb.com/api/v2/check` |
| **Nominatim (OSM)** | 地理编码 —— 将地名解析为经纬度坐标 | `nominatim.openstreetmap.org/search` |
### 🧠 实体关系图(左侧面板)
- 基于 **Cytoscape.js** 的交互式有向图
- 节点按类型用颜色编码:`Event`(琥珀色)、`ThreatActor`(红色)、`Indicator`(蓝色)、`Vulnerability`(橙色)、`Location`(绿色)、`Organization`(紫色)
- 边标记有关系类型:`ATTACKED`、`CONTROLS`、`LOCATED_IN`、`CORRELATES_WITH`、`MENTIONS`
- 点击节点以高亮显示其整个邻域
- 自由拖拽、缩放、平移图表
### ↔️ 可拖拽的分屏布局
- (前端)最初的演示版包含带有可拖动分隔线的分屏布局。
- 当前版本主要专注于**实体图**的分析工作流(地理空间视图已移除)。
### ⚡ 完全无状态的后端
- 零数据库(没有 SQLite、没有 PostgreSQL、没有 Redis)
- 每个请求都会生成一个新的异步 HTTPX client 会话
- 所有数据都在一次 HTTP 响应中被解析、统一并返回
- 内存会在响应发送后立即清除
## 架构
```
┌───────────┐ POST /api/investigate?query=... ┌───────────────┐
│ Browser │ ════════════════════════════════════════ ▶ │ FastAPI │
│ (Vite) │ │ (uvicorn) │
│ │ ◀ ═══════════════════════════════════════ │ │
│ React │ Unified JSON payload │ ┌─────────┐ │
│ + TS │ { nodes, edges, geojson } │ │ asyncio │ │
│ │ │ │ gather()│ │
│ ┌──────┐ │ │ └──┬──┬──┘ │
│ │Cyto- │ │ │ │ │ │
│ │scape │ │ │ ┌──▼──▼──┐ │
│ └──────┘ │ │ │ httpx │ │
│ ┌──────┐ │ │ │(async) │ │
│ │Globe │ │ │ └──┬──┬──┘ │
│ │ .gl │ │ │ │ │ │
│ └──────┘ │ ┌─────────┐ ┌──────┐ ┌────────┐ │ ┌──▼──▼──┐ │
└───────────┘ │ GDELT │ │ OTX │ │Pulsedive│ │ │ 5 APIs │
│ DOC v2 │ │ API │ │ API │ │ │ in │
└─────────┘ └──────┘ └────────┘ │ │ parallel│
┌─────────┐ ┌──────────┐ │ └─────────┘ │
│ Abuse │ │Nominatim │ └───────────────┘
│ IPDB │ │(Geocode) │
└─────────┘ └──────────┘
```
**数据流:**
1. 用户输入种子查询条件(IP、域名、组织、国家、城市、关键词)
2. 前端发送 `POST /api/investigate?query=`
3. 后端**并发**向 GDELT、OTX、Pulsedive、AbuseIPDB 发起 4 个异步 HTTP 请求(+ 回退到 Nominatim 进行地理编码)
4. 每个响应都会被解析、去重并标准化为:
- **`nodes`**:具有属性的实体类型
- **`edges`**:节点之间的关系连接
- **`geojson`**:包含 `Point` 几何图形的 `FeatureCollection`
5. 统一的 JSON 被返回;后端丢弃所有引用
6. 前端注入数据:
- `GraphPanel` → Cytoscape.js 绘制实体图
- `GlobePanel` → Globe.gl 在 3D 地球仪上渲染点和弧线
## 技术栈
### 后端
| 技术 | 用途 |
|-----------|---------|
| **Python 3.12+** | Runtime |
| **FastAPI** | 带有 OpenAPI 文档的 REST API 框架 |
| **uvicorn** | ASGI 服务器(包含 `httptools`、`websockets`) |
| **httpx** | 用于并发 API 调用的异步 HTTP 客户端 |
| **Pydantic v2** | 数据验证与序列化 |
### 前端
| 技术 | 用途 |
|-----------|---------|
| **React 18** | UI 框架 |
| **TypeScript** | 类型安全 |
| **Vite 5** | 构建工具和开发服务器 |
| **Tailwind CSS 3** | Utility-first 样式框架 |
| **Cytoscape.js** | 交互式实体关系图 |
| **Globe.gl** | 基于 Three.js 的 3D 地理空间地球仪 |
| **Three.js** | 3D 渲染引擎(通过 Globe.gl 打包) |
## 项目结构
```
palantir-osint/
├── backend/
│ ├── main.py # FastAPI app, health endpoint, /api/investigate
│ ├── models.py # Pydantic schemas (GraphNode, GraphEdge, GeoJSON, etc.)
│ ├── fetchers.py # Async API fetchers + merge orchestrator
│ └── requirements.txt # Python dependencies
│
├── frontend/
│ ├── index.html # Entry HTML
│ ├── package.json # NPM dependencies
│ ├── tsconfig.json # TypeScript config
│ ├── vite.config.ts # Vite config (proxy /api → localhost:8000)
│ ├── tailwind.config.js # Tailwind theme (dark palette, accent colours)
│ ├── postcss.config.js # PostCSS plugins
│ └── src/
│ ├── main.tsx # React DOM entry
│ ├── App.tsx # Root component (graph + analytics + dossier, search bar)
│ ├── index.css # Tailwind directives, scrollbar, gutter styles
│ ├── types.ts # Frontend type definitions matching backend schema
│ ├── useInvestigation.ts # Custom hook: loading/error/data/investigate
│ └── components/
│ ├── GraphPanel.tsx # Cytoscape.js entity-relation graph
│ └── GlobePanel.tsx # Globe.gl 3D geospatial view
│
├── README.md # This file
└── .gitignore
```
## 安装说明
### 前置条件
- 已安装 **Python 3.12+** 并添加到 `PATH`
- 已安装 **Node.js 20+** 和 **npm 10+**
- 终端(cmd,设置了执行策略的 PowerShell,或 Git Bash)
### 后端 (Python/FastAPI)
```
# 导航到 backend 目录
cd palantir-osint/backend
# (可选)创建并激活虚拟环境
python -m venv venv
# 在 Windows 上:
venv\Scripts\activate
# 在 Mac/Linux 上:
# source venv/bin/activate
# 安装依赖
pip install -r requirements.txt
# 启动开发服务器
python main.py
# 或者
uvicorn main:app --reload --host 0.0.0.0 --port 8000
```
后端将在 **`http://localhost:8000`** 提供。
自动生成的 OpenAPI 文档位于:**`http://localhost:8000/docs`**
### 前端 (React/Vite)
```
# 打开第二个终端
# 导航到 frontend 目录
cd palantir-osint/frontend
# 安装依赖
npm install
# 启动开发服务器
npm run dev
```
前端将在 **`http://localhost:5173`** 提供。
Vite 开发服务器将 `/api/*` 请求代理到 `http://127.0.0.1:8000`,因此一切都可以开箱即用。
### 生产环境构建
```
cd palantir-osint/frontend
npm run build
# 输出位于 frontend/dist/
# 使用任意静态文件服务器提供服务,或通过 FastAPI 提供服务
```
## 使用指南
### 1. 启动两个服务器
```
# 终端 1 — Backend
cd palantir-osint/backend && uvicorn main:app --reload --port 8000
# 终端 2 — Frontend
cd palantir-osint/frontend && npm run dev
```
### 2. 打开应用程序
在浏览器中导航至 **`http://localhost:5173`**。
你将看到:
### 3. 输入种子查询条件
在搜索栏中输入以下任意内容,然后点击 **INVESTIGATE**(或按 Enter 键):
| 查询类型 | 示例 |
|-----------|---------|
| IP 地址 | `185.220.101.0` |
| 域名 | `malware-domain.com` |
| 组织 | `APT29` 或 `Fancy Bear` |
| 国家 / 城市 | `Ukraine` 或 `Kyiv` |
| 常规威胁 | `ransomware` 或 `phishing campaign` |
| 事件关键词 | `cyber attack on power grid` |
### 4. 探索结果
**左侧面板 —— 实体图:**
- 节点按类型用颜色编码(见左下角的图例)
- 点击任意节点以高亮显示其相连的边和邻居(可切换)
- 拖动节点以重新排列布局
- 滚动进行缩放,拖动背景进行平移
**右侧面板 —— 3D 地球仪:**
- 点将出现在 GDELT 文章中带有地理编码的位置 + 任何带有坐标的节点上
- 动画弧线在第一个点和所有其他点之间绘制出中心辐射型的连接
- 拖动以旋转地球仪,滚动进行缩放
- 将鼠标悬停在任何点上以查看其标签
### 5. 调整分屏大小
拖动图表和地球仪面板之间的垂直细分隔条以调整分屏比例。你的首选项将保存在 `localStorage` 中。
## API 参考
### `POST /api/investigate`
**Query parameter:**
| 参数 | 类型 | 必填 | 描述 |
|-------|------|----------|-------------|
| `query` | `string` | 是 | 种子查询 —— IP、域名、组织、国家、城市或关键词 |
**响应 `200 OK`:**
```
{
"query": "185.220.101.0",
"nodes": [
{
"id": "abuse-185.220.101.0",
"label": "IP: 185.220.101.0",
"type": "Indicator",
"properties": {
"abuse_score": 85,
"total_reports": 23,
"country": "DE",
"isp": "Hetzner Online GmbH",
"usage_type": "Data Center/Web Hosting"
},
"latitude": null,
"longitude": null
}
],
"edges": [
{
"id": "edge-a1b2c3d4e5f6",
"source": "abuse-185.220.101.0",
"target": "abuse-report-abc123",
"label": "ATTACKED",
"properties": {}
}
],
"geojson": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [30.5, 50.4] },
"properties": {
"id": "loc-Kyiv",
"label": "Kyiv, Ukraine",
"type": "gdelt_location",
"source": "https://...",
"title": "Cyber attack on Ukrainian grid"
}
}
]
}
}
```
**响应 `400`:**
```
{
"detail": "query must not be empty"
}
```
**响应 `502`:**
```
{
"detail": "Exception details if external APIs fail"
}
```
### `GET /api/health`
```
{
"status": "ok",
"service": "palantir-osint"
}
```
## 数据结构
### `GraphNode`
| 字段 | 类型 | 描述 |
|-------|------|-------------|
| `id` | `string` | 唯一标识符(例如 `abuse-1.2.3.4`,`gdelt-https://...`) |
| `label` | `string` | 显示标签(截断为 60 个字符) |
| `type` | `enum` | 以下之一:`Event`、`ThreatActor`、`Indicator`、`Vulnerability`、`Location`、`Organization` |
| `properties` | `object` | 来源特定的元数据(评分、标签、URL、描述) |
| `latitude` | `float|null` | 地理空间纬度(如果可用) |
| `longitude` | `float|null` | 地理空间经度(如果可用) |
### `GraphEdge`
| 字段 | 类型 | 描述 |
|-------|------|-------------|
| `id` | `string` | 唯一边标识符 |
| `source` | `string` | 源节点 `id` |
| `target` | `string` | 目标节点 `id` |
| `label` | `enum` | 以下之一:`ATTACKED`、`CONTROLS`、`LOCATED_IN`、`CORRELATES_WITH`、`MENTIONS`、`TARGETS`、`ORIGINATES_FROM`、`EXPLOITS` |
| `properties` | `object` | 边元数据 |
### GeoJSON FeatureCollection
带有 `Point` 几何图形的标准 [GeoJSON](https://geojson.org/) `FeatureCollection`。每个 feature 的 `properties` 至少包含:
| 属性 | 类型 | 描述 |
|----------|------|-------------|
| `id` | `string` | 对原始节点的引用 |
| `label` | `string` | 点的显示标签 |
| `type` | `string` | 实体类型或来源标识符(例如 `gdelt_location`、`Indicator`) |
## 使用的外部 API
所有 API 均为**免费且无需 API 密钥**(除特别说明外 —— 但即使没有密钥,该应用程序在绝大多数功能上依然可以正常运行)。
### GDELT DOC API v2
- **URL:** `https://api.gdeltproject.org/api/v2/doc/doc`
- **免费层级:** 无限制,无需 API 密钥
- **速率限制:** 官方文档未作说明;请适量请求
- **数据:** 匹配种子查询的新闻文章、主题、地点、人物、组织
### AlienVault OTX
- **URL:** `https://otx.alienvault.com/api/v1/pulses/subscribed`
- **免费层级:** 无需 API 密钥即可访问公开的 pulse
- **数据:** 威胁 pulse、指标、恶意软件家族、攻击者标签
### Pulsedive
- **URL:** `https://pulsedive.com/api/indicators.php`
- **免费层级:** 无 API 密钥每天限 5 次请求;使用免费 API 密钥每天 100 次
- **数据:** 指标风险评分、威胁情报源、活动历史
- **注意:** 如果需要更高的速率限制,请在 pulsedive.com 注册免费的 API 密钥,并以 `?key=YOUR_KEY` 的形式传递
### AbuseIPDB
- **URL:** `https://api.abuseipdb.com/api/v2/check`
- **免费层级:** 使用免费 API 密钥每天 1,000 次请求
- **注意:** 没有密钥时,此 endpoint 将返回 401。应用程序会妥善处理此情况 —— 其他来源的数据依然有效。
### OpenStreetMap Nominatim
- **URL:** `https://nominatim.openstreetmap.org/search`
- **免费层级:** 带有 `User-Agent` 标头时无限使用
- **使用政策:** 每秒最多 1 次请求。我们的代码严格遵守了此规定。
- **数据:** 地理编码 —— 将城市/国家/地名解析为经纬度坐标
## 无状态设计理念
该平台有意设计为**零持久化数据**:
1. **无数据库** —— 每次调查都是全新的计算
2. **无用户会话** —— 无登录、无身份验证、无 cookie
3. **无缓存** —— 每个请求都直接访问实时 API
4. **无后台任务** —— 无 Celery、无消息队列
5. **仅在中** —— 数据在请求期间存在于 Python 的 `list` 和 `dict` 对象中,随后被垃圾回收
**为什么是无状态的?**
- 零维护开销(无数据库迁移、无备份)
- 极易进行横向扩展(在负载均衡器后添加更多的 FastAPI worker)
- 每个请求都是可重现的 —— 没有隐藏状态
- 兼容临时/边缘部署(Cloudflare Workers、AWS Lambda 等)
**权衡:** 每个请求都需要承担所有外部 API 调用的完整延迟(约 2–5 秒)。对于时效性比速度更重要的调查工具来说,这是可以接受的。
## 故障排除
### 后端无法启动
```
Error: [Errno 10048] Only one usage of each socket address is normally permitted
```
→ 端口 8000 已被占用。结束该进程或更改端口:
```
# 查找进程
netstat -ano | findstr :8000
# 终止它(替换 PID)
taskkill /PID /F
```
### 未返回任何结果
- 免费的 API 可能对你的请求进行了速率限制。请等待几秒钟后重试。
- 如果没有 API 密钥,某些 API(Pulsedive、AbuseIPDB)会限制每日使用量。
- IP 查询格式必须为 `x.x.x.x` —— AbuseIPDB 仅在遇到有效的 IPv4 时才会触发。
### 空白的地球仪 / 没有点显示
- 该查询可能没有返回任何可进行地理编码的位置。
- 尝试输入诸如“Ukraine”或“Tokyo”之类的国家/城市名称,以查看丰富的地理空间结果。
- 检查浏览器控制台中是否有 Globe.gl 错误(通常与 CORS 或图片加载有关)。
### 编辑器中出现 TypeScript 错误
```
# 确保已安装依赖
cd palantir-osint/frontend && npm install
# 在全新安装并重新加载编辑器后,这些错误应该会消失。
```
### Vite 代理无法正常工作
```
Error: Network Error / 405 Method Not Allowed
```
→ 确保后端正在端口 8000 上运行。Vite 配置会将 `/api` 代理到 `http://127.0.0.1:8000`。
→ 检查后端 CORS 中间件是否允许你的前端 origin。
## 许可证
本项目作为开源软件提供,仅用于教育和研究目的。
各外部 API 均有其各自的服务条款 —— 在生产环境中使用前请确保合规。
*使用 FastAPI、React、Cytoscape.js、Globe.gl 和 Tailwind CSS 构建。*
标签:AV绕过, ESC4, FastAPI, GitHub, OSINT, React, Syscalls, 可视化图谱, 威胁情报, 安全调查, 实时处理, 开发者工具, 自动化攻击, 运行时操纵, 逆向工具