0% found this document useful (0 votes)
17 views14 pages

Nmap

The document outlines a Python application using PyQt5 for network scanning and vulnerability assessment with Nmap. It includes classes for managing scanning threads, generating reports, and handling user profiles and scheduled scans. The application supports output in various formats and provides a graphical interface for users to interact with the scanning process.

Uploaded by

dorom18292
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views14 pages

Nmap

The document outlines a Python application using PyQt5 for network scanning and vulnerability assessment with Nmap. It includes classes for managing scanning threads, generating reports, and handling user profiles and scheduled scans. The application supports output in various formats and provides a graphical interface for users to interact with the scanning process.

Uploaded by

dorom18292
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 14

import sys

import os
import subprocess
import json
import datetime
import re
import webbrowser
from PyQt5.QtWidgets import (QApplication, QMainWindow, QLabel, QLineEdit,
QPushButton, QTextEdit, QVBoxLayout, QHBoxLayout,
QWidget, QComboBox, QGroupBox, QCheckBox, QTabWidget,
QFileDialog, QMessageBox, QProgressBar, QFrame,
QSplitter, QTreeWidget, QTreeWidgetItem, QGridLayout,
QMenu, QAction, QToolBar, QStatusBar, QTableWidget,
QTableWidgetItem, QHeaderView, QInputDialog,
QShortcut,
QSystemTrayIcon, QStyle)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QDateTime, QSettings,
QUrl
from PyQt5.QtGui import QIcon, QFont, QPixmap, QKeySequence, QColor,
QDesktopServices
import platform

class NmapScanThread(QThread):
scan_output = pyqtSignal(str)
scan_complete = pyqtSignal(bool, str)
scan_progress = pyqtSignal(int)
scan_hosts = pyqtSignal(dict)

def __init__(self, target, options, output_format="normal"):


QThread.__init__(self)
self.target = target
self.options = options
self.output_format = output_format
self.canceled = False

def run(self):
try:
self.scan_output.emit(f"‫بدأ الفحص‬:
{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

# ‫ إضافة خيار الإخراج‬XML ‫إذا كان متاحًا‬


xml_output = ""
if self.output_format == "xml":
# ‫ إنشاء اسم ملف مؤقت للإخراج‬XML
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
xml_output = f"nmap_scan_{timestamp}.xml"
self.options += f" -oX {xml_output}"

command = ["nmap"]
command.extend(self.options.split())
command.append(self.target)

self.scan_output.emit(f"‫تنفيذ الأمر‬: {' '.join(command)}")

process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True
)

# ‫تتبع معلومات المضيفين‬


hosts_info = {}
current_host = None

# ‫إرسال تحديثات التقدم‬


progress = 0
for line in process.stdout:
if self.canceled:
process.terminate()
self.scan_output.emit("‫تم إلغاء الفحص‬.")
self.scan_complete.emit(False, "")
return

self.scan_output.emit(line.strip())

# ‫تحليل معلومات المضيفين‬


if "Nmap scan report for" in line:
host_match = re.search(r"for\s+(.+)\s+\((.+)\)", line)
if host_match:
current_host = host_match.group(2) # ‫ عنوان‬IP
hostname = host_match.group(1)
hosts_info[current_host] = {"hostname": hostname, "ports":
[]}
else:
# ‫ عنوان‬IP ‫فقط‬
ip_match = re.search(r"for\s+(.+)", line)
if ip_match:
current_host = ip_match.group(1)
hosts_info[current_host] = {"hostname": "", "ports":
[]}

# ‫تحليل معلومات المنافذ‬


if current_host and "/tcp" in line or "/udp" in line:
port_match = re.search(r"(\d+)/(tcp|udp)\s+(\w+)\s+(.+)", line)
if port_match:
port_num = port_match.group(1)
port_type = port_match.group(2)
port_state = port_match.group(3)
port_service = port_match.group(4)

if "ports" not in hosts_info[current_host]:


hosts_info[current_host]["ports"] = []

hosts_info[current_host]["ports"].append({
"number": port_num,
"type": port_type,
"state": port_state,
"service": port_service
})

# ‫تحديث شريط التقدم‬


if "% done" in line:
try:
progress = int(line.split("%")[0].split()[-1])
self.scan_progress.emit(progress)
except:
pass

process.wait()
self.scan_hosts.emit(hosts_info)
self.scan_output.emit(f"‫انتهى الفحص‬:
{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
self.scan_complete.emit(True, xml_output)

except Exception as e:
self.scan_output.emit(f"‫حدث خطأ‬: {str(e)}")
self.scan_complete.emit(False, "")

def cancel(self):
self.canceled = True

class VulnerabilityScanner(QThread):
scan_output = pyqtSignal(str)
scan_complete = pyqtSignal(bool)

def __init__(self, targets, options):


super().__init__()
self.targets = targets
self.options = options

def run(self):
try:
# ‫ أمر‬nmap ‫ مع‬NSE ‫لفحص الثغرات‬
command = ["nmap", "-sV", "--script", "vuln"]
command.extend(self.options.split())
for target in self.targets:
command.append(target)

self.scan_output.emit(f"‫بدء فحص الثغرات‬: {' '.join(command)}")

process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True
)

for line in process.stdout:


self.scan_output.emit(line.strip())

process.wait()
self.scan_output.emit("‫اكتمل فحص الثغرات‬.")
self.scan_complete.emit(True)

except Exception as e:
self.scan_output.emit(f"‫حدث خطأ في فحص الثغرات‬: {str(e)}")
self.scan_complete.emit(False)

class ReportGenerator:
@staticmethod
def generate_html_report(scan_data, filename):
html = """
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>‫ تقرير فحص‬Nmap</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background-color: white;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}
h1, h2, h3 {
color: #2c3e50;
}
.header {
border-bottom: 2px solid #3498db;
padding-bottom: 10px;
margin-bottom: 20px;
}
.host {
margin-bottom: 30px;
border: 1px solid #ddd;
border-radius: 5px;
padding: 15px;
}
table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
}
th, td {
padding: 12px 15px;
border: 1px solid #ddd;
text-align: right;
}
th {
background-color: #3498db;
color: white;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
.footer {
margin-top: 30px;
text-align: center;
color: #7f8c8d;
font-size: 0.9em;
}
.open {
color: green;
font-weight: bold;
}
.closed {
color: red;
}
.filtered {
color: orange;
}
.summary {
background-color: #eaf2f8;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>‫ تقرير فحص‬Nmap</h1>
<p>‫تاريخ التقرير‬: """ + datetime.datetime.now().strftime("%Y-
%m-%d %H:%M:%S") + """</p>
</div>

<div class="summary">
<h2>‫<ملخص الفحص‬/h2>
<p>‫عدد المضيفات التي تم فحصها‬: """ +
str(len(scan_data.get("hosts", {}))) + """</p>
</div>
"""

# ‫إضافة معلومات المضيفات‬


for ip, host_info in scan_data.get("hosts", {}).items():
html += f"""
<div class="host">
<h2>‫المضيف‬: {ip}</h2>
"""

if host_info.get("hostname"):
html += f"<p>‫اسم المضيف‬: {host_info['hostname']}</p>"

# ‫جدول المنافذ‬
ports = host_info.get("ports", [])
if ports:
html += """
<h3>‫<المنافذ المفتوحة‬/h3>
<table>
<thead>
<tr>
<th>‫<المنفذ‬/th>
<th>‫<النوع‬/th>
<th>‫<الحالة‬/th>
<th>‫<الخدمة‬/th>
</tr>
</thead>
<tbody>
"""

for port in ports:


state_class = "open" if port["state"] == "open" else ("closed"
if port["state"] == "closed" else "filtered")
html += f"""
<tr>
<td>{port['number']}</td>
<td>{port['type']}</td>
<td class="{state_class}">{port['state']}</td>
<td>{port['service']}</td>
</tr>
"""

html += """
</tbody>
</table>
"""
else:
html += "<p>‫<لم يتم العثور على منافذ مفتوحة‬/p>"

html += "</div>"

# ‫إضافة المخرجات الخام‬


html += f"""
<div>
<h2>‫<المخرجات الخام‬/h2>
<pre style="background-color: #f9f9f9; padding: 15px; border-
radius: 5px; overflow: auto; direction: ltr; text-align: left;">
{scan_data.get("raw_output", "")}
</pre>
</div>

<div class="footer">
<p>‫ تم إنشاء هذا التقرير بواسطة برنامج واجهة‬Nmap ‫<الرسومية‬/p>
</div>
</div>
</body>
</html>
"""

with open(filename, 'w', encoding='utf-8') as f:


f.write(html)

return filename

class NetworkMapGenerator:
@staticmethod
def generate_map(hosts_info, filename):
# ‫ إنشاء مخطط الشبكة باستخدام‬mermaid
mermaid_code = """
graph TD
Internet((‫ ))الإنترنت‬--> Router[‫]الراوتر‬
"""

# ‫إضافة المضيفات إلى المخطط‬


for ip, host_info in hosts_info.items():
host_id = "host_" + ip.replace(".", "_")
host_label = ip
if host_info.get("hostname"):
host_label += "<br>" + host_info.get("hostname")
mermaid_code += f"""
Router --> {host_id}["{host_label}"]
"""

# ‫إضافة المنافذ المفتوحة‬


for port in host_info.get("ports", []):
if port["state"] == "open":
port_id = f"{host_id}_port_{port['number']}"
port_label = f"‫{ منفذ‬port['number']}<br>{port['service']}"
mermaid_code += f"""
{host_id} --> {port_id}["{port_label}"]
"""

# ‫ إنشاء ملف‬HTML ‫ يحتوي على مخطط‬mermaid


html = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>‫<مخطط الشبكة‬/title>
<script
src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<style>
body {{
font-family: Arial, sans-serif;
text-align: center;
direction: rtl;
}}
.mermaid {{
margin: 0 auto;
max-width: 1200px;
}}
</style>
</head>
<body>
<h1>‫<مخطط الشبكة‬/h1>
<div class="mermaid">
{mermaid_code}
</div>
<script>
mermaid.initialize({{ startOnLoad: true }});
</script>
</body>
</html>
"""

with open(filename, 'w', encoding='utf-8') as f:


f.write(html)

return filename

class SavedProfile:
def __init__(self, name, target, options, description=""):
self.name = name
self.target = target
self.options = options
self.description = description
self.created_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

class ProfileManager:
def __init__(self, settings):
self.settings = settings
self.profiles = self.load_profiles()

def load_profiles(self):
profiles = []
self.settings.beginGroup("ScanProfiles")
profile_count = self.settings.beginReadArray("profiles")

for i in range(profile_count):
self.settings.setArrayIndex(i)
name = self.settings.value("name")
target = self.settings.value("target")
options = self.settings.value("options")
description = self.settings.value("description", "")
created_date = self.settings.value("created_date",
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

profile = SavedProfile(name, target, options, description)


profile.created_date = created_date
profiles.append(profile)

self.settings.endArray()
self.settings.endGroup()

return profiles

def save_profiles(self):
self.settings.beginGroup("ScanProfiles")
self.settings.beginWriteArray("profiles")

for i, profile in enumerate(self.profiles):


self.settings.setArrayIndex(i)
self.settings.setValue("name", profile.name)
self.settings.setValue("target", profile.target)
self.settings.setValue("options", profile.options)
self.settings.setValue("description", profile.description)
self.settings.setValue("created_date", profile.created_date)

self.settings.endArray()
self.settings.endGroup()
self.settings.sync()

def add_profile(self, profile):


self.profiles.append(profile)
self.save_profiles()

def remove_profile(self, index):


if 0 <= index < len(self.profiles):
del self.profiles[index]
self.save_profiles()

def get_profile_names(self):
return [profile.name for profile in self.profiles]
class ScheduledScan:
def __init__(self, name, target, options, schedule_time, repeat=False,
repeat_interval=0):
self.name = name
self.target = target
self.options = options
self.schedule_time = schedule_time # QDateTime
self.repeat = repeat
self.repeat_interval = repeat_interval # ‫بالدقائق‬
self.last_run = None
self.enabled = True

class ScheduleManager:
def __init__(self, settings):
self.settings = settings
self.scheduled_scans = self.load_scheduled_scans()

def load_scheduled_scans(self):
scans = []
self.settings.beginGroup("ScheduledScans")
scan_count = self.settings.beginReadArray("scans")

for i in range(scan_count):
self.settings.setArrayIndex(i)
name = self.settings.value("name")
target = self.settings.value("target")
options = self.settings.value("options")
schedule_time_str = self.settings.value("schedule_time")
schedule_time = QDateTime.fromString(schedule_time_str, Qt.ISODate)
repeat = self.settings.value("repeat", False, type=bool)
repeat_interval = self.settings.value("repeat_interval", 0, type=int)
last_run_str = self.settings.value("last_run", "")
enabled = self.settings.value("enabled", True, type=bool)

scan = ScheduledScan(name, target, options, schedule_time, repeat,


repeat_interval)

if last_run_str:
scan.last_run = QDateTime.fromString(last_run_str, Qt.ISODate)

scan.enabled = enabled
scans.append(scan)

self.settings.endArray()
self.settings.endGroup()

return scans

def save_scheduled_scans(self):
self.settings.beginGroup("ScheduledScans")
self.settings.beginWriteArray("scans")

for i, scan in enumerate(self.scheduled_scans):


self.settings.setArrayIndex(i)
self.settings.setValue("name", scan.name)
self.settings.setValue("target", scan.target)
self.settings.setValue("options", scan.options)
self.settings.setValue("schedule_time",
scan.schedule_time.toString(Qt.ISODate))
self.settings.setValue("repeat", scan.repeat)
self.settings.setValue("repeat_interval", scan.repeat_interval)

if scan.last_run:
self.settings.setValue("last_run",
scan.last_run.toString(Qt.ISODate))

self.settings.setValue("enabled", scan.enabled)

self.settings.endArray()
self.settings.endGroup()
self.settings.sync()

def add_scheduled_scan(self, scan):


self.scheduled_scans.append(scan)
self.save_scheduled_scans()

def remove_scheduled_scan(self, index):


if 0 <= index < len(self.scheduled_scans):
del self.scheduled_scans[index]
self.save_scheduled_scans()

def get_scans_to_run(self):
"""‫"""إرجاع قائمة بالفحوصات التي يجب تشغيلها الآن‬
current_time = QDateTime.currentDateTime()
scans_to_run = []

for scan in self.scheduled_scans:


if not scan.enabled:
continue

if scan.last_run is None:
# ‫لم يتم تشغيلها من قبل‬
if scan.schedule_time <= current_time:
scans_to_run.append(scan)
elif scan.repeat:
# ‫حساب وقت التشغيل التالي‬
minutes_since_last_run = scan.last_run.secsTo(current_time) / 60
if minutes_since_last_run >= scan.repeat_interval:
scans_to_run.append(scan)

return scans_to_run

def update_last_run(self, scan_index):


if 0 <= scan_index < len(self.scheduled_scans):
self.scheduled_scans[scan_index].last_run = QDateTime.currentDateTime()
self.save_scheduled_scans()

class HostDiscoveryThread(QThread):
discovery_output = pyqtSignal(str)
discovery_complete = pyqtSignal(list)

def __init__(self, target_range):


super().__init__()
self.target_range = target_range
def run(self):
try:
self.discovery_output.emit(f"‫بدء اكتشاف المضيفات في النطاق‬:
{self.target_range}")

# ‫ استخدام‬Nmap ‫الكتشاف المضيفات النشطة‬


command = ["nmap", "-sn", self.target_range]

self.discovery_output.emit(f"‫تنفيذ الأمر‬: {' '.join(command)}")

process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True
)

# ‫استخراج المضيفات من المخرجات‬


hosts = []
for line in process.stdout:
self.discovery_output.emit(line.strip())

# ‫ البحث عن عناوين‬IP
if "Nmap scan report for" in line:
ip_match = re.search(r"for\s+(.+)\s+\((.+)\)", line)
if ip_match:
hostname = ip_match.group(1)
ip = ip_match.group(2)
hosts.append({"ip": ip, "hostname": hostname})
else:
# ‫ عنوان‬IP ‫فقط‬
ip_match = re.search(r"for\s+(.+)", line)
if ip_match:
ip = ip_match.group(1)
hosts.append({"ip": ip, "hostname": ""})

process.wait()
self.discovery_output.emit(f"‫ تم العثور على‬.‫اكتمل اكتشاف المضيفات‬
{len(hosts)} ‫مضيف‬.")
self.discovery_complete.emit(hosts)

except Exception as e:
self.discovery_output.emit(f"‫حدث خطأ في اكتشاف المضيفات‬: {str(e)}")
self.discovery_complete.emit([])

class PortSuggestionHelper:
@staticmethod
def get_common_ports():
"""‫"""إرجاع قائمة بالمنافذ الشائعة مع وصفها‬
return {
"21": "FTP",
"22": "SSH",
"23": "Telnet",
"25": "SMTP",
"53": "DNS",
"80": "HTTP",
"110": "POP3",
"115": "SFTP",
"135": "RPC",
"139": "NetBIOS",
"143": "IMAP",
"194": "IRC",
"443": "HTTPS",
"445": "SMB",
"1433": "MSSQL",
"1723": "PPTP",
"3306": "MySQL",
"3389": "RDP",
"5432": "PostgreSQL",
"5900": "VNC",
"8080": "HTTP Proxy"
}

@staticmethod
def get_port_groups():
"""‫"""إرجاع مجموعات المنافذ الشائعة‬
return {
"23,25,53,80,110,143,443-20" :"‫"المنافذ الأساسية‬,
"80,443,8080,8443" :"‫"منافذ الويب‬,
"1433,1521,3306,5432,6379,27017" :"‫"منافذ قواعد البيانات‬,
"22,23,3389,5900" :"‫"منافذ الإدارة عن بعد‬,
"25,110,143,465,587,993,995" :"‫"منافذ البريد الإلكتروني‬,
"135,139,445,3389" :"‫"منافذ ويندوز‬,
"‫ منفذ‬100 ‫"أفضل‬: "--top-ports 100",
"‫ منفذ‬1000 ‫"أفضل‬: "--top-ports 1000"
}

class NmapGUI(QMainWindow):
def __init__(self):
super().__init__()

# ‫إعدادات التطبيق‬
self.settings = QSettings("NmapGUI", "NmapScanner")

# ‫مدير الملفات الشخصية والجدولة‬


self.profile_manager = ProfileManager(self.settings)
self.schedule_manager = ScheduleManager(self.settings)

# ‫المتغيرات‬
self.scan_history = []
self.current_hosts_info = {}
self.scheduled_scan_timer = QTimer()
self.scheduled_scan_timer.timeout.connect(self.check_scheduled_scans)
self.scheduled_scan_timer.start(60000) # ‫التحقق كل دقيقة‬

self.initUI()
self.load_settings()

# ‫رمز الصينية النظام‬


self.setup_system_tray()

def setup_system_tray(self):
self.tray_icon = QSystemTrayIcon(self)
self.tray_icon.setIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))

# ‫قائمة رمز الصينية‬


tray_menu = QMenu()

show_action = QAction("‫إخفاء‬/‫"عرض‬, self)


show_action.triggered.connect(self.toggle_window_visibility)

quit_action = QAction("‫"خروج‬, self)


quit_action.triggered.connect(self.close)

tray_menu.addAction(show_action)
tray_menu.addSeparator()
tray_menu.addAction(quit_action)

self.tray_icon.setContextMenu(tray_menu)
self.tray_icon.activated.connect(self.tray_icon_activated)

# ‫تفعيل رمز الصينية‬


self.tray_icon.show()

def tray_icon_activated(self, reason):


if reason == QSystemTrayIcon.DoubleClick:
self.toggle_window_visibility()

def toggle_window_visibility(self):
if self.isVisible():
self.hide()
else:
self.show()
self.setWindowState(self.windowState() & ~Qt.WindowMinimized |
Qt.WindowActive)
self.activateWindow()

def initUI(self):
self.setWindowTitle("‫ أداة‬Nmap ‫ واجهة المستخدم الرسومية‬- ‫)"المتقدمة‬
self.setGeometry(100, 100, 1000, 700)

# ‫إنشاء شريط الأدوات‬


self.create_toolbar()

# ‫إنشاء شريط الحالة‬


self.statusBar = QStatusBar()
self.setStatusBar(self.statusBar)
self.statusBar.showMessage("‫)"جاهز‬

# ‫إنشاء ألسنة التبويب‬


self.tabs = QTabWidget()
self.scan_tab = QWidget()
self.history_tab = QWidget()
self.discovery_tab = QWidget()
self.vulnerability_tab = QWidget()
self.profiles_tab = QWidget()
self.schedule_tab = QWidget()
self.reports_tab = QWidget()
self.settings_tab = QWidget()

self.tabs.addTab(self.scan_tab, "‫)"الفحص‬
self.tabs.addTab(self.discovery_tab, "‫)"اكتشاف المضيفات‬
self.tabs.addTab(self.vulnerability_tab, "‫)"فحص الثغرات‬
self.tabs.addTab(self.history_tab, "‫)"السجل‬
self.tabs.addTab(self.profiles_tab, "‫)"الملفات الشخصية‬
self.tabs.addTab(self.schedule_tab, "‫)"جدولة الفحص‬
self.tabs.addTab(self.reports_tab, "‫)"التقارير‬
self.tabs.addTab(self.settings_tab, "‫)"الإعدادات‬

# ‫تهيئة ألسنة التبويب‬


self.setup_scan_tab()
self.setup_discovery_tab()
self.setup_vulnerability_tab()
self.

You might also like