
Piattaforma di indagine OSINT basata su grafi con analisi temporale, gestione delle entità e trasformazioni basate su IA per scoprire connessioni nascoste tra email, nomi utente, immagini e luoghi.

PANO è una potente piattaforma di investigazione OSINT che combina visualizzazione a grafo, analisi della timeline e strumenti basati sull'AI per aiutarti a scoprire connessioni e pattern nascosti nei tuoi dati.
Per iniziare • Funzionalità • Documentazione • Contribuire
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
Clona il repository:
git clone https://github.com/ALW1EZ/PANO.git
cd PANO
Avvia l'applicazione:
./start_pano.shstart_pano.batLo script di avvio farà automaticamente:
Per utilizzare la trasformazione Email Lookup è necessario prima autenticarsi con GHunt. Dopo aver avviato pano tramite gli script di avvio;
source venv/bin/activatecall venv\Scripts\activateVisualizzazione interattiva del grafo
Analisi della timeline
Integrazione mappa
Analisi email
Analisi nomi utente
Analisi immagini
Le entità sono i mattoni fondamentali di PANO. Rappresentano informazioni distinte che possono essere connesse e analizzate:
Tipi integrati
Sistema di proprietà
Le trasformazioni sono operazioni automatizzate che elaborano le entità per scoprire nuove informazioni e relazioni:
Tipi di operazione
Caratteristiche
Gli helper sono strumenti specializzati con interfacce utente dedicate per specifici compiti investigativi:
Helper disponibili
Caratteristiche degli helper
Accogliamo contributi! Per contribuire a PANO:
Nota: Usiamo un unico branch
mainper lo sviluppo. Tutte le pull request devono essere fatte direttamente sumain.
Le entità sono le strutture dati principali di PANO. Ogni entità rappresenta un'informazione con proprietà e comportamenti specifici. Per creare un'entità personalizzata:
entities (ad es. 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"])
Questo progetto è concesso in licenza Creative Commons Attribuzione-NonCommerciale (CC BY-NC).
Sei libero di:
A queste condizioni:
Un ringraziamento speciale a tutti gli autori e contributori delle librerie che hanno reso possibile questo progetto.
Creato da ALW1EZ con AI ❤️
Le trasformazioni sono operazioni che elaborano entità e generano nuovi approfondimenti o relazioni. Per creare una trasformazione personalizzata:
transforms (ad es. 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)
Gli helper sono strumenti specializzati che forniscono capacità investigative aggiuntive tramite un'interfaccia utente dedicata. Per creare un helper personalizzato:
helpers (ad es. helpers/data_analyzer.py)from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
QTextEdit, QLabel, QComboBox
)
from .base import BaseHelper
from qasync import asyncSlot
class DummyHelper(BaseHelper):
"""A dummy helper for testing"""
name = "Dummy Helper"
description = "A dummy helper for testing"
def setup_ui(self):
"""Initialize the helper's user interface"""
# Create input text area
self.input_label = QLabel("Input:")
self.input_text = QTextEdit()
self.input_text.setPlaceholderText("Enter text to process...")
self.input_text.setMinimumHeight(100)
# Create operation selector
operation_layout = QHBoxLayout()
self.operation_label = QLabel("Operation:")
self.operation_combo = QComboBox()
self.operation_combo.addItems(["Uppercase", "Lowercase", "Title Case"])
operation_layout.addWidget(self.operation_label)
operation_layout.addWidget(self.operation_combo)
# Create process button
self.process_btn = QPushButton("Process")
self.process_btn.clicked.connect(self.process_text)
# Create output text area
self.output_label = QLabel("Output:")
self.output_text = QTextEdit()
self.output_text.setReadOnly(True)
self.output_text.setMinimumHeight(100)
# Add widgets to main layout
self.main_layout.addWidget(self.input_label)
self.main_layout.addWidget(self.input_text)
self.main_layout.addLayout(operation_layout)
self.main_layout.addWidget(self.process_btn)
self.main_layout.addWidget(self.output_label)
self.main_layout.addWidget(self.output_text)
# Set dialog size
self.resize(400, 500)
@asyncSlot()
async def process_text(self):
"""Process the input text based on selected operation"""
text = self.input_text.toPlainText()
operation = self.operation_combo.currentText()
if operation == "Uppercase":
result = text.upper()
elif operation == "Lowercase":
result = text.lower()
else: # Title Case
result = text.title()
self.output_text.setPlainText(result)