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 0000000..2170b15 Binary files /dev/null and b/fonts/Exo2.ttf differ 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