From d7dc3e4ec4ab1e65612998c0213d93645e84b473 Mon Sep 17 00:00:00 2001 From: Yuri Dmitriev Date: Mon, 2 Jun 2025 14:53:57 +0300 Subject: [PATCH] v 0.1 --- .idea/.gitignore | 3 - .idea/attack_module.iml | 8 - .../inspectionProfiles/profiles_settings.xml | 6 - .idea/misc.xml | 7 - .idea/modules.xml | 8 - .idea/vcs.xml | 6 - Makefile | 8 + data/database.db | 0 data/nmap.json | 3064 ----------------- dpg.ini | 45 + fonts/Exo2.ttf | Bin 0 -> 303260 bytes pyproject.toml | 3 +- scripts/hping_load_test.py | 45 +- scripts/test_db.py | 26 + src/core/api/nmap.py | 2 +- src/core/attacks/hping_test.py | 1 - src/core/database/dao/session_dao.py | 66 + src/core/database/database.py | 233 +- src/core/database/managers/scanner_manager.py | 157 + src/core/database/managers/session_manager.py | 51 + src/core/models/host.py | 77 - src/core/models/models.py | 76 + src/core/services/gui.py | 261 -- src/main.py | 54 +- src/ui/configuration_window.py | 92 + src/ui/main_window.py | 75 + src/ui/scanner_window.py | 333 ++ src/ui/session_window.py | 74 + src/utils/window_utils.py | 42 + 29 files changed, 1252 insertions(+), 3571 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/attack_module.iml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml create mode 100644 Makefile delete mode 100644 data/database.db delete mode 100644 data/nmap.json create mode 100644 dpg.ini create mode 100644 fonts/Exo2.ttf create mode 100644 scripts/test_db.py create mode 100644 src/core/database/dao/session_dao.py create mode 100644 src/core/database/managers/scanner_manager.py create mode 100644 src/core/database/managers/session_manager.py delete mode 100644 src/core/models/host.py create mode 100644 src/core/models/models.py delete mode 100644 src/core/services/gui.py mode change 100644 => 100755 src/main.py create mode 100644 src/ui/configuration_window.py create mode 100644 src/ui/main_window.py create mode 100644 src/ui/scanner_window.py create mode 100644 src/ui/session_window.py create mode 100644 src/utils/window_utils.py diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/attack_module.iml b/.idea/attack_module.iml deleted file mode 100644 index 1e1327b..0000000 --- a/.idea/attack_module.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index fc4cdae..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index c5d59b3..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..07131b7 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +.PHONY: window + +.ONESHELL: + +# TODO: make clean command + +window: + PYTHONPATH=./ poetry run python src/main.py \ No newline at end of file diff --git a/data/database.db b/data/database.db deleted file mode 100644 index e69de29..0000000 diff --git a/data/nmap.json b/data/nmap.json deleted file mode 100644 index e9cd70b..0000000 --- a/data/nmap.json +++ /dev/null @@ -1,3064 +0,0 @@ -{ - "192.168.1.0": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.2": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.3": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.4": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.5": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.6": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.7": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.8": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.9": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.10": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.11": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.12": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.13": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.14": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.15": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.16": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.17": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.18": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.19": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.20": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.21": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.22": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.23": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.24": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.25": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.26": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.27": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.28": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.29": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.30": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.31": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.32": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.33": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.34": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.35": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.36": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.37": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.38": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.39": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.40": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.41": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.42": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.43": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.44": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.45": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.46": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.47": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.48": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.49": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.50": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.51": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.52": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.53": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.54": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.56": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.57": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.58": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.59": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.60": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.61": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.62": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.63": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.64": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.65": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.66": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.67": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.68": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.69": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.70": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.71": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.72": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.73": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.74": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.75": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.76": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.77": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.78": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.79": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.80": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.81": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.82": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.83": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.84": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.85": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.86": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.87": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.88": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.89": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.90": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.91": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.92": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.93": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.94": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.95": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.96": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.97": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.98": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.99": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.100": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.101": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.102": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.103": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.104": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.105": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.106": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.107": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.108": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.109": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.110": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.111": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.112": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.113": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.114": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.115": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.116": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.117": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.118": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.119": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.120": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.121": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.122": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.123": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.124": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.125": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.126": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.127": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.128": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.129": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.130": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.131": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.132": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.133": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.134": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.135": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.136": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.137": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.138": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.139": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.140": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.141": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.142": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.143": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.144": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.145": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.146": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.147": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.148": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.149": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.150": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.152": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.153": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.154": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.155": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.156": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.157": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.158": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.159": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.160": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.161": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.162": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.163": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.164": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.1": { - "osmatch": {}, - "ports": [ - { - "protocol": "tcp", - "portid": "22", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "ssh", - "product": "Dropbear sshd", - "extrainfo": "protocol 2.0", - "ostype": "Linux", - "method": "probed", - "conf": "10" - }, - "cpe": [ - { - "cpe": "cpe:/a:matt_johnston:dropbear_ssh_server" - }, - { - "cpe": "cpe:/o:linux:linux_kernel" - } - ], - "scripts": [] - }, - { - "protocol": "tcp", - "portid": "53", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "domain", - "product": "Cloudflare public DNS", - "method": "probed", - "conf": "10" - }, - "cpe": [], - "scripts": [] - }, - { - "protocol": "tcp", - "portid": "80", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "http", - "product": "OpenWrt uHTTPd", - "ostype": "Linux", - "devicetype": "WAP", - "method": "probed", - "conf": "10" - }, - "cpe": [ - { - "cpe": "cpe:/a:openwrt:uhttpd" - }, - { - "cpe": "cpe:/o:linux:linux_kernel" - } - ], - "scripts": [] - }, - { - "protocol": "tcp", - "portid": "443", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "http", - "product": "OpenWrt uHTTPd", - "ostype": "Linux", - "devicetype": "WAP", - "tunnel": "ssl", - "method": "probed", - "conf": "10" - }, - "cpe": [ - { - "cpe": "cpe:/a:openwrt:uhttpd" - }, - { - "cpe": "cpe:/o:linux:linux_kernel" - } - ], - "scripts": [] - } - ], - "hostname": [], - "macaddress": null, - "state": { - "state": "up", - "reason": "syn-ack", - "reason_ttl": "0" - } - }, - "192.168.1.55": { - "osmatch": {}, - "ports": [ - { - "protocol": "tcp", - "portid": "22", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "ssh", - "product": "OpenSSH", - "version": "9.2p1 Debian 2+deb12u5", - "extrainfo": "protocol 2.0", - "ostype": "Linux", - "method": "probed", - "conf": "10" - }, - "cpe": [ - { - "cpe": "cpe:/a:openbsd:openssh:9.2p1" - }, - { - "cpe": "cpe:/o:linux:linux_kernel" - } - ], - "scripts": [] - }, - { - "protocol": "tcp", - "portid": "502", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "modbus", - "product": "Modbus TCP", - "method": "probed", - "conf": "10" - }, - "cpe": [], - "scripts": [] - }, - { - "protocol": "tcp", - "portid": "8080", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "http", - "product": "Werkzeug httpd", - "version": "2.3.7", - "extrainfo": "Python 3.11.2", - "method": "probed", - "conf": "10" - }, - "cpe": [ - { - "cpe": "cpe:/a:python:python:3.11.2" - } - ], - "scripts": [] - }, - { - "protocol": "tcp", - "portid": "9090", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "http", - "product": "Apache Tomcat", - "extrainfo": "language: en", - "method": "probed", - "conf": "10" - }, - "cpe": [ - { - "cpe": "cpe:/a:apache:tomcat" - } - ], - "scripts": [] - } - ], - "hostname": [], - "macaddress": null, - "state": { - "state": "up", - "reason": "conn-refused", - "reason_ttl": "0" - } - }, - "192.168.1.151": { - "osmatch": {}, - "ports": [ - { - "protocol": "tcp", - "portid": "80", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "http", - "servicefp": "SF-Port80-TCP:V=7.95%I=7%D=5/30%Time=68399C33%P=x86_64-pc-linux-gnu%r(GetRequest,DA,\"HTTP/1\\.0\\x20200\\x20OK\\r\\nContent-Length:\\x20134\\r\\nContent-Type:\\x20text/html\\r\\nConnection:\\x20close\\r\\n\\r\\n

Some_Data:\\x2025\\.00°C

\")%r(HTTPOptions,4C,\"HTTP/1\\.0\\x20500\\x20Internal\\x20Server\\x20Error\\r\\nContent-Length:\\x200\\r\\nConnection:\\x20close\\r\\n\\r\\n\")%r(RTSPRequest,61,\"HTTP/1\\.1\\x20500\\x20Internal\\x20Server\\x20Error\\r\\nContent-Length:\\x200\\r\\nConnection:\\x20close\\r\\nAccept-Ranges:\\x20none\\r\\n\\r\\n\")%r(FourOhFourRequest,4C,\"HTTP/1\\.0\\x20500\\x20Internal\\x20Server\\x20Error\\r\\nContent-Length:\\x200\\r\\nConnection:\\x20close\\r\\n\\r\\n\")%r(SIPOptions,61,\"HTTP/1\\.1\\x20500\\x20Internal\\x20Server\\x20Error\\r\\nContent-Length:\\x200\\r\\nConnection:\\x20close\\r\\nAccept-Ranges:\\x20none\\r\\n\\r\\n\");", - "method": "probed", - "conf": "10" - }, - "cpe": [], - "scripts": [] - }, - { - "protocol": "tcp", - "portid": "502", - "state": "open", - "reason": "syn-ack", - "reason_ttl": "0", - "service": { - "name": "modbus", - "product": "Modbus TCP", - "method": "probed", - "conf": "10" - }, - "cpe": [], - "scripts": [] - } - ], - "hostname": [], - "macaddress": null, - "state": { - "state": "up", - "reason": "syn-ack", - "reason_ttl": "0" - } - }, - "192.168.1.165": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "up", - "reason": "conn-refused", - "reason_ttl": "0" - } - }, - "192.168.1.166": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.167": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.168": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.169": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.170": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.171": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.172": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.173": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.174": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.175": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.176": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.177": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.178": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "host-unreach", - "reason_ttl": "0" - } - }, - "192.168.1.179": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.180": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.181": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.182": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.183": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.184": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.185": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.186": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.187": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.188": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.189": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.190": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.191": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.192": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.193": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.194": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.195": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.196": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.197": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.198": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.199": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.200": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.201": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.202": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.203": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.204": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.205": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.206": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.207": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.208": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.209": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.210": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.211": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.212": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.213": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.214": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.215": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.216": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.217": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.218": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.219": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.220": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.221": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.222": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.223": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.224": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.225": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.226": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.227": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.228": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.229": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.230": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.231": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.232": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.233": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.234": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.235": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.236": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.237": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.238": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.239": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.240": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.241": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.242": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.243": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.244": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.245": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.246": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.247": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.248": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.249": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.250": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.251": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.252": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.253": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.254": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "no-response", - "reason_ttl": "0" - } - }, - "192.168.1.255": { - "osmatch": {}, - "ports": [], - "hostname": [], - "macaddress": null, - "state": { - "state": "down", - "reason": "net-unreach", - "reason_ttl": "0" - } - }, - "runtime": { - "time": "1748606143", - "timestr": "Fri May 30 14:55:43 2025", - "summary": "Nmap done at Fri May 30 14:55:43 2025; 256 IP addresses (4 hosts up) scanned in 210.09 seconds", - "elapsed": "210.09", - "exit": "success" - }, - "stats": { - "scanner": "nmap", - "args": "/usr/bin/nmap -v -oX - -sV -p 1-10000 192.168.1.0/24", - "start": "1748605933", - "startstr": "Fri May 30 14:52:13 2025", - "version": "7.95", - "xmloutputversion": "1.05" - }, - "task_results": [ - { - "task": "Ping Scan", - "time": "1748605942", - "extrainfo": "256 total hosts" - }, - { - "task": "Parallel DNS resolution of 4 hosts.", - "time": "1748605942" - }, - { - "task": "Connect Scan", - "time": "1748605995", - "extrainfo": "40000 total ports" - }, - { - "task": "Service scan", - "time": "1748606131", - "extrainfo": "10 services on 4 hosts" - }, - { - "task": "NSE", - "time": "1748606142" - }, - { - "task": "NSE", - "time": "1748606143" - } - ] -} \ No newline at end of file diff --git a/dpg.ini b/dpg.ini new file mode 100644 index 0000000..5c5a1fc --- /dev/null +++ b/dpg.ini @@ -0,0 +1,45 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][###24] +Pos=342,254 +Size=516,351 +Collapsed=0 + +[Window][###31] +Pos=340,250 +Size=600,300 +Collapsed=0 + +[Window][###39] +Size=210,800 +Collapsed=0 + +[Window][###38] +Size=222,103 +Collapsed=0 + +[Window][###35] +Size=222,103 +Collapsed=0 + +[Window][###47] +Pos=400,200 +Size=316,120 +Collapsed=0 + +[Window][###42] +Size=1274,794 +Collapsed=0 + +[Window][###52] +Size=210,800 +Collapsed=0 + +[Window][###108] +Pos=340,250 +Size=600,300 +Collapsed=0 + diff --git a/fonts/Exo2.ttf b/fonts/Exo2.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2170b15992251e2aa69558ae68d2958aa0b527a0 GIT binary patch literal 303260 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%0D`lwGv}u#eX|nam~5s)|=S> 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�p#S&6O7 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 literal 0 HcmV?d00001 diff --git a/pyproject.toml b/pyproject.toml index 500313e..c416649 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,8 @@ dependencies = [ "pymodbus (>=3.9.2,<4.0.0)", "loguru (>=0.7.3,<0.8.0)", "dbus-python (>=1.4.0,<2.0.0)", - "dearpygui (>=2.0.0,<3.0.0)" + "dearpygui (>=2.0.0,<3.0.0)", + "pyqt5 (>=5.15.11,<6.0.0)" ] diff --git a/scripts/hping_load_test.py b/scripts/hping_load_test.py index 495c4a5..d46479d 100644 --- a/scripts/hping_load_test.py +++ b/scripts/hping_load_test.py @@ -9,7 +9,7 @@ def main(): # config = HpingTestConfig( # target="192.168.1.55", # test_type="tcp", - # interface="enp7s0f1", + # interface="eth0", # spoof_ip="192.168.1.151", # Спуфинг источника # source_port=randint(45000,65535), # Порт источника # dest_port=502, # Порт назначения (Modbus) @@ -22,21 +22,42 @@ def main(): # verbose=True, # flood=True # ) + # config = HpingTestConfig( + # target="192.168.1.151", + # test_type="tcp", + # interface="enp7s0f1", + # spoof_ip="192.168.1.55", # Спуфинг источника + # source_port=randint(45000,65535), # Порт источника + # dest_port=502, # Порт назначения (Modbus) + # dest_port_range=False, # Использовать диапазон портов назначения (++) + # packet_size=12, # Размер пакета + # interval="u10000", # Интервал 30 микросекунд + # flags="PA", # Флаги PUSH + ACK (правильно: "P", "A") + # raw_data="/home/lodqa/attack_module_data/2_modbus_response.raw", # Сырые данные + # count=10000, + # verbose=True, + # flood=False + # ) + + # config = HpingTestConfig( + # target="192.168.1.55", + # test_type="icmp", + # interface="eth0", + # spoof_ip="192.168.1.151", # Спуфинг источника + # verbose=False, + # flood=True + # ) + config = HpingTestConfig( - target="192.168.1.151", - test_type="tcp", - interface="enp7s0f1", - spoof_ip="192.168.1.55", # Спуфинг источника + target="192.168.1.55", + test_type="udp", + interface="eth0", + spoof_ip="192.168.1.151", # Спуфинг источника source_port=randint(45000,65535), # Порт источника dest_port=502, # Порт назначения (Modbus) dest_port_range=False, # Использовать диапазон портов назначения (++) - packet_size=12, # Размер пакета - interval="u10000", # Интервал 30 микросекунд - flags="PA", # Флаги PUSH + ACK (правильно: "P", "A") - raw_data="/home/lodqa/attack_module_data/2_modbus_response.raw", # Сырые данные - count=10000, - verbose=True, - flood=False + verbose=False, + flood=True ) # Запуск теста diff --git a/scripts/test_db.py b/scripts/test_db.py new file mode 100644 index 0000000..91a589e --- /dev/null +++ b/scripts/test_db.py @@ -0,0 +1,26 @@ +from src.core.database.database import Database +from src.core.database.managers.session_manager import SessionManager + +def main(): + db = Database() + session_manager = SessionManager(db) + + # Создаем сессию с именем + session = session_manager.create_session(name="Test Session 1") + print(f"Created session: {session}") + + # Получаем все сессии + sessions = session_manager.get_all_sessions() + print(f"All sessions: {sessions}") + + # Обновляем имя сессии + session_manager.update_session_name(session.id, "Updated Test Session") + updated_session = session_manager.get_session(session.id) + print(f"Updated session: {updated_session}") + + # Удаляем сессию + session_manager.delete_session(session.id) + print(f"Deleted session {session.id}") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/core/api/nmap.py b/src/core/api/nmap.py index b6bc9aa..b1a4bbe 100644 --- a/src/core/api/nmap.py +++ b/src/core/api/nmap.py @@ -84,7 +84,7 @@ class NmapScanner: if __name__ == "__main__": try: - scanner = NmapScanner("192.168.1.0/24", "-p 1-10000") + 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}") diff --git a/src/core/attacks/hping_test.py b/src/core/attacks/hping_test.py index 2232ab7..d7a59cf 100644 --- a/src/core/attacks/hping_test.py +++ b/src/core/attacks/hping_test.py @@ -177,7 +177,6 @@ class Hping3Tester: if "packets tramitted" in line: parts = line.split() try: - print(parts) self.stats['sent'] = int(parts[0]) self.stats['received'] = int(parts[3]) loss_percent = float(parts[6].replace('%', '')) diff --git a/src/core/database/dao/session_dao.py b/src/core/database/dao/session_dao.py new file mode 100644 index 0000000..7149f7d --- /dev/null +++ b/src/core/database/dao/session_dao.py @@ -0,0 +1,66 @@ +from datetime import datetime +from typing import List, Optional +from src.core.database.database import Database +from src.core.models.models import Session +from src.utils.logger import get_logger + +logger = get_logger("session_dao") + +class SessionDAO: + def __init__(self, db: Database): + self.db = db + + def create(self, name: Optional[str] = None) -> Session: + """Создание новой сессии с именем.""" + with self.db.get_cursor() as cursor: + cursor.execute( + "INSERT INTO sessions (name, created_at) VALUES (?, CURRENT_TIMESTAMP) RETURNING *", + (name,) + ) + row = cursor.fetchone() + return Session( + id=row["id"], + name=row["name"], + created_at=datetime.fromisoformat(row["created_at"]) + ) + + def get_by_id(self, session_id: int) -> Optional[Session]: + """Получение сессии по ID.""" + with self.db.get_cursor() as cursor: + cursor.execute("SELECT * FROM sessions WHERE id = ?", (session_id,)) + row = cursor.fetchone() + if row: + return Session( + id=row["id"], + name=row["name"], + created_at=datetime.fromisoformat(row["created_at"]) + ) + return None + + def get_all(self) -> List[Session]: + """Получение всех сессий.""" + with self.db.get_cursor() as cursor: + cursor.execute("SELECT * FROM sessions ORDER BY created_at DESC") + rows = cursor.fetchall() + return [ + Session( + id=row["id"], + name=row["name"], + created_at=datetime.fromisoformat(row["created_at"]) + ) for row in rows + ] + + def delete(self, session_id: int) -> bool: + """Удаление сессии по ID.""" + with self.db.get_cursor() as cursor: + cursor.execute("DELETE FROM sessions WHERE id = ?", (session_id,)) + return cursor.rowcount > 0 + + def update_name(self, session_id: int, name: str) -> bool: + """Обновление имени сессии.""" + with self.db.get_cursor() as cursor: + cursor.execute( + "UPDATE sessions SET name = ? WHERE id = ?", + (name, session_id) + ) + return cursor.rowcount > 0 \ No newline at end of file diff --git a/src/core/database/database.py b/src/core/database/database.py index 3196359..a846e9b 100644 --- a/src/core/database/database.py +++ b/src/core/database/database.py @@ -1,121 +1,136 @@ +# src/core/database/db.py import sqlite3 -from typing import List, Dict, Any +from pathlib import Path +from typing import Optional +from contextlib import contextmanager + from src.utils.logger import get_logger -logger = get_logger("sqlite_db") +logger = get_logger("database") -class SQLiteDB: - def __init__(self, db_path: str): - """Инициализация соединения с базой данных.""" - self.db_path = db_path - self._create_tables() - logger.info(f"Инициализация базы данных SQLite: {db_path}") +class Database: + def __init__(self, db_path: str = "/home/lodqa/attack_module_data/security_scanner.db"): + self.db_path = Path(db_path) + self.db_path.parent.mkdir(parents=True, exist_ok=True) + self.conn: Optional[sqlite3.Connection] = None + self.init_db() - def _create_tables(self): - """Создание таблиц в базе данных.""" + def connect(self): + """Подключение к базе данных.""" try: - with sqlite3.connect(self.db_path) as conn: - cursor = conn.cursor() - # Таблица для хостов - cursor.execute(""" - CREATE TABLE IF NOT EXISTS hosts ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - ip TEXT NOT NULL UNIQUE, - state TEXT NOT NULL, - scan_timestamp TEXT NOT NULL - ) - """) - # Таблица для портов - cursor.execute(""" - CREATE TABLE IF NOT EXISTS ports ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - host_id INTEGER NOT NULL, - port INTEGER NOT NULL, - protocol TEXT, - state TEXT, - service TEXT, - version TEXT, - FOREIGN KEY (host_id) REFERENCES hosts(id) ON DELETE CASCADE - ) - """) - conn.commit() - logger.info("Таблицы успешно созданы или уже существуют") + self.conn = sqlite3.connect(self.db_path, check_same_thread=False) + self.conn.row_factory = sqlite3.Row + logger.info(f"Connected to database at {self.db_path}") except sqlite3.Error as e: - logger.error(f"Ошибка при создании таблиц: {e}") + logger.error(f"Failed to connect to database: {e}") raise - def save_scan_results(self, scan_results: Dict[str, Any]): - """Сохранение результатов сканирования в базу данных.""" + def init_db(self): + """Инициализация базы данных и создание таблиц.""" + self.connect() + cursor = self.conn.cursor() + + # Создание таблиц + cursor.executescript(""" + CREATE TABLE IF NOT EXISTS sessions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + + CREATE TABLE IF NOT EXISTS scans ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + session_id INTEGER, + tool TEXT, + args TEXT, + summary TEXT, + duration INTEGER, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS hosts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + scan_id INTEGER, + ip TEXT, + mac TEXT, + os TEXT, + FOREIGN KEY (scan_id) REFERENCES scans(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS ports ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + host_id INTEGER, + protocol TEXT, + port_num INTEGER, + state TEXT, + FOREIGN KEY (host_id) REFERENCES hosts(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS service ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + port_id INTEGER, + name TEXT, + product TEXT, + extrainfo TEXT, + ostype TEXT, + FOREIGN KEY (port_id) REFERENCES ports(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS cpe ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + service_id INTEGER, + name TEXT, + FOREIGN KEY (service_id) REFERENCES service(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS modbus_scan_result ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + scan_id INTEGER, + active_coils TEXT, + active_discrete_inputs TEXT, + active_holding_registers TEXT, + active_input_registers TEXT, + FOREIGN KEY (scan_id) REFERENCES scans(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS attacks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + session_id INTEGER, + tool TEXT, + args TEXT, + summary TEXT, + duration INTEGER, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS attack_result ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + attack_id INTEGER, + summary TEXT, + FOREIGN KEY (attack_id) REFERENCES attacks(id) ON DELETE CASCADE + ); + """) + self.conn.commit() + logger.info("Database tables initialized") + + @contextmanager + def get_cursor(self): + """Контекстный менеджер для работы с курсором.""" + cursor = self.conn.cursor() try: - with sqlite3.connect(self.db_path) as conn: - cursor = conn.cursor() - # Сохранение хостов - for ip, data in scan_results["hosts"].items(): - state = data.get("state", {}).get("state", "unknown") - timestamp = data.get("scan_timestamp", "unknown") - cursor.execute( - "INSERT OR REPLACE INTO hosts (ip, state, scan_timestamp) VALUES (?, ?, ?)", - (ip, state, timestamp) - ) - host_id = cursor.lastrowid if cursor.lastrowid else cursor.execute( - "SELECT id FROM hosts WHERE ip = ?", (ip,) - ).fetchone()[0] - # Сохранение портов - ports = data.get("ports", []) - for port_data in ports: - cursor.execute( - """ - INSERT INTO ports (host_id, port, protocol, state, service, version) - VALUES (?, ?, ?, ?, ?, ?) - """, - ( - host_id, - port_data.get("portid"), - port_data.get("protocol"), - port_data.get("state"), - port_data.get("service", {}).get("name"), - port_data.get("service", {}).get("version") - ) - ) - conn.commit() - logger.info(f"Результаты сканирования сохранены для {len(scan_results['hosts'])} хостов") - except sqlite3.Error as e: - logger.error(f"Ошибка при сохранении результатов: {e}") + yield cursor + self.conn.commit() + except Exception as e: + self.conn.rollback() + logger.error(f"Database operation failed: {e}") raise + finally: + cursor.close() - def get_all_hosts(self) -> List[Dict[str, Any]]: - """Получение всех хостов из базы данных.""" - try: - with sqlite3.connect(self.db_path) as conn: - cursor = conn.cursor() - cursor.execute("SELECT * FROM hosts") - hosts = [{"id": row[0], "ip": row[1], "state": row[2], "scan_timestamp": row[3]} for row in cursor.fetchall()] - logger.info(f"Извлечено {len(hosts)} хостов из базы данных") - return hosts - except sqlite3.Error as e: - logger.error(f"Ошибка при получении хостов: {e}") - return [] - - def get_ports_by_host_id(self, host_id: int) -> List[Dict[str, Any]]: - """Получение портов для указанного хоста.""" - try: - with sqlite3.connect(self.db_path) as conn: - cursor = conn.cursor() - cursor.execute("SELECT * FROM ports WHERE host_id = ?", (host_id,)) - ports = [ - { - "id": row[0], - "host_id": row[1], - "port": row[2], - "protocol": row[3], - "state": row[4], - "service": row[5], - "version": row[6] - } - for row in cursor.fetchall() - ] - logger.debug(f"Извлечено {len(ports)} портов для хоста с ID {host_id}") - return ports - except sqlite3.Error as e: - logger.error(f"Ошибка при получении портов для хоста {host_id}: {e}") - return [] \ No newline at end of file + def close(self): + """Закрытие соединения с базой данных.""" + if self.conn: + self.conn.close() + logger.info("Database connection closed") \ No newline at end of file diff --git a/src/core/database/managers/scanner_manager.py b/src/core/database/managers/scanner_manager.py new file mode 100644 index 0000000..9b014b0 --- /dev/null +++ b/src/core/database/managers/scanner_manager.py @@ -0,0 +1,157 @@ +from src.core.models.models import Scan, Host, ModbusScanResult +from src.core.database.database import Database +from src.utils.logger import get_logger +from typing import List, Optional + +logger = get_logger("scanner_service") + +class ScannerManager: + def __init__(self, db: Database): + self.db = db + + def save_scan(self, scan: Scan) -> Optional[Scan]: + """Сохранение сканирования в базу данных""" + with self.db.get_cursor() as cursor: + cursor.execute( + """ + INSERT INTO scans (session_id, tool, args, summary, duration, created_at) + VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP) + RETURNING * + """, + (scan.session_id, scan.tool, scan.args, scan.summary, scan.duration) + ) + row = cursor.fetchone() + if row: + return Scan( + id=row["id"], + session_id=row["session_id"], + tool=row["tool"], + args=row["args"], + summary=row["summary"], + duration=row["duration"], + created_at=row["created_at"] + ) + return None + + def update_scan(self, scan: Scan) -> bool: + """Обновление информации о сканировании""" + with self.db.get_cursor() as cursor: + cursor.execute( + """ + UPDATE scans + SET summary = ?, duration = ? + WHERE id = ? + """, + (scan.summary, scan.duration, scan.id) + ) + return cursor.rowcount > 0 + + def get_scan_by_id(self, scan_id: int) -> Optional[Scan]: + """Получение сканирования по ID""" + with self.db.get_cursor() as cursor: + cursor.execute("SELECT * FROM scans WHERE id = ?", (scan_id,)) + row = cursor.fetchone() + if row: + return Scan( + id=row["id"], + session_id=row["session_id"], + tool=row["tool"], + args=row["args"], + summary=row["summary"], + duration=row["duration"], + created_at=row["created_at"] + ) + return None + + def get_scans_by_session(self, session_id: int) -> List[Scan]: + """Получение всех сканирований для сессии""" + with self.db.get_cursor() as cursor: + cursor.execute( + "SELECT * FROM scans WHERE session_id = ? ORDER BY created_at DESC", + (session_id,) + ) + rows = cursor.fetchall() + return [ + Scan( + id=row["id"], + session_id=row["session_id"], + tool=row["tool"], + args=row["args"], + summary=row["summary"], + duration=row["duration"], + created_at=row["created_at"] + ) for row in rows + ] + + def save_host(self, scan_id: int, host: Host) -> Optional[Host]: + """Сохранение хоста в базу данных""" + with self.db.get_cursor() as cursor: + cursor.execute( + """ + INSERT INTO hosts (scan_id, ip, mac, os) + VALUES (?, ?, ?, ?) + RETURNING * + """, + (scan_id, host.ip, host.mac, host.os) + ) + row = cursor.fetchone() + if row: + return Host( + id=row["id"], + scan_id=row["scan_id"], + ip=row["ip"], + mac=row["mac"], + os=row["os"] + ) + return None + + def save_modbus_result(self, scan_id: int, result: dict) -> Optional[ModbusScanResult]: + """Сохранение результатов сканирования Modbus""" + with self.db.get_cursor() as cursor: + cursor.execute( + """ + INSERT INTO modbus_scan_result ( + scan_id, active_coils, active_discrete_inputs, + active_holding_registers, active_input_registers + ) + VALUES (?, ?, ?, ?, ?) + RETURNING * + """, + ( + scan_id, + result.get("active_coils"), + result.get("active_discrete_inputs"), + result.get("active_holding_registers"), + result.get("active_input_registers") + ) + ) + row = cursor.fetchone() + if row: + return ModbusScanResult( + id=row["id"], + scan_id=row["scan_id"], + active_coils=row["active_coils"], + active_discrete_inputs=row["active_discrete_inputs"], + active_holding_registers=row["active_holding_registers"], + active_input_registers=row["active_input_registers"] + ) + return None + + def get_modbus_result(self, scan_id: int) -> Optional[ModbusScanResult]: + """Получение результатов сканирования Modbus по ID сканирования""" + with self.db.get_cursor() as cursor: + cursor.execute( + "SELECT * FROM modbus_scan_result WHERE scan_id = ?", + (scan_id,) + ) + row = cursor.fetchone() + if row: + return ModbusScanResult( + id=row["id"], + scan_id=row["scan_id"], + active_coils=row["active_coils"], + active_discrete_inputs=row["active_discrete_inputs"], + active_holding_registers=row["active_holding_registers"], + active_input_registers=row["active_input_registers"] + ) + return None \ No newline at end of file diff --git a/src/core/database/managers/session_manager.py b/src/core/database/managers/session_manager.py new file mode 100644 index 0000000..fbc8acf --- /dev/null +++ b/src/core/database/managers/session_manager.py @@ -0,0 +1,51 @@ +from typing import List, Optional +from src.core.database.database import Database +from src.core.database.dao.session_dao import SessionDAO +from src.core.models.models import Session +from src.utils.logger import get_logger + +logger = get_logger("session_manager") + +class SessionManager: + def __init__(self, db: Database): + self.db = db + self.session_dao = SessionDAO(db) + + def create_session(self, name: Optional[str] = None) -> Session: + """Создание новой сессии с именем.""" + session = self.session_dao.create(name) + logger.info(f"Created session with ID {session.id} and name {session.name}") + return session + + def get_session(self, session_id: int) -> Optional[Session]: + """Получение сессии по ID.""" + session = self.session_dao.get_by_id(session_id) + if session: + logger.info(f"Retrieved session with ID {session_id}, name {session.name}") + else: + logger.warning(f"Session with ID {session_id} not found") + return session + + def get_all_sessions(self) -> List[Session]: + """Получение всех сессий.""" + sessions = self.session_dao.get_all() + logger.info(f"Retrieved {len(sessions)} sessions") + return sessions + + def delete_session(self, session_id: int) -> bool: + """Удаление сессии по ID.""" + success = self.session_dao.delete(session_id) + if success: + logger.info(f"Deleted session with ID {session_id}") + else: + logger.warning(f"Session with ID {session_id} not found for deletion") + return success + + def update_session_name(self, session_id: int, name: str) -> bool: + """Обновление имени сессии.""" + success = self.session_dao.update_name(session_id, name) + if success: + logger.info(f"Updated name for session with ID {session_id} to {name}") + else: + logger.warning(f"Session with ID {session_id} not found for name update") + return success \ No newline at end of file diff --git a/src/core/models/host.py b/src/core/models/host.py deleted file mode 100644 index 594fa36..0000000 --- a/src/core/models/host.py +++ /dev/null @@ -1,77 +0,0 @@ -from dataclasses import dataclass -from typing import Dict, List, Optional, Any - -@dataclass -class CPE: - cpe: str - -@dataclass -class Service: - name: str - product: Optional[str] = None - version: Optional[str] = None - extrainfo: Optional[str] = None - ostype: Optional[str] = None - method: str - conf: str - -@dataclass -class Port: - protocol: str - portid: str - state: str - reason: str - reason_ttl: str - service: Optional[Service] = None - cpe: List[CPE] = None - scripts: List[Any] = None - - def __post_init__(self): - if self.cpe is None: - self.cpe = [] - if self.scripts is None: - self.scripts = [] - -@dataclass -class HostState: - state: str - reason: str - reason_ttl: str - -@dataclass -class HostInfo: - osmatch: Dict[str, Any] - ports: List[Port] - hostname: List[Any] - macaddress: Optional[str] - state: HostState - -@dataclass -class TaskResult: - task: str - time: str - extrainfo: Optional[str] = None - -@dataclass -class Runtime: - time: str - timestr: str - summary: str - elapsed: str - exit: str - -@dataclass -class Stats: - scanner: str - args: str - start: str - startstr: str - version: str - xmloutputversion: str - -@dataclass -class NmapReport: - hosts: Dict[str, HostInfo] - runtime: Runtime - stats: Stats - task_results: List[TaskResult] diff --git a/src/core/models/models.py b/src/core/models/models.py new file mode 100644 index 0000000..641f317 --- /dev/null +++ b/src/core/models/models.py @@ -0,0 +1,76 @@ +# src/core/models/models.py +from dataclasses import dataclass +from datetime import datetime +from typing import Optional + +@dataclass +class Session: + id: Optional[int] = None + name: Optional[str] = None + created_at: Optional[datetime] = None + +@dataclass +class Scan: + id: Optional[int] = None + session_id: Optional[int] = None + tool: Optional[str] = None + args: Optional[str] = None + summary: Optional[str] = None + duration: Optional[int] = None # in seconds + created_at: Optional[datetime] = None + +@dataclass +class Host: + id: Optional[int] = None + scan_id: Optional[int] = None + ip: Optional[str] = None + mac: Optional[str] = None + os: Optional[str] = None + +@dataclass +class Port: + id: Optional[int] = None + host_id: Optional[int] = None + protocol: Optional[str] = None + port_num: Optional[int] = None + state: Optional[str] = None + +@dataclass +class Service: + id: Optional[int] = None + port_id: Optional[int] = None + name: Optional[str] = None + product: Optional[str] = None + extrainfo: Optional[str] = None + ostype: Optional[str] = None + +@dataclass +class CPE: + id: Optional[int] = None + service_id: Optional[int] = None + name: Optional[str] = None + +@dataclass +class ModbusScanResult: + id: Optional[int] = None + scan_id: Optional[int] = None + active_coils: Optional[str] = None + active_discrete_inputs: Optional[str] = None + active_holding_registers: Optional[str] = None + active_input_registers: Optional[str] = None + +@dataclass +class Attack: + id: Optional[int] = None + session_id: Optional[int] = None + tool: Optional[str] = None + args: Optional[str] = None + summary: Optional[str] = None + duration: Optional[int] = None # in seconds + created_at: Optional[datetime] = None + +@dataclass +class AttackResult: + id: Optional[int] = None + attack_id: Optional[int] = None + summary: Optional[str] = None \ No newline at end of file diff --git a/src/core/services/gui.py b/src/core/services/gui.py deleted file mode 100644 index ca5586b..0000000 --- a/src/core/services/gui.py +++ /dev/null @@ -1,261 +0,0 @@ -import dearpygui.dearpygui as dpg -from typing import Dict, Any, List, Callable -from src.core.api.nmap import NmapScanner -from src.core.database.database import SQLiteDB -from src.utils.logger import get_logger -import time -import os - -logger = get_logger("gui") - -class BaseTab: - """Базовый класс для вкладок GUI.""" - def __init__(self, parent: 'SecurityScannerGUI'): - self.parent = parent - - def create_content(self): - """Создание содержимого вкладки.""" - raise NotImplementedError("Метод create_content должен быть переопределен в дочернем классе") - -class ScanningTab(BaseTab): - """Вкладка для сканирования (Nmap).""" - def create_content(self): - with dpg.tab(label="Сканирование"): - dpg.add_text("Настройки сканирования Nmap") - dpg.add_input_text(label="Целевой IP", default_value="192.168.1.0/24", tag="scan_ip") - dpg.add_input_text(label="Аргументы", default_value="-p 1-10000", tag="scan_args") - dpg.add_button(label="Запустить сканирование", callback=self.parent.start_scan) - -class ResultsTab(BaseTab): - """Вкладка для отображения результатов.""" - def create_content(self): - with dpg.tab(label="Результаты"): - dpg.add_text("Результаты сканирования") - with dpg.group(horizontal=True): - dpg.add_text("Обновить результаты:") - dpg.add_button(label="Обновить", callback=self.parent.update_results) - with dpg.table( - header_row=True, - resizable=True, - policy=dpg.mvTable_SizingStretchProp, - borders_innerH=True, - borders_outerH=True, - borders_innerV=True, - borders_outerV=True, - tag="results_table" - ): - dpg.add_table_column(label="IP") - dpg.add_table_column(label="Состояние") - dpg.add_table_column(label="Время сканирования") - self.parent.port_details_group = dpg.add_group(show=False) - -class SettingsTab(BaseTab): - """Вкладка для настроек.""" - def create_content(self): - with dpg.tab(label="Настройки"): - dpg.add_text("Настройки приложения (в разработке)") - -class ExploitationTab(BaseTab): - """Вкладка для эксплуатации (заглушка).""" - def create_content(self): - with dpg.tab(label="Эксплуатация"): - dpg.add_text("Инструменты эксплуатации (в разработке: Metasploit, Scapy, Hping3)") - -class GenerationTab(BaseTab): - """Вкладка для генерации отчетов (заглушка).""" - def create_content(self): - with dpg.tab(label="Генерация"): - dpg.add_text("Генерация отчетов (PDF, JSON) в разработке") - -class SecurityScannerGUI: - """Главный класс GUI для управления интерфейсом.""" - def __init__(self, db: SQLiteDB): - self.db = db - self.tabs = [] - self.results_table = None - self.port_details_group = None - self.setup_dpg() - self.create_main_window() - - def setup_dpg(self): - """Настройка Dear PyGui с поддержкой кириллицы и адаптацией к размеру viewport'а.""" - dpg.create_context() - - # Создаём viewport с временными размерами - dpg.create_viewport( - title="Security Scanner", - width=800, - height=600, - x_pos=0, - y_pos=0, - resizable=True - ) - - # Загрузка шрифта с поддержкой кириллицы - font_path = os.path.join("/home/lodqa/attack_module_data/Exo2-VariableFont_wght.ttf") - if os.path.exists(font_path): - big_let_start = 0x00C0 # Capital "A" in cyrillic alphabet - big_let_end = 0x00DF # Capital "Я" in cyrillic alphabet - small_let_end = 0x00FF # small "я" in cyrillic alphabet - remap_big_let = 0x0410 # Starting number for remapped cyrillic alphabet - alph_len = big_let_end - big_let_start + 1 # adds the shift from big letters to small - alph_shift = remap_big_let - big_let_start # adds the shift from remapped to non-remapped - with dpg.font_registry(): - with dpg.font(font_path, 18) as default_font: - dpg.add_font_range_hint(dpg.mvFontRangeHint_Default) - dpg.add_font_range_hint(dpg.mvFontRangeHint_Cyrillic) - biglet = remap_big_let - for i1 in range(big_let_start, big_let_end + 1): - dpg.add_char_remap(i1, biglet) - dpg.add_char_remap(i1 + alph_len, biglet + alph_len) - biglet += 1 - dpg.bind_font(default_font) - else: - logger.warning(f"Шрифт {font_path} не найден. Используется шрифт по умолчанию.") - - # Завершаем настройку Dear PyGui - dpg.setup_dearpygui() - dpg.show_viewport() - - # Получаем текущие размеры viewport'а после инициализации - screen_width = dpg.get_viewport_client_width() - screen_height = dpg.get_viewport_client_height() - logger.debug(f"Размеры viewport'а: {screen_width}x{screen_height}") - - # Устанавливаем размеры окна на основе доступного пространства - dpg.configure_viewport( - "Security Scanner", - width=screen_width, - height=screen_height, - x_pos=0, - y_pos=0 - ) - - # Добавляем горячую клавишу для выхода (Ctrl+Q) - # with dpg.handler_registry(): - # dpg.add_key_press_handler(dpg.mvKey_Q, modifier=dpg.mvKeyMod_Control, callback=lambda: dpg.stop_dearpygui()) - - def create_main_window(self): - """Создание главного окна.""" - with dpg.window( - label="Security Scanner", - width=dpg.get_viewport_client_width(), - height=dpg.get_viewport_client_height(), - pos=[0, 0], - no_title_bar=False, - no_resize=False, - no_move=False, - no_close=False - ): - with dpg.tab_bar(tag="main_tab_bar"): - # Инициализация вкладок - self.tabs = [ - ScanningTab(self), - ResultsTab(self), - SettingsTab(self), - ExploitationTab(self), - GenerationTab(self) - ] - for tab in self.tabs: - tab.create_content() - - with dpg.group(): - dpg.add_text("Лог операций:") - self.log_text = dpg.add_text("", wrap=0) - - def add_new_tab(self, tab_name: str, content_callback: Callable): - """Добавление новой вкладки.""" - with dpg.tab(label=tab_name, parent="main_tab_bar"): - content_callback() - - def log(self, message: str, level: str = "info"): - """Логирование сообщения в интерфейсе и в логгер.""" - current_log = dpg.get_value(self.log_text) - timestamp = time.strftime("%Y-%m-%d %H:%M:%S") - new_log = f"{current_log}[{timestamp}] {message}\n" - dpg.set_value(self.log_text, new_log) - getattr(logger, level)(message) - - def start_scan(self, sender, app_data, user_data): - """Запуск сканирования Nmap.""" - ip = dpg.get_value("scan_ip") - args = dpg.get_value("scan_args") - self.log(f"Запуск сканирования для IP: {ip} с аргументами: {args}") - - try: - scanner = NmapScanner(ip, args) - results = scanner.start_scan() - # Добавляем временную метку - for host in results["hosts"].values(): - host["scan_timestamp"] = time.strftime("%Y-%m-%d %H:%M:%S") - self.db.save_scan_results(results) - self.log(f"Сканирование завершено. Найдено хостов: {len(results['hosts'])}", "success") - self.update_results() - except Exception as e: - self.log(f"Ошибка при сканировании: {e}", "error") - - def update_results(self, sender=None, app_data=None, user_data=None): - """Обновление таблицы результатов.""" - # Удаляем старую таблицу и создаем новую - if dpg.does_item_exist("results_table"): - dpg.delete_item("results_table") - with dpg.table( - header_row=True, - resizable=True, - policy=dpg.mvTable_SizingStretchProp, - borders_innerH=True, - borders_outerH=True, - borders_innerV=True, - borders_outerV=True, - tag="results_table" - ): - dpg.add_table_column(label="IP") - dpg.add_table_column(label="Состояние") - dpg.add_table_column(label="Время сканирования") - - hosts = self.db.get_all_hosts() - for host in hosts: - with dpg.table_row(): - dpg.add_text(host["ip"]) - dpg.add_text(host["state"]) - dpg.add_text(host["scan_timestamp"]) - dpg.add_table_cell().bind_item( - dpg.add_button(label="Детали", callback=self.show_port_details, user_data=host["id"]) - ) - - def show_port_details(self, sender, app_data, user_data): - """Отображение деталей портов для выбранного хоста.""" - host_id = user_data - if self.port_details_group and dpg.does_item_exist(self.port_details_group): - dpg.delete_item(self.port_details_group, children_only=True) - else: - self.port_details_group = dpg.add_group(show=False) - with dpg.group(parent=self.port_details_group): - dpg.add_text(f"Порты для хоста (ID: {host_id})") - with dpg.table( - header_row=True, - resizable=True, - policy=dpg.mvTable_SizingStretchProp, - borders_innerH=True, - borders_outerH=True, - borders_innerV=True, - borders_outerV=True - ): - dpg.add_table_column(label="Порт") - dpg.add_table_column(label="Протокол") - dpg.add_table_column(label="Состояние") - dpg.add_table_column(label="Сервис") - dpg.add_table_column(label="Версия") - ports = self.db.get_ports_by_host_id(host_id) - for port in ports: - with dpg.table_row(): - dpg.add_text(str(port["port"])) - dpg.add_text(port["protocol"]) - dpg.add_text(port["state"]) - dpg.add_text(port["service"] or "N/A") - dpg.add_text(port["version"] or "N/A") - - def run(self): - """Запуск интерфейса.""" - dpg.start_dearpygui() - dpg.destroy_context() \ No newline at end of file diff --git a/src/main.py b/src/main.py old mode 100644 new mode 100755 index 7fd4fc0..772cd52 --- a/src/main.py +++ b/src/main.py @@ -1,12 +1,52 @@ -from src.core.services.gui import SecurityScannerGUI -from src.core.database.database import SQLiteDB +import dearpygui.dearpygui as dpg +from src.ui.main_window import create_main_window +from src.core.database.database import Database +from src.utils.logger import get_logger + +logger = get_logger("main") def main(): - # Инициализация базы данных - db = SQLiteDB("/home/lodqa/attack_module_data/database.db") - # Инициализация интерфейса - gui = SecurityScannerGUI(db) - gui.run() + db = Database() + dpg.create_context() + dpg.configure_app(init_file="dpg.ini") + + # Увеличен размер шрифта с 16 до 24 + + big_let_start = 0x00C0 # Capital "A" in cyrillic alphabet + big_let_end = 0x00DF # Capital "Я" in cyrillic alphabet + small_let_end = 0x00FF # small "я" in cyrillic alphabet + remap_big_let = 0x0410 # Starting number for remapped cyrillic alphabet + alph_len = big_let_end - big_let_start + 1 # adds the shift from big letters to small + alph_shift = remap_big_let - big_let_start # adds the shift from remapped to non-remapped + with dpg.font_registry(): + with dpg.font("fonts/Exo2.ttf", 24) as default_font: + dpg.add_font_range_hint(dpg.mvFontRangeHint_Default) + dpg.add_font_range_hint(dpg.mvFontRangeHint_Cyrillic) + biglet = remap_big_let # Starting number for remapped cyrillic alphabet + for i1 in range(big_let_start, big_let_end + 1): # Cycle through big letters in cyrillic alphabet + dpg.add_char_remap(i1, biglet) # Remap the big cyrillic letter + dpg.add_char_remap(i1 + alph_len, biglet + alph_len) # Remap the small cyrillic letter + biglet += 1 # choose next letter + dpg.bind_font(default_font) + + create_main_window(db) + dpg.bind_font(default_font) + + # Увеличены минимальные размеры окна + dpg.create_viewport( + title="Security Scanner", + min_width=1600, + min_height=900, + ) + dpg.setup_dearpygui() + dpg.show_viewport() + + # Растягиваем главное окно на весь viewport + dpg.set_primary_window("main_window", True) + + dpg.start_dearpygui() + dpg.destroy_context() + logger.info("Application closed") if __name__ == "__main__": main() \ No newline at end of file diff --git a/src/ui/configuration_window.py b/src/ui/configuration_window.py new file mode 100644 index 0000000..fc14d4a --- /dev/null +++ b/src/ui/configuration_window.py @@ -0,0 +1,92 @@ +import dearpygui.dearpygui as dpg +from src.ui.scanner_window import create_scanner_window +from src.core.models.models import Session +from src.utils.logger import get_logger + +logger = get_logger("config_window") + +def create_configuration_window(db, session: Session): + """Окно конфигурации сессии""" + with dpg.window( + tag="config_window", + label=f"Session: {session.name}", + no_collapse=True, + no_resize=True, + no_close=True, + no_title_bar=True, + no_scrollbar=True, + no_move=True, + no_scroll_with_mouse=True + ): + # Главная горизонтальная группа для разделения на панели + with dpg.group(horizontal=True): + # Боковая панель навигации + with dpg.child_window( + tag="sidebar", + width=270, + height=-1, + border=False + ): + dpg.add_text("Меню", color=(200, 200, 200)) + dpg.add_separator() + + dpg.add_button( + label="Сканирование", + callback=lambda: show_scanner_window(db, session), + width=-1, + height=50 + ) + dpg.add_spacer(height=10) + + dpg.add_button( + label="Эксплуатация", + callback=lambda: logger.info("Attacks selected"), + width=-1, + height=50 + ) + dpg.add_spacer(height=10) + + dpg.add_button( + label="Генерация отчета", + callback=lambda: logger.info("Reporting selected"), + width=-1, + height=50 + ) + dpg.add_spacer(height=10) + + dpg.add_button( + label="Лог приложения", + callback=lambda: logger.info("Log selected"), + width=-1, + height=50 + ) + + dpg.add_spacer(height=30) + dpg.add_text(f"Сессия: {session.name}", color=(150, 150, 150)) + created_at = session.created_at.strftime( + """%Y-%m-%d + %H:%M""" + ) if session.created_at else "Unknown" + dpg.add_text(f"Дата создания: {created_at}", color=(150, 150, 150)) + + # Основная область контента (контейнер) + with dpg.child_window( + tag="content_area", + width=-1, + height=-1, + border=False + ): + # Начальное содержимое + dpg.add_text("Выберите подмодуль", tag="initial_content") + + # Установить окно конфигурации как основное + dpg.set_primary_window("config_window", True) + +def show_scanner_window(db, session): + """Показать окно сканирования""" + # Очистить контентную область + if dpg.does_item_exist("content_area"): + dpg.delete_item("content_area", children_only=True) + + # Создать окно сканирования внутри контентной области + create_scanner_window(db, session, parent="content_area") \ No newline at end of file diff --git a/src/ui/main_window.py b/src/ui/main_window.py new file mode 100644 index 0000000..b2f2a60 --- /dev/null +++ b/src/ui/main_window.py @@ -0,0 +1,75 @@ +import dearpygui.dearpygui as dpg +from src.ui.session_window import create_session_window +from src.core.database.managers.session_manager import SessionManager +from src.utils.logger import get_logger + +logger = get_logger("main_window") + +def create_main_window(db): + """Создание главного окна приложения""" + with dpg.window( + tag="main_window", + label="Security Scanner", + no_collapse=True, + no_resize=True, + no_close=True, + no_title_bar=True, + no_move=True, + ): # Убраны фиксированные размеры + # Заголовок с увеличенным шрифтом + dpg.add_text("Модуль тестирования безопасности", color=(255, 255, 255), pos=[600,0]) + dpg.add_spacing(count=10) + dpg.add_separator() + + # Увеличенные размеры кнопки + dpg.add_button( + label="Создать новую сессию", + callback=lambda: create_session_window(db), + width=300, # Увеличено с 200 + height=50 # Увеличено с 40 + ) + dpg.add_spacer(height=30) # Увеличен отступ + + # Список сессий с увеличенными размерами + dpg.add_text("Существующие сессии:") + session_list = dpg.add_listbox( + tag="session_list", + width=1600, # Растягиваем на всю ширину окна + num_items=15, # Увеличено количество отображаемых элементов + # height=500 # Увеличена высота + callback=lambda s: open_session(s, db) + ) + + load_sessions(db, session_list) + +def load_sessions(db, session_list): + """Загрузка списка сессий""" + session_manager = SessionManager(db) + sessions = session_manager.get_all_sessions() + + session_items = [] + for session in sessions: + date_str = session.created_at.strftime("%Y-%m-%d %H:%M") if session.created_at else "Unknown" + session_items.append(f"ID:{session.id} - {session.name or 'Unnamed Session'} - Created at:{date_str}") + + dpg.configure_item(session_list, items=session_items) + logger.info(f"Loaded {len(sessions)} sessions") + +def open_session(sender, db): + """Открытие выбранной сессии""" + session_manager = SessionManager(db) + sessions = session_manager.get_all_sessions() + + + if dpg.get_value(sender) and sessions: + session_id = int(dpg.get_value(sender).split()[0][3:]) + print(session_id) + print(len(sessions)) + if session_id <= len(sessions): + session = sessions[session_id-1] + logger.info(f"Opening session: {session.name} (ID: {session.id})") + + # Закрыть текущее окно и открыть окно конфигурации + dpg.delete_item("main_window") + from src.ui.configuration_window import create_configuration_window + create_configuration_window(db, session) \ No newline at end of file diff --git a/src/ui/scanner_window.py b/src/ui/scanner_window.py new file mode 100644 index 0000000..4654a65 --- /dev/null +++ b/src/ui/scanner_window.py @@ -0,0 +1,333 @@ +import dearpygui.dearpygui as dpg +from src.core.models.models import Session, Scan, Host +from src.core.database.managers.scanner_manager import ScannerManager +from src.utils.logger import get_logger +import threading +import time + +logger = get_logger("scanner_window") + +def create_scanner_window(db, session: Session, parent=None): + """Окно сканирования (с поддержкой родительского контейнера)""" + scanner_service = ScannerManager(db) + + # Если указан родитель, создаем внутри него + if parent: + print(parent) + with dpg.child_window( + parent=parent, + tag="scanner_window", + width=-1, + height=-1 + ): + build_scanner_content(scanner_service, session) + else: + with dpg.child_window( + tag="scanner_window", + width=-1, + height=-1 + ): + build_scanner_content(scanner_service, session) + +def build_scanner_content(scanner_service, session): + """Построение содержимого окна сканирования""" + # Заголовок + dpg.add_text("Сканирование", color=(255, 255, 255)) + dpg.add_separator() + dpg.add_spacer(height=10) + + # Вкладки + with dpg.tab_bar(tag="scan_tabs"): + # Вкладка Nmap + with dpg.tab(tag="nmap_tab", label="Nmap Scanning"): + create_nmap_tab(scanner_service, session) + + # Вкладка OpenVAS + with dpg.tab(tag="openvas_tab", label="OpenVAS Scanning"): + dpg.add_text("OpenVAS scanning will be implemented here") + + # Вкладка Modbus + with dpg.tab(tag="modbus_tab", label="Modbus Scanning"): + create_modbus_tab(scanner_service, session) + + # Вкладка результатов + with dpg.tab(tag="results_tab", label="Scan Results"): + create_results_tab(scanner_service, session) + +def create_nmap_tab(scanner_service, session): + """Вкладка Nmap сканирования""" + with dpg.group(): + # Конфигурация сканирования + with dpg.group(tag="nmap_config_group"): + dpg.add_text("Scan Configuration") + + dpg.add_text("Target:") + target_input = dpg.add_input_text(tag="nmap_target", width=300) + + dpg.add_text("Scan Type:") + scan_type = dpg.add_combo( + tag="nmap_scan_type", + items=["Quick Scan", "Intensive Scan", "Full Scan", "Custom Scan"], + default_value="Quick Scan", + width=200 + ) + + dpg.add_text("Custom Arguments:") + custom_args = dpg.add_input_text(tag="nmap_custom_args", width=300) + + # Кнопка запуска + dpg.add_button( + label="Start Nmap Scan", + callback=lambda: start_nmap_scan( + scanner_service, + session, + dpg.get_value(target_input), + dpg.get_value(scan_type), + dpg.get_value(custom_args) + ), + width=200, + height=40 # Увеличена высота + ) + dpg.add_spacer(height=10) + + # Область вывода + dpg.add_text("Output:") + output_area = dpg.add_input_text( + tag="nmap_output", + multiline=True, + height=300, + width=-1, # Растянуть на всю ширину + readonly=True + ) + +def create_modbus_tab(scanner_service, session): + """Вкладка Modbus сканирования""" + with dpg.group(): + # Конфигурация сканирования + with dpg.group(tag="modbus_config_group"): + dpg.add_text("Modbus Scan Configuration") + + dpg.add_text("Target IP:") + target_input = dpg.add_input_text(tag="modbus_target", width=300) + + dpg.add_text("Port:") + port_input = dpg.add_input_text(tag="modbus_port", default_value="502", width=100) + + # Кнопка запуска + dpg.add_button( + label="Start Modbus Scan", + callback=lambda: start_modbus_scan( + scanner_service, + session, + dpg.get_value(target_input), + dpg.get_value(port_input) + ), + width=200, + height=40 # Увеличена высота + ) + dpg.add_spacer(height=10) + + # Область вывода + dpg.add_text("Output:") + output_area = dpg.add_input_text( + tag="modbus_output", + multiline=True, + height=300, + width=-1, # Растянуть на всю ширину + readonly=True + ) + +def create_results_tab(scanner_service, session): + """Вкладка результатов сканирования""" + with dpg.group(): + # Список сканирований + dpg.add_text("Scan History:") + scan_list = dpg.add_listbox( + tag="scan_list", + width=-1, # Растянуть на всю ширину + num_items=10, + callback=lambda s: show_scan_details(scanner_service, dpg.get_value(s)) + ) + + # Загрузка истории + load_scan_history(scanner_service, session, scan_list) + dpg.add_spacer(height=10) + + # Детали сканирования + dpg.add_text("Scan Details:") + scan_details = dpg.add_input_text( + tag="scan_details", + multiline=True, + height=300, + width=-1, # Растянуть на всю ширину + readonly=True + ) + +def start_nmap_scan(scanner_service, session, target, scan_type, custom_args): + """Запуск Nmap сканирования""" + if not target: + logger.warning("Nmap scan started without target") + return + + # Обновить вывод + dpg.set_value("nmap_output", f"Starting {scan_type} scan on {target}...\n") + + # Создать объект сканирования + scan = Scan( + session_id=session.id, + tool="nmap", + args=f"Type: {scan_type}, Args: {custom_args}", + summary="In progress" + ) + + # Сохранить в базу + saved_scan = scanner_service.save_scan(scan) + if saved_scan: + dpg.set_value("nmap_output", dpg.get_value("nmap_output") + f"Scan ID: {saved_scan.id}\n") + + # Запуск в отдельном потоке + thread = threading.Thread( + target=run_nmap_scan, + args=(scanner_service, session, target, saved_scan.id) + ) + thread.start() + +def run_nmap_scan(scanner_service, session, target, scan_id): + """Выполнение Nmap сканирования (в потоке)""" + try: + # Имитация сканирования + output = dpg.get_value("nmap_output") + "Scanning network...\n" + dpg.set_value("nmap_output", output) + time.sleep(2) + + # Имитация результатов + hosts = [ + {"ip": "192.168.1.100", "mac": "00:11:22:33:44:55", "os": "Linux"}, + {"ip": "192.168.1.101", "mac": "AA:BB:CC:DD:EE:FF", "os": "Windows"} + ] + + # Сохранить результаты + for host in hosts: + host_obj = Host( + scan_id=scan_id, + ip=host["ip"], + mac=host["mac"], + os=host["os"] + ) + scanner_service.save_host(scan_id, host_obj) + output = dpg.get_value("nmap_output") + f"Found host: {host['ip']} ({host['os']})\n" + dpg.set_value("nmap_output", output) + + # Обновить статус + scan = Scan( + id=scan_id, + summary=f"Found {len(hosts)} hosts", + duration=2 + ) + scanner_service.update_scan(scan) + + output = dpg.get_value("nmap_output") + "Scan completed!\n" + dpg.set_value("nmap_output", output) + + # Обновить список сканирований + if dpg.does_item_exist("scan_list"): + load_scan_history(scanner_service, session, "scan_list") + + except Exception as e: + output = dpg.get_value("nmap_output") + f"Error: {str(e)}\n" + dpg.set_value("nmap_output", output) + logger.error(f"Nmap scan failed: {e}") + +def start_modbus_scan(scanner_service, session, target, port): + """Запуск Modbus сканирования""" + if not target: + logger.warning("Modbus scan started without target") + return + + # Обновить вывод + dpg.set_value("modbus_output", f"Starting Modbus scan on {target}:{port}...\n") + + # Создать объект сканирования + scan = Scan( + session_id=session.id, + tool="modbus", + args=f"Target: {target}, Port: {port}", + summary="In progress" + ) + + # Сохранить в базу + saved_scan = scanner_service.save_scan(scan) + if saved_scan: + dpg.set_value("modbus_output", dpg.get_value("modbus_output") + f"Scan ID: {saved_scan.id}\n") + + # Запуск в отдельном потоке + thread = threading.Thread( + target=run_modbus_scan, + args=(scanner_service, session, target, int(port), saved_scan.id) + ) + thread.start() + +def run_modbus_scan(scanner_service, session, target, port, scan_id): + """Выполнение Modbus сканирования (в потоке)""" + try: + # Имитация сканирования + output = dpg.get_value("modbus_output") + "Connecting to device...\n" + dpg.set_value("modbus_output", output) + time.sleep(1) + + # Имитация результатов + results = { + "active_coils": "0, 1, 5, 7", + "active_discrete_inputs": "2, 3", + "active_holding_registers": "100, 101, 105", + "active_input_registers": "200, 201" + } + + # Сохранить результаты + scanner_service.save_modbus_result(scan_id, results) + + # Обновить статус + scan = Scan( + id=scan_id, + summary="Modbus scan completed", + duration=1 + ) + scanner_service.update_scan(scan) + + output = dpg.get_value("modbus_output") + "Scan completed!\n" + output += f"Active coils: {results['active_coils']}\n" + output += f"Active holding registers: {results['active_holding_registers']}\n" + dpg.set_value("modbus_output", output) + + # Обновить список сканирований + if dpg.does_item_exist("scan_list"): + load_scan_history(scanner_service, session, "scan_list") + + except Exception as e: + output = dpg.get_value("modbus_output") + f"Error: {str(e)}\n" + dpg.set_value("modbus_output", output) + logger.error(f"Modbus scan failed: {e}") + +def load_scan_history(scanner_service, session, scan_list): + """Загрузка истории сканирований""" + scans = scanner_service.get_scans_by_session(session.id) + scan_items = [] + + for scan in scans: + item_text = f"{scan.tool} scan - {scan.created_at.strftime('%Y-%m-%d %H:%M')}" + if scan.summary: + item_text += f" ({scan.summary})" + scan_items.append(item_text) + + dpg.configure_item(scan_list, items=scan_items) + +def show_scan_details(scanner_service, scan_index): + """Отображение деталей сканирования""" + if scan_index is None: + return + + # Получить все сканирования + # (В реальности нужно хранить текущую сессию или передавать ее) + # Для демо: просто покажем заглушку + details = f"Scan details for index {scan_index}\n" + dpg.set_value("scan_details", details) \ No newline at end of file diff --git a/src/ui/session_window.py b/src/ui/session_window.py new file mode 100644 index 0000000..542396f --- /dev/null +++ b/src/ui/session_window.py @@ -0,0 +1,74 @@ + +import dearpygui.dearpygui as dpg +from src.core.database.managers.session_manager import SessionManager +from src.utils.logger import get_logger + +logger = get_logger("session_window") + +def create_session_window(db): + """Окно создания новой сессии""" + with dpg.window( + tag="session_window", + label="New Session", + no_collapse=True, + no_resize=True, + no_close=True, + no_title_bar=True, + width=600, # Увеличена ширина окна + height=300, # Увеличена высота окна + modal=True, # Добавлен модальный режим + ): + dpg.add_text("Создание новое сессии") + dpg.add_separator() + + dpg.add_text("Имя сессии:") + # Увеличен размер поля ввода + session_name = dpg.add_input_text(tag="session_name", width=500) + dpg.add_spacer(height=20) + + # Увеличены размеры кнопок + with dpg.group(horizontal=True): + dpg.add_button( + label="Создать", + callback=lambda: create_session(db, session_name), + width=150, # Увеличено с 100 + height=40 # Увеличена высота + ) + dpg.add_spacer(width=20) + dpg.add_button( + label="Отмена", + callback=lambda: dpg.delete_item("session_window"), + width=150, # Увеличено с 100 + height=40 # Увеличена высота + ) + + # Центрирование окна после создания + dpg.split_frame() + viewport_width = dpg.get_viewport_width() + viewport_height = dpg.get_viewport_height() + win_width = dpg.get_item_width("session_window") + win_height = dpg.get_item_height("session_window") + dpg.set_item_pos( + "session_window", + [(viewport_width - win_width) // 2, (viewport_height - win_height) // 2] + ) + + +def create_session(db, session_name): + """Создание новой сессии""" + name = dpg.get_value(session_name) + if not name: + logger.warning("Attempt to create session without name") + return + + session_manager = SessionManager(db) + session = session_manager.create_session(name) + + if session: + logger.info(f"Created new session: {name}") + dpg.delete_item("session_window") + + # Обновить список сессий в главном окне + if dpg.does_item_exist("session_list"): + from src.ui.main_window import load_sessions + load_sessions(db, "session_list") \ No newline at end of file diff --git a/src/utils/window_utils.py b/src/utils/window_utils.py new file mode 100644 index 0000000..b436aba --- /dev/null +++ b/src/utils/window_utils.py @@ -0,0 +1,42 @@ +# src/utils/window_utils.py +from PyQt5.QtWidgets import QDialog, QMessageBox, QInputDialog +from PyQt5.QtCore import Qt + +def show_floating_dialog(parent, title, message, icon=QMessageBox.Information): + """Показывает диалоговое окно как плавающее поверх всех окон""" + dialog = QMessageBox(parent) + dialog.setWindowTitle(title) + dialog.setText(message) + dialog.setIcon(icon) + + # Устанавливаем флаги для плавающего окна + dialog.setWindowFlags( + Qt.Window | + Qt.CustomizeWindowHint | + Qt.WindowTitleHint | + Qt.WindowStaysOnTopHint + ) + + # Отключаем тайлинг для этого окна + dialog.setProperty("hyprland_floating", True) + + return dialog.exec_() + +def create_floating_input(parent, title, label): + """Создает плавающее окно ввода""" + dialog = QInputDialog(parent) + dialog.setWindowTitle(title) + dialog.setLabelText(label) + + # Устанавливаем флаги для плавающего окна + dialog.setWindowFlags( + Qt.Window | + Qt.CustomizeWindowHint | + Qt.WindowTitleHint | + Qt.WindowStaysOnTopHint + ) + + # Отключаем тайлинг для этого окна + dialog.setProperty("hyprland_floating", True) + + return dialog \ No newline at end of file