95 lines
4.3 KiB
Python
95 lines
4.3 KiB
Python
import re
|
||
import json
|
||
from typing import Any, Dict
|
||
import nmap3
|
||
from src.utils.logger import get_logger
|
||
|
||
logger = get_logger("nmap_scanner")
|
||
|
||
|
||
class NmapScanner:
|
||
def __init__(self, ip: str, args: str = "-sV"):
|
||
"""
|
||
Инициализация сканера Nmap
|
||
|
||
:param ip: целевой IP-адрес
|
||
:param args: аргументы для сканирования (по умолчанию: -sV)
|
||
"""
|
||
self.ip = ip
|
||
self.args = args
|
||
self.nmap = nmap3.Nmap()
|
||
logger.info(f"Инициализация NmapScanner для IP: {ip}, аргументы: {args}")
|
||
|
||
def start_scan(self) -> Dict[str, Any]:
|
||
"""
|
||
Запуск сканирования и возврат очищенных результатов
|
||
|
||
:return: словарь с разделенными результатами
|
||
"""
|
||
logger.info(f"🚀 Запуск сканирования Nmap для {self.ip} с аргументами: {self.args}")
|
||
try:
|
||
# Запуск сканирования с определением версий
|
||
scan_result = self.nmap.nmap_version_detection(self.ip, args=self.args)
|
||
logger.debug(f"Сырые результаты сканирования: {json.dumps(scan_result, indent=2)}")
|
||
|
||
# Очистка и структурирование результатов
|
||
cleaned_result = self.return_clear_result(scan_result)
|
||
logger.success(f"✅ Сканирование завершено для {self.ip}. Найдено хостов: {len(cleaned_result['hosts'])}")
|
||
return cleaned_result
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при выполнении сканирования Nmap: {e}")
|
||
return {"hosts": {}, "service_info": {}}
|
||
|
||
@staticmethod
|
||
def return_clear_result(raw_data: Dict[str, Any]) -> Dict[str, Any]:
|
||
"""
|
||
Очистка и структурирование сырых данных от Nmap
|
||
|
||
:param raw_data: сырые данные от nmap_version_detection
|
||
:return: словарь с разделенными результатами
|
||
"""
|
||
logger.info("Начало обработки сырых данных Nmap")
|
||
try:
|
||
# Регулярное выражение для проверки IPv4
|
||
ip_pattern = re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
|
||
|
||
hosts = {}
|
||
service_info = {}
|
||
|
||
for key, value in raw_data.items():
|
||
# Проверяем, является ли ключ IP-адресом
|
||
if ip_pattern.match(key):
|
||
# Проверяем, в каком состоянии находится хост
|
||
if value.get('state', {}).get('state') == "up":
|
||
hosts[key] = value
|
||
logger.debug(f"Обнаружен активный хост: {key}")
|
||
else:
|
||
logger.debug(
|
||
f"Хост {key} не активен (состояние: {value.get('state', {}).get('state', 'unknown')})")
|
||
else:
|
||
service_info[key] = value
|
||
|
||
logger.info(
|
||
f"Обработка завершена. Активных хостов: {len(hosts)}, сервисная информация: {len(service_info)}")
|
||
return {
|
||
"hosts": hosts,
|
||
"service_info": service_info
|
||
}
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при обработке данных Nmap: {e}")
|
||
return {"hosts": {}, "service_info": {}}
|
||
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
scanner = NmapScanner("192.168.1.55", "-p 1-10000")
|
||
result = scanner.start_scan()
|
||
path = "/home/lodqa/attack_module_data/nmap.json"
|
||
logger.info(f"Сохранение результатов в файл: {path}")
|
||
with open(path, 'w', encoding='utf-8') as file:
|
||
json.dump(result, file, ensure_ascii=False, indent=4)
|
||
logger.success(f"Результаты успешно сохранены в {path}")
|
||
except Exception as e:
|
||
logger.error(f"Ошибка в главном блоке: {e}") |