
PANO 是一个强大的 OSINT 调查平台,它结合了图形可视化、时间线分析和 AI 驱动工具,帮助您发现数据中的隐藏联系和模式。
https://github.com/user-attachments/assets/6b95e97a-ffdd-4056-b12b-f268d8e5d565
https://github.com/user-attachments/assets/af0c0f65-7b79-417c-a678-a789d42a6003
https://github.com/user-attachments/assets/568b4c28-be78-4559-a607-899fca2f9613
https://github.com/user-attachments/assets/6aa191eb-09de-41d5-b96f-4a2e32d6a0c2
https://github.com/user-attachments/assets/96377b80-e137-4eb4-9387-a0db4e49c2c1
https://github.com/user-attachments/assets/4228bda0-6c13-4ea9-bc07-d87abe367e10
克隆仓库:
git clone https://github.com/ALW1EZ/PANO.git
cd PANO
运行应用程序:
./start_pano.shstart_pano.bat启动脚本将自动:
为了使用 Email Lookup 转换功能 您需要先使用 GHunt 登录。 通过启动脚本启动 PANO 后;
source venv/bin/activatecall venv\Scripts\activate交互式图形可视化
时间线分析
地图集成
电子邮件分析
用户名分析
图片分析
实体是 PANO 的基本构建块。它们代表可以被连接和分析的不同信息片段:
内置类型
属性系统
转换是自动化的操作,用于处理实体以发现新的信息和关系:
操作类型
特性
助手是具有专用用户界面的专业化工具,用于特定的调查任务:
可用助手
助手特性
我们欢迎贡献!要为 PANO 做贡献:
注意:我们使用单一
main分支进行开发。所有拉取请求应直接提交到main。
实体是 PANO 中的核心数据结构。每个实体代表一个具有特定属性和行为的信息片段。要创建自定义实体:
entities 文件夹中创建一个新文件(例如 entities/phone_number.py)from dataclasses import dataclass
from typing import ClassVar, Dict, Any
from .base import Entity
@dataclass
class PhoneNumber(Entity):
name: ClassVar[str] = "Phone Number"
description: ClassVar[str] = "A phone number entity with country code and validation"
def init_properties(self):
"""Initialize phone number properties"""
self.setup_properties({
"number": str,
"country_code": str,
"carrier": str,
"type": str, # mobile, landline, etc.
"verified": bool
})
def update_label(self):
"""Update the display label"""
self.label = self.format_label(["country_code", "number"])
转换是处理实体并生成新洞察或关系的操作。要创建自定义转换:
transforms 文件夹中创建一个新文件(例如 transforms/phone_lookup.py)from dataclasses import dataclass
from typing import ClassVar, List
from .base import Transform
from entities.base import Entity
from entities.phone_number import PhoneNumber
from entities.location import Location
from ui.managers.status_manager import StatusManager
@dataclass
class PhoneLookup(Transform):
name: ClassVar[str] = "Phone Number Lookup"
description: ClassVar[str] = "Lookup phone number details and location"
input_types: ClassVar[List[str]] = ["PhoneNumber"]
output_types: ClassVar[List[str]] = ["Location"]
async def run(self, entity: PhoneNumber, graph) -> List[Entity]:
if not isinstance(entity, PhoneNumber):
return []
status = StatusManager.get()
operation_id = status.start_loading("Phone Lookup")
try:
# Your phone number lookup logic here
# Example: query an API for phone number details
location = Location(properties={
"country": "Example Country",
"region": "Example Region",
"carrier": "Example Carrier",
"source": "PhoneLookup transform"
})
return [location]
except Exception as e:
status.set_text(f"Error during phone lookup: {str(e)}")
return []
finally:
status.stop_loading(operation_id)
助手是通过专用 UI 界面提供额外调查能力的专业化工具。要创建自定义助手:
helpers 文件夹中创建一个新文件(例如 helpers/data_analyzer.py)from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
QTextEdit, QLabel, QComboBox
)
from .base import BaseHelper
from qasync import asyncSlot