without reports
This commit is contained in:
5
dpg.ini
5
dpg.ini
@ -78,3 +78,8 @@ Pos=300,200
|
||||
Size=700,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][###118]
|
||||
Pos=340,250
|
||||
Size=600,300
|
||||
Collapsed=0
|
||||
|
||||
|
@ -14,7 +14,8 @@ dependencies = [
|
||||
"loguru (>=0.7.3,<0.8.0)",
|
||||
"dbus-python (>=1.4.0,<2.0.0)",
|
||||
"dearpygui (>=2.0.0,<3.0.0)",
|
||||
"pyqt5 (>=5.15.11,<6.0.0)"
|
||||
"pyqt5 (>=5.15.11,<6.0.0)",
|
||||
"python-gvm (>=26.2.0,<27.0.0)"
|
||||
]
|
||||
|
||||
|
||||
|
@ -1,76 +1,126 @@
|
||||
from gvm.connections import TLSConnection
|
||||
from gvm.protocols.gmp import GMP
|
||||
from gvm.connections import UnixSocketConnection
|
||||
from gvm.protocols.gmp import Gmp
|
||||
from gvm.errors import GvmError
|
||||
from src.utils.logger import get_logger
|
||||
|
||||
logger = get_logger("openvas_scanner")
|
||||
|
||||
class OpenvasScanner:
|
||||
def __init__(self, hostname, port, username, password):
|
||||
"""Инициализация сканера OpenVAS"""
|
||||
def __init__(self, socket_path='/var/lib/docker/volumes/greenbone-community-edition_gvmd_socket_vol/_data/gvmd.sock'):
|
||||
"""
|
||||
Инициализация сканера OpenVAS.
|
||||
|
||||
:param socket_path: Путь к сокету GVM (по умолчанию '/var/run/gvmd.sock')
|
||||
"""
|
||||
self.socket_path = socket_path
|
||||
self.connection = None
|
||||
self.gmp = None
|
||||
|
||||
def connect(self, username, password):
|
||||
"""
|
||||
Подключение к GVM.
|
||||
|
||||
:param username: Имя пользователя для аутентификации
|
||||
:param password: Пароль для аутентификации
|
||||
"""
|
||||
try:
|
||||
self.connection = TLSConnection(hostname=hostname, port=port)
|
||||
self.gmp = GMP(self.connection)
|
||||
self.gmp.authenticate(username, password)
|
||||
self.configurations = {config.get_name(): config.get_id() for config in self.gmp.get_configurations().get_configurations()}
|
||||
logger.info(f"Connected to GVM at {hostname}:{port}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to connect to GVM: {e}")
|
||||
self.connection = UnixSocketConnection(path=self.socket_path)
|
||||
with Gmp(connection=self.connection) as gmp:
|
||||
gmp.authenticate(username, password)
|
||||
logger.info(f"Успешно подключено к GVM через {self.socket_path}")
|
||||
except GvmError as e:
|
||||
logger.error(f"Ошибка подключения к GVM: {e}")
|
||||
raise
|
||||
|
||||
|
||||
def get_configurations(self):
|
||||
"""Получить список конфигураций сканирования"""
|
||||
return list(self.configurations.keys())
|
||||
|
||||
def start_scan(self, scan_name, targets, scan_config_name):
|
||||
"""Начать сканирование"""
|
||||
"""
|
||||
Получение списка конфигураций сканирования.
|
||||
|
||||
:return: Список названий конфигураций
|
||||
"""
|
||||
try:
|
||||
configs = self.gmp.get_scan_configs()
|
||||
return [config.get('name') for config in configs]
|
||||
except GvmError as e:
|
||||
logger.error(f"Ошибка при получении конфигураций: {e}")
|
||||
raise
|
||||
|
||||
def create_target(self, name, hosts):
|
||||
"""
|
||||
Создание цели для сканирования.
|
||||
|
||||
:param name: Имя цели
|
||||
:param hosts: Список хостов (IP-адресов или сетей)
|
||||
:return: ID созданной цели
|
||||
"""
|
||||
try:
|
||||
target = self.gmp.create_target(name=name, hosts=hosts)
|
||||
return target.get('id')
|
||||
except GvmError as e:
|
||||
logger.error(f"Ошибка при создании цели: {e}")
|
||||
raise
|
||||
|
||||
def create_task(self, name, config_name, target_id):
|
||||
"""
|
||||
Создание задачи сканирования.
|
||||
|
||||
:param name: Имя задачи
|
||||
:param config_name: Название конфигурации сканирования
|
||||
:param target_id: ID цели
|
||||
:return: ID созданной задачи
|
||||
"""
|
||||
try:
|
||||
configs = self.gmp.get_scan_configs(filter=f"name={config_name}")
|
||||
if not configs:
|
||||
raise ValueError(f"Конфигурация '{config_name}' не найдена")
|
||||
config_id = configs[0].get('id')
|
||||
task = self.gmp.create_task(name=name, config_id=config_id, target_id=target_id)
|
||||
return task.get('id')
|
||||
except GvmError as e:
|
||||
logger.error(f"Ошибка при создании задачи: {e}")
|
||||
raise
|
||||
|
||||
def start_task(self, task_id):
|
||||
"""
|
||||
Запуск задачи сканирования.
|
||||
|
||||
:param task_id: ID задачи
|
||||
"""
|
||||
try:
|
||||
config_id = self.configurations.get(scan_config_name)
|
||||
if not config_id:
|
||||
raise ValueError(f"Конфигурация {scan_config_name} не найдена")
|
||||
# Создать цель
|
||||
target_response = self.gmp.create_target(
|
||||
name=f"Target for {scan_name}",
|
||||
hosts=targets.split(',')
|
||||
)
|
||||
target_id = target_response.get_id()
|
||||
# Создать задачу
|
||||
task_response = self.gmp.create_task(
|
||||
name=scan_name,
|
||||
config_id=config_id,
|
||||
target_id=target_id
|
||||
)
|
||||
task_id = task_response.get_id()
|
||||
# Запустить задачу
|
||||
self.gmp.start_task(task_id)
|
||||
logger.info(f"Started scan with task ID: {task_id}")
|
||||
return task_id
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to start scan: {e}")
|
||||
logger.info(f"Задача {task_id} запущена")
|
||||
except GvmError as e:
|
||||
logger.error(f"Ошибка при запуске задачи: {e}")
|
||||
raise
|
||||
|
||||
|
||||
def get_task_status(self, task_id):
|
||||
"""Получить статус задачи"""
|
||||
"""
|
||||
Получение статуса задачи.
|
||||
|
||||
:param task_id: ID задачи
|
||||
:return: Статус задачи
|
||||
"""
|
||||
try:
|
||||
tasks = self.gmp.get_tasks(filter_string=f"id={task_id}").get_tasks()
|
||||
if tasks:
|
||||
return tasks[0].get_status()
|
||||
logger.warning(f"Task {task_id} not found")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get task status: {e}")
|
||||
task = self.gmp.get_task(task_id)
|
||||
return task.get('status')
|
||||
except GvmError as e:
|
||||
logger.error(f"Ошибка при получении статуса задачи: {e}")
|
||||
raise
|
||||
|
||||
|
||||
def get_report(self, task_id):
|
||||
"""Получить отчет по задаче"""
|
||||
"""
|
||||
Получение отчета по задаче.
|
||||
|
||||
:param task_id: ID задачи
|
||||
:return: Отчет в формате XML
|
||||
"""
|
||||
try:
|
||||
reports = self.gmp.get_reports(filter_string=f"task={task_id}")
|
||||
if reports.get_reports():
|
||||
report_id = reports.get_reports()[0].get_id()
|
||||
report = self.gmp.get_report(report_id).get_report()
|
||||
logger.info(f"Retrieved report for task {task_id}")
|
||||
reports = self.gmp.get_reports(filter=f"task_id={task_id}")
|
||||
if reports:
|
||||
report_id = reports[0].get('id')
|
||||
report = self.gmp.get_report(report_id, format='xml')
|
||||
return report
|
||||
logger.warning(f"No report found for task {task_id}")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get report: {e}")
|
||||
except GvmError as e:
|
||||
logger.error(f"Ошибка при получении отчета: {e}")
|
||||
raise
|
@ -55,6 +55,9 @@ def build_attack_content(session):
|
||||
# Вкладка Modbus (атаки на Modbus)
|
||||
with dpg.tab(tag="modbus_attack_tab", label="Атаки на Modbus"):
|
||||
create_modbus_attack_tab()
|
||||
|
||||
with dpg.tab(tag="scapy_tab", label="Scapy"):
|
||||
logger.info("Вкладка Scapy нажата")
|
||||
|
||||
def create_metasploit_tab():
|
||||
"""Вкладка Metasploit (заглушка)"""
|
||||
|
@ -17,7 +17,7 @@ def create_main_window(db):
|
||||
no_move=True,
|
||||
): # Убраны фиксированные размеры
|
||||
# Заголовок с увеличенным шрифтом
|
||||
dpg.add_text("Модуль тестирования безопасности", color=(255, 255, 255), pos=[600,0])
|
||||
dpg.add_text("Модуль тестирования безопасности", color=(255, 255, 255), pos=[500,0])
|
||||
dpg.add_spacing(count=10)
|
||||
dpg.add_separator()
|
||||
|
||||
|
@ -3,6 +3,7 @@ from src.core.models.models import Session, Scan, Host, Port, Service
|
||||
from src.core.database.managers.scanner_manager import ScannerManager
|
||||
from src.core.api.nmap import NmapScanner
|
||||
from src.core.attacks.modbus_scan import ModbusScanner
|
||||
from src.core.api.openvas import OpenvasScanner
|
||||
from src.utils.logger import get_logger
|
||||
import threading
|
||||
import time
|
||||
@ -13,6 +14,7 @@ logger = get_logger("scanner_window")
|
||||
# Глобальные переменные для управления сканерами
|
||||
nmap_scanner = None
|
||||
modbus_scanner = None
|
||||
openvas_scanner = None
|
||||
|
||||
def create_scanner_window(db, session: Session, parent=None):
|
||||
"""Окно сканирования (с поддержкой родительского контейнера)"""
|
||||
@ -45,7 +47,7 @@ def build_scanner_content(scanner_service, session):
|
||||
create_nmap_tab(scanner_service, session)
|
||||
|
||||
with dpg.tab(tag="openvas_tab", label="OpenVAS Scanning"):
|
||||
dpg.add_text("OpenVAS scanning will be implemented here")
|
||||
create_openvas_tab(scanner_service, session)
|
||||
|
||||
with dpg.tab(tag="modbus_tab", label="Modbus Scanning"):
|
||||
create_modbus_tab(scanner_service, session)
|
||||
@ -236,6 +238,154 @@ def run_nmap_scan(scanner_service, session, scan_id, scanner):
|
||||
)
|
||||
scanner_service.update_scan(scan)
|
||||
|
||||
def create_openvas_tab(scanner_service, session):
|
||||
"""Вкладка OpenVAS сканирования"""
|
||||
with dpg.group():
|
||||
# Группа для настроек подключения
|
||||
with dpg.group(tag="openvas_connection_group"):
|
||||
dpg.add_text("Настройки подключения к OpenVAS")
|
||||
dpg.add_text("Сокет (например, /var/run/gvmd.sock):")
|
||||
socket_input = dpg.add_input_text(tag="openvas_socket", default_value="/var/run/gvmd.sock", width=300)
|
||||
dpg.add_text("Имя пользователя:")
|
||||
username_input = dpg.add_input_text(tag="openvas_username", width=300)
|
||||
dpg.add_text("Пароль:")
|
||||
password_input = dpg.add_input_text(tag="openvas_password", password=True, width=300)
|
||||
dpg.add_button(
|
||||
label="Подключиться",
|
||||
callback=lambda: connect_to_openvas(
|
||||
dpg.get_value(socket_input),
|
||||
dpg.get_value(username_input),
|
||||
dpg.get_value(password_input)
|
||||
),
|
||||
width=200,
|
||||
height=40
|
||||
)
|
||||
dpg.add_spacer(height=10)
|
||||
|
||||
# Группа для настроек сканирования (скрыта до подключения)
|
||||
with dpg.group(tag="openvas_scan_group", show=False):
|
||||
dpg.add_text("Настройки сканирования")
|
||||
dpg.add_text("Имя сканирования:")
|
||||
scan_name_input = dpg.add_input_text(tag="openvas_scan_name", width=300)
|
||||
dpg.add_text("Цели (IP-адреса или сети, через запятую):")
|
||||
targets_input = dpg.add_input_text(tag="openvas_targets", width=300)
|
||||
dpg.add_text("Конфигурация сканирования:")
|
||||
config_combo = dpg.add_combo(tag="openvas_config", items=[], width=300)
|
||||
dpg.add_button(
|
||||
label="Начать сканирование",
|
||||
callback=lambda: start_openvas_scan(
|
||||
scanner_service,
|
||||
session,
|
||||
dpg.get_value(scan_name_input),
|
||||
dpg.get_value(targets_input),
|
||||
dpg.get_value(config_combo)
|
||||
),
|
||||
width=200,
|
||||
height=40
|
||||
)
|
||||
dpg.add_spacer(height=10)
|
||||
|
||||
# Область вывода
|
||||
dpg.add_text("Вывод:")
|
||||
dpg.add_input_text(
|
||||
tag="openvas_output",
|
||||
multiline=True,
|
||||
height=300,
|
||||
width=-1,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
def connect_to_openvas(socket_path, username, password):
|
||||
"""Подключение к OpenVAS"""
|
||||
global openvas_scanner
|
||||
try:
|
||||
openvas_scanner = OpenvasScanner(socket_path=socket_path)
|
||||
openvas_scanner.connect(username, password)
|
||||
configs = openvas_scanner.get_configurations()
|
||||
dpg.configure_item("openvas_config", items=configs)
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + "✅ Подключено к OpenVAS\n")
|
||||
dpg.configure_item("openvas_scan_group", show=True)
|
||||
except Exception as e:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + f"❌ Ошибка подключения: {str(e)}\n")
|
||||
logger.error(f"OpenVAS connection failed: {e}")
|
||||
|
||||
def start_openvas_scan(scanner_service, session, scan_name, targets, config_name):
|
||||
"""Запуск OpenVAS сканирования"""
|
||||
global openvas_scanner
|
||||
if openvas_scanner is None:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + "❌ Не подключено к OpenVAS\n")
|
||||
return
|
||||
|
||||
try:
|
||||
# Создание цели
|
||||
target_id = openvas_scanner.create_target(scan_name, targets.split(','))
|
||||
# Создание задачи
|
||||
task_id = openvas_scanner.create_task(scan_name, config_name, target_id)
|
||||
# Запуск задачи
|
||||
openvas_scanner.start_task(task_id)
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + f"🚀 Задача {task_id} запущена\n")
|
||||
|
||||
# Сохранение сканирования в базе данных
|
||||
scan = Scan(
|
||||
session_id=session.id,
|
||||
tool="openvas",
|
||||
args=f"Имя: {scan_name}, Цели: {targets}, Конфигурация: {config_name}",
|
||||
summary="В процессе",
|
||||
created_at=datetime.utcnow()
|
||||
)
|
||||
saved_scan = scanner_service.save_scan(scan)
|
||||
if saved_scan:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + f"📝 ID сканирования: {saved_scan.id}\n")
|
||||
|
||||
# Запуск потока для отслеживания статуса задачи
|
||||
thread = threading.Thread(
|
||||
target=monitor_openvas_task,
|
||||
args=(scanner_service, session, saved_scan.id, task_id)
|
||||
)
|
||||
thread.start()
|
||||
|
||||
except Exception as e:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + f"❌ Ошибка: {str(e)}\n")
|
||||
logger.error(f"OpenVAS scan failed: {e}")
|
||||
|
||||
def monitor_openvas_task(scanner_service, session, scan_id, task_id):
|
||||
"""Отслеживание статуса задачи OpenVAS"""
|
||||
global openvas_scanner
|
||||
try:
|
||||
start_time = time.time()
|
||||
while True:
|
||||
status = openvas_scanner.get_task_status(task_id)
|
||||
if status == 'Done':
|
||||
report = openvas_scanner.get_report(task_id)
|
||||
if report:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + "✅ Сканирование завершено\n")
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + f"Отчет:\n{report}\n")
|
||||
else:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + "❌ Отчет не найден\n")
|
||||
break
|
||||
elif status in ['Running', 'Requested']:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + f"⏳ Статус: {status}\n")
|
||||
else:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + f"❌ Неизвестный статус: {status}\n")
|
||||
break
|
||||
time.sleep(10)
|
||||
|
||||
# Обновление статуса сканирования в базе данных
|
||||
scan = Scan(
|
||||
id=scan_id,
|
||||
summary="OpenVAS сканирование завершено",
|
||||
duration=int(time.time() - start_time),
|
||||
created_at=datetime.utcnow()
|
||||
)
|
||||
scanner_service.update_scan(scan)
|
||||
|
||||
if dpg.does_item_exist("scan_list"):
|
||||
load_scan_history(scanner_service, session, "scan_list")
|
||||
|
||||
except Exception as e:
|
||||
dpg.set_value("openvas_output", dpg.get_value("openvas_output") + f"❌ Ошибка: {str(e)}\n")
|
||||
logger.error(f"OpenVAS task monitoring failed: {e}")
|
||||
|
||||
def create_modbus_tab(scanner_service, session):
|
||||
"""Вкладка Modbus сканирования"""
|
||||
with dpg.group():
|
||||
|
Reference in New Issue
Block a user