Загрузить файлы в «src»

This commit is contained in:
2026-04-21 00:40:31 +03:00
parent c7d2dfc9e4
commit 6031c45917
5 changed files with 168 additions and 0 deletions

21
src/ai_analyser.py Normal file
View File

@@ -0,0 +1,21 @@
def analyze_threat(self, packet_text, context):
prompt = f"""
ROLE: Senior CyberSecurity Researcher (Wireless Networks).
DATA: Current packet: {packet_text}
HISTORY_CONTEXT: {context}
TASK:
1. Проверь пакет на признаки известных атак:
- Deauthentication Flood (уязвимость 802.11w)
- Rogue AP / Evil Twin (несоответствие RSSI/MAC)
- WPA Handshake sniffing (EAPOL flow)
- WPS Pixie Dust / Brute Force
2. Если это атака, укажи её название и CVE (если есть).
3. Оцени риск по шкале от 1 до 10.
4. Предложи команду для исправления (например, 'enable 802.11w' или 'disable WPS').
ОТВЕТЬ КРАТКО И ТЕХНИЧЕСКИ ТОЧНО.
"""
# Вызов Ollama API...
# Временная заглушка - в реальном приложении здесь будет вызов API
return "Анализ не реализован в текущей версии"

14
src/embedder.py Normal file
View File

@@ -0,0 +1,14 @@
import requests
import os
class Embedder:
def __init__(self, model_name="qwen3-embedding:8b"):
self.model_name = model_name
self.ollama_url = os.getenv("OLLAMA_URL", "http://localhost:11434")
def get_vector(self, text):
response = requests.post(
f"{self.ollama_url}/api/embeddings",
json={"model": self.model_name, "prompt": text}
)
return response.json()["embedding"]

66
src/main.py Normal file
View File

@@ -0,0 +1,66 @@
import sys
import uuid
import json
import socket
from scapy.all import sniff
import os
from parser import PacketParser
from embedder import Embedder
from vector_store import VectorDB
from ai_analyser import AIAnalyser
# Настройки моделей из вашего списка
EMBEDDING_MODEL = "qwen3-embedding:8b"
ANALYSIS_MODEL = "qwen3.5:35b-a3b" # или Qwen3-Coder для глубокого тех-анализа
# Инициализация
embedder = Embedder(model_name=EMBEDDING_MODEL)
db = VectorDB(collection_name="wifi_lab", vector_size=4096) # Размерность Qwen 8B
ai = AIAnalyser()
parser = PacketParser()
def process_packet(pkt):
# 1. Извлекаем признаки
text_desc = parser.parse_to_text(pkt)
if not text_desc: return
# 2. Генерируем вектор через Ollama
vector = embedder.get_vector(text_desc)
# 3. Ищем аномалии в Qdrant
# Мы смотрим на "дистанцию". Если похожих векторов нет (score низкий),
# значит поведение сети изменилось.
search_results = db.find_similar(vector)
# Порог аномалии (экспериментально для Косинусного сходства < 0.7)
is_anomaly = len(search_results) == 0 or search_results[0].score < 0.7
# 4. Сохраняем в Qdrant для истории
db.add_packet(str(uuid.uuid4()), vector, {"subtype": pkt.subtype}, text_desc)
if is_anomaly:
print(f"\n[!] ОБНАРУЖЕНА УЯЗВИМОСТЬ/АНОМАЛИЯ: {text_desc}")
# 5. Анализ через мощную Qwen 35B
context = [res.payload['text'] for res in search_results]
report = ai.analyze_threat(text_desc, context)
print(f"[AI REPORT]:\n{report}\n" + "-"*50)
def main():
HOST = '0.0.0.0'
PORT = 9999
print(f"[*] Анализатор слушает на {HOST}:{PORT}...")
# Создаем серверный сокет
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with conn:
print(f"[*] Соединение установлено с {addr}")
# Превращаем сокет в объект файла для Scapy
fileobj = conn.makefile(mode='rb')
sniff(opened_socket=fileobj, prn=process_packet, store=0)
if __name__ == "__main__":
main()

31
src/parser.py Normal file
View File

@@ -0,0 +1,31 @@
from scapy.all import Dot11, Dot11Deauth, Dot11Beacon, raw
class PacketParser:
@staticmethod
def parse_to_text(pkt):
"""Превращает пакет в текстовое описание для эмбеддинга"""
if not pkt.haslayer(Dot11):
return None
# Извлекаем базовые параметры
info = {
"type": pkt.type,
"subtype": pkt.subtype,
"addr1": pkt.addr1, # Получатель
"addr2": pkt.addr2, # Отправитель
"rssi": getattr(pkt, 'dBm_AntSignal', 'N/A') # Мощность сигнала
}
# Определяем тип фрейма человеческим языком
frame_types = {0: "Management", 1: "Control", 2: "Data"}
type_str = frame_types.get(pkt.type, "Unknown")
# Формируем строку-описание
text_desc = f"Type: {type_str}, Subtype: {pkt.subtype}, From: {info['addr2']}, To: {info['addr1']}, RSSI: {info['rssi']}"
# Добавляем часть полезной нагрузки (payload) если есть
payload = raw(pkt.payload).hex()[:64]
if payload:
text_desc += f", Payload: {payload}"
return text_desc

36
src/vector_store.py Normal file
View File

@@ -0,0 +1,36 @@
import os
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
class VectorDB:
def __init__(self, collection_name="wifi_lab", vector_size=4096):
host = os.getenv("QDRANT_HOST", "localhost")
port = int(os.getenv("QDRANT_PORT", 6333))
self.client = QdrantClient(host=host, port=port)
self.collection_name = collection_name
# Создаем коллекцию, если её нет (размерность 4096 для Qwen 8B Embedding)
self.client.recreate_collection(
collection_name=self.collection_name,
vectors_config=VectorParams(size=vector_size, distance=Distance.COSINE),
)
def add_packet(self, pkt_id, vector, metadata, text):
self.client.upsert(
collection_name=self.collection_name,
points=[
PointStruct(
id=pkt_id,
vector=vector,
payload={"metadata": metadata, "text": text}
)
]
)
def find_similar(self, vector):
return self.client.search(
collection_name=self.collection_name,
query_vector=vector,
limit=3,
with_payload=True
)