From f4ebea4decc25869bb1fd078a79583337d31490b Mon Sep 17 00:00:00 2001 From: mmichlol Date: Wed, 4 Feb 2026 21:43:58 +0100 Subject: [PATCH] Initial commit --- .gitattributes | 2 + .gitignore | 181 ++++++++++++++++++++++++++++++++++++++++ LICENSE | 21 +++++ README.md | 17 ++++ main.py | 23 ++++++ network_scanner.py | 75 +++++++++++++++++ sendMessage.py | 10 +++ templates/index.html | 191 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 520 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 main.py create mode 100644 network_scanner.py create mode 100644 sendMessage.py create mode 100644 templates/index.html diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd15ec4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,181 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +#uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Cursor +# Cursor is an AI-powered code editor.`.cursorignore` specifies files/directories to +# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data +# refer to https://docs.cursor.com/context/ignore-files +.cursorignore +.cursorindexingignore \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c81fda3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 mmichlol + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b84222e --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# SkanerV2 +## Opis +Skaner V2 to kolejna odsłona naszego narzędzia do skanowania sieci lokalnej w poszukiwaniu urządzeń i otwartych portów na tych urządzeniach. Zasada działania podobna do nmap tylko napisane w pytonie, htmlu, css i js i kożystające z wygodnego interfejsu przeglądarkowego. Cały czas dodajemy do niego dodatkowe funkcje więc jak to się mówi ***"stay tuned"*** :) +## Instrukcje użytkowania + +### 1. Zainstaluj potrzebne pakiety do pythona: +``` +pip install flask threading requests sockets +``` +### 2. Pobierz i rozpakuj plik z kodem +### 3. Przejdź do katalogu z kodem +### 4. Uruchom kod +``` +python main.py +``` +### 5. Przejdź do [interfejsu sieciowego](http://127.0.0.1:5000) +### 6. Kliknij "Skanuj sieć" diff --git a/main.py b/main.py new file mode 100644 index 0000000..5a8ae12 --- /dev/null +++ b/main.py @@ -0,0 +1,23 @@ +from flask import Flask, render_template, jsonify +from network_scanner import NetworkScanner +import threading +import requests + +app = Flask(__name__) +scanner = NetworkScanner() + +@app.route('/') +def index(): + return render_template('index.html') # Zwróć stronę główną + +@app.route('/scan') +def scan(): + # Rozpocznij skanowanie w nowym wątku + thread = threading.Thread(target=scanner.scan_network_for_devices) + thread.start() + thread.join() # Czekaj na zakończenie skanowania + return jsonify(scanner.devices) # Zwróć znalezione urządzenia jako JSON + + +if __name__ == '__main__': + app.run(debug=True) # Uruchom serwer diff --git a/network_scanner.py b/network_scanner.py new file mode 100644 index 0000000..ffedb32 --- /dev/null +++ b/network_scanner.py @@ -0,0 +1,75 @@ +import socket +import threading + +class NetworkScanner: + def __init__(self): + self.devices = [] + self.lock = threading.Lock() # Lock do synchronizacji dostępu do listy urządzeń + self.running = False + + def is_port_open(self, ip, port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(0.05) # Zmniejszony timeout + try: + result = sock.connect_ex((ip, port)) + return result == 0 + finally: + sock.close() + + def scan_ip(self, ip): + ports = [21, 22, 23, 25, 53, 67, 68, 69, 70, 79, 80, 110, 111, 115, 123, 137, 138, 139, 143, 161, 162, 179, 194, 220, 389, 443, 445, 465, 514, 515, 543, 548, 554, 587, 631, 636, 646, 669, 688, 690, 700, 707, 720, 749, 750, 780, 818, 830, 843, 873, 880, 888, 990, 993, 995, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079] # Typowe porty dla urządzeń + for port in ports: + if self.is_port_open(ip, port): + with self.lock: # Użyj locka do synchronizacji + self.devices.append({"ip": ip, "port": port}) + print(f"Znaleziono otwarty port {port} na {ip}") + + def scan_network_for_devices(self): + self.devices.clear() # Wyczyść poprzednie wyniki + + # Ustawiam prefix automatycznie + def get_ip(): + # Biorę adres lokalnego interfejsu przy użyciu socketów + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.settimeout(0) + try: + s.connect(('8.8.8.8', 80)) # Łączymy się z dnsem googla żeby mieć ten adres którym komp się łączy z internetem a nie np adres wirtualnej karty sieciowej wirtualboxa albo adres pętli zwrotnej + ip = s.getsockname()[0] + except Exception: + ip = '127.0.0.1' # Jak się z niczym nie połączy ustawia na pętle zwrotną żeby nie wywaliło błędu i żeby nie zcrashowało programu + finally: + s.close() # Zamyka socket bo nie będzie już nam potrzebny + return ip + + # Ustawiam sobie zmienną na adres ip + ip_address = get_ip() + + # Dzielę go na 4 oktety + octets = ip_address.split(".") + + # Łącze oktety ze sobą ale tu już bez ostatniego + network_prefix = ".".join(octets[:-1]) + "." + + print("Rozpoczynam skanowanie sieci...") + + self.running = True # Rozpocznij skanowanie + threads = [] + + for i in range(1, 255): + if not self.running: + print("Skanowanie przerwane.") + break + ip = f"{network_prefix}{i}" + thread = threading.Thread(target=self.scan_ip, args=(ip,)) + threads.append(thread) + thread.start() # Uruchom skanowanie w nowym wątku + + for thread in threads: + thread.join() # Czekaj na zakończenie wszystkich wątków + + print("Skanowanie zakończone.") + +# Umożliwienie importu z tego pliku +if __name__ == "__main__": + scanner = NetworkScanner() + scanner.scan_network_for_devices() diff --git a/sendMessage.py b/sendMessage.py new file mode 100644 index 0000000..98882e5 --- /dev/null +++ b/sendMessage.py @@ -0,0 +1,10 @@ +import requests + +def send_message(message, server_ip, port): + url = f'http://{server_ip}:{port}/message' # Wstaw URL serwera + data = {'message': message} # Wiadomość jako dane JSON + response = requests.post(url, json=data) + if response.status_code == 200: + print("Wiadomość została pomyślnie wysłana!") + else: + print("Błąd podczas wysyłania wiadomości:", response.status_code) diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..ec2a834 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,191 @@ + + + + + + Skaner Sieci + + + +
+

Skaner Sieci

+ +
+

Akcje

+ + +
+ +
+ + +
+ +
+
+ + + + \ No newline at end of file