PANO - Advanced OSINT Investigation Platform Combining Graph Visualization, Timeline Analysis, And AI Assistance To Uncover Hidden Connections In Data
PANO is a powerful OSINT investigation platform that combines graph visualization, timeline analysis, and AI-powered tools to help you uncover hidden connections and patterns in your data.
Getting Started
-
Clone the repository:
bash git clone https://github.com/ALW1EZ/PANO.git cd PANO
-
Run the application:
- Linux:
./start_pano.sh
- Windows:
start_pano.bat
The startup script will automatically: - Check for updates - Set up the Python environment - Install dependencies - Launch PANO
In order to use Email Lookup transform You need to login with GHunt first. After starting the pano via starter scripts;
- Select venv manually
- Linux:
source venv/bin/activate
- Windows:
call venv\Scripts\activate
- See how to login here
đĄ Quick Start Guide
- Create Investigation: Start a new investigation or load an existing one
- Add Entities: Drag entities from the sidebar onto the graph
- Discover Connections: Use transforms to automatically find relationships
- Analyze: Use timeline and map views to understand patterns
- Save: Export your investigation for later use
đ Features
đ¸️ Core Functionality
- Interactive Graph Visualization
- Drag-and-drop entity creation
- Multiple layout algorithms (Circular, Hierarchical, Radial, Force-Directed)
- Dynamic relationship mapping
-
Visual node and edge styling
-
Timeline Analysis
- Chronological event visualization
- Interactive timeline navigation
- Event filtering and grouping
-
Temporal relationship analysis
-
Map Integration
- Geographic data visualization
- Location-based analysis
- Interactive mapping features
- Coordinate plotting and tracking
đŻ Entity Management
- Supported Entity Types
- đ§ Email addresses
- đ¤ Usernames
- đ Websites
- đź️ Images
- đ Locations
- ⏰ Events
- đ Text content
- đ§ Custom entity types
đ Transform System
- Email Analysis
- Google account investigation
- Calendar event extraction
- Location history analysis
-
Connected services discovery
-
Username Analysis
- Cross-platform username search
- Social media profile discovery
- Platform correlation
-
Web presence analysis
-
Image Analysis
- Reverse image search
- Visual content analysis
- Metadata extraction
- Related image discovery
đ¤ AI Integration
- PANAI
- Natural language investigation assistant
- Automated entity extraction and relationship mapping
- Pattern recognition and anomaly detection
- Multi-language support
- Context-aware suggestions
- Timeline and graph analysis
đ§Š Core Components
đŚ Entities
Entities are the fundamental building blocks of PANO. They represent distinct pieces of information that can be connected and analyzed:
- Built-in Types
- đ§ Email: Email addresses with service detection
- đ¤ Username: Social media and platform usernames
- đ Website: Web pages with metadata
- đź️ Image: Images with EXIF and analysis
- đ Location: Geographic coordinates and addresses
- ⏰ Event: Time-based occurrences
-
đ Text: Generic text content
-
Properties System
- Type-safe property validation
- Automatic property getters
- Dynamic property updates
- Custom property types
- Metadata support
⚡ Transforms
Transforms are automated operations that process entities to discover new information and relationships:
- Operation Types
- đ Discovery: Find new entities from existing ones
- đ Correlation: Connect related entities
- đ Analysis: Extract insights from entity data
- đ OSINT: Gather open-source intelligence
-
đ Enrichment: Add data to existing entities
-
Features
- Async operation support
- Progress tracking
- Error handling
- Rate limiting
- Result validation
đ ️ Helpers
Helpers are specialized tools with dedicated UIs for specific investigation tasks:
- Available Helpers
- đ Cross-Examination: Analyze statements and testimonies
- đ¤ Portrait Creator: Generate facial composites
- đ¸ Media Analyzer: Advanced image processing and analysis
- đ Base Searcher: Search near places of interest
-
đ Translator: Translate text between languages
-
Helper Features
- Custom Qt interfaces
- Real-time updates
- Graph integration
- Data visualization
- Export capabilities
đĽ Contributing
We welcome contributions! To contribute to PANO:
- Fork the repository at https://github.com/ALW1EZ/PANO/
- Make your changes in your fork
- Test your changes thoroughly
- Create a Pull Request to our main branch
- In your PR description, include:
- What the changes do
- Why you made these changes
- Any testing you've done
- Screenshots if applicable
Note: We use a single
main
branch for development. All pull requests should be made directly tomain
.
đ Development Guide
Click to expand development documentation
### System Requirements - Operating System: Windows or Linux - Python 3.11+ - PySide6 for GUI - Internet connection for online features ### Custom Entities Entities are the core data structures in PANO. Each entity represents a piece of information with specific properties and behaviors. To create a custom entity: 1. Create a new file in the `entities` folder (e.g., `entities/phone_number.py`) 2. Implement your entity class:from dataclasses import dataclassfrom typing import ClassVar, Dict, Anyfrom .base import Entity@dataclassclass 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"])
### Custom Transforms Transforms are operations that process entities and generate new insights or relationships. To create a custom transform: 1. Create a new file in the `transforms` folder (e.g., `transforms/phone_lookup.py`) 2. Implement your transform class: from dataclasses import dataclassfrom typing import ClassVar, Listfrom .base import Transformfrom entities.base import Entityfrom entities.phone_number import PhoneNumberfrom entities.location import Locationfrom ui.managers.status_manager import StatusManager@dataclassclass 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)
### Custom Helpers Helpers are specialized tools that provide additional investigation capabilities through a dedicated UI interface. To create a custom helper: 1. Create a new file in the `helpers` folder (e.g., `helpers/data_analyzer.py`) 2. Implement your helper class: from PySide6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QTextEdit, QLabel, QComboBox)from .base import BaseHelperfrom qasync import asyncSlotclass 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)
đ License
This project is licensed under the Creative Commons Attribution-NonCommercial (CC BY-NC) License.
You are free to: - ✅ Share: Copy and redistribute the material - ✅ Adapt: Remix, transform, and build upon the material
Under these terms: - âš️ Attribution: You must give appropriate credit - đŤ NonCommercial: No commercial use - đ No additional restrictions
đ Acknowledgments
Special thanks to all library authors and contributors who made this project possible.
đ¨đť Author
Created by ALW1EZ with AI ❤️
Source: www.kitploit.com