
منصة تحقيقات استخباراتية مفتوحة المصدر (OSINT) تعتمد على الرسوم البيانية مع تحليل زمني، إدارة الكيانات، وتحويلات مدعومة بالذكاء الاصطناعي لكشف الروابط الخفية عبر البريد الإلكتروني، أسماء المستخدمين، الصور، والمواقع.

PANO هي منصة قوية للتحقيقات مفتوحة المصدر (OSINT) تجمع بين التصور البياني، وتحليل الجدول الزمني، وأدوات الذكاء الاصطناعي لمساعدتك على كشف الروابط والأنماط المخفية في بياناتك.
بدء الاستخدام • المميزات • التوثيق • المساهمة
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 transform) تحتاج إلى تسجيل الدخول باستخدام GHunt أولاً. بعد بدء PANO عبر البرامج النصية للتشغيل:
source venv/bin/activatecall venv\Scripts\activateالتصور البياني التفاعلي (Interactive Graph Visualization)
تحليل الجدول الزمني (Timeline Analysis)
التكامل مع الخريطة (Map Integration)
تحليل البريد الإلكتروني
تحليل اسم المستخدم
تحليل الصور
الكيانات هي اللبنات الأساسية لـ PANO. تمثل قطعاً متميزة من المعلومات يمكن ربطها وتحليلها:
الأنواع المضمنة
نظام الخصائص (Properties System)
التحويلات هي عمليات مؤتمتة تعالج الكيانات لاكتشاف معلومات وعلاقات جديدة:
أنواع العمليات
الميزات
المساعدون هي أدوات متخصصة بواجهات مستخدم مخصصة لمهام تحقيق محددة:
المساعدون المتوفرون
ميزات المساعدين
نرحب بالمساهمات! للمساهمة في 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"])
هذا المشروع مرخص بموجب رخصة Creative Commons Attribution-NonCommercial (CC BY-NC).
أنت حر في:
بموجب هذه الشروط:
شكر خاص لجميع مؤلفي المكتبات والمساهمين الذين جعلوا هذا المشروع ممكناً.
تم الإنشاء بواسطة ALW1EZ مع ❤️ من الذكاء الاصطناعي
التحويلات هي عمليات تعالج الكيانات وتولد رؤى أو علاقات جديدة. لإنشاء تحويل مخصص:
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)
المساعدون هي أدوات متخصصة توفر إمكانيات تحقيق إضافية عبر واجهة مستخدم مخصصة. لإنشاء مساعد مخصص:
helpers (مثل: 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)