Python: Создание сканера портов
В этом уроке я проведу вас через процесс создания простого сканера портов с помощью Python.
https://t.me/addlist/8vDUwYRGujRmZjFi – папка с телеграм каналами для Python разработчика.
Для начала мы должны создать новый файл.
mousepad scanner.py&
Затем нам нужно включить shebang в начало нашего файла.
#!/bin/python3
Кроме того, нам нужно импортировать несколько модулей.
import sys
import socket
from datetime import datetime
Далее нам необходимо установить количество системных аргументов.
if len(sys.argv) == 2:
target = socket.gethostbyname(sys.argv[1])
else:
print("Invalid amount of arguments")
print("Syntax: python3 scanner.py <ip>")
Давайте попробуем разложить все по полочкам.
if len(sys.argv) == 2:
Мы используем метод len и указываем “sys.argv”. “argv” , которые обозначают количество аргументов, которые мы передаем, в данном случае это два. На диаграмме ниже наглядно показано, что это за аргументы, имяя скрипта и ip адрес для сканера.
Если мы передадим Python больше или меньше двух аргументов, произойдет ошибка.
print("Invalid amount of arguments")
print("Syntax: python3 scanner.py <ip>")
target = socket.gethostbyname(sys.argv[1])
Здесь мы передаем в target “socket.gethostbyname(sys.argv[1])” – функция gethostbyname преобразует имя хоста в соответствующий ему адрес IPv4. Например, если у нас есть имя хоста в DNS под названием “Punisher”, Python определит его и преобразует в IPv4-адрес.
Для данного проекта рекомендуется избегать использования имен хостов и вместо этого использовать IPv4-адреса.
Теперь встроим таймер в наш скрипт.
print("-" * 50)
print("Scanning target: "+target)
print("Time started: "+str(datetime.now()))
print("-" * 50)
Давайте проверим функциональность нашего таймер, используя в качестве цели случайный IP-адрес.
Теперь у нас есть функциональный таймер.
Давайте перейдем к созданию функциональности для нашего скрипта. Мы начнем с добавления кода .
try:
for port in range(50,85):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.setdefaulttimeout(1)
result = s.connect_ex((target,port))
if result == 0:
print(f"Port {port} is open")
s.close()
Давайте пройдемся по этому разделу, чтобы лучше понять, что происходит.
for port in range(50,85):
В настоящее время мы выполняем цикл for, который итерирует диапазон портов от 50 до 85.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Мы создали переменную для сбора IPv4-адреса (AF_INET), а также собираем порты, к которым хотим подключиться (SOCK_STREAM).
socket.setdefaulttimeout(1)
Добавив эту строку кода, Python будет ждать одну секунду, прежде чем перейти к следующему порту.
result = s.connect_ex((target,port))
if result == 0:
print(f"Port {port} is open")
s.close()
Эта строка кода указывает, что мы собираемся подключиться к цели и порту, оба из которых являются переменными, которые мы уже определили.
Функция s.connect_ex служит индикатором ошибок: если порт открыт, она вернет ноль, а закрытый порт вернет единицу. Поэтому, если результат равен нулю, программа выведет “Порт {port} открыт”. Если результат какой-либо другой, программа закроет соединение с помощью s.close() и перейдет к следующему порту в цикле. Этот процесс продолжается до тех пор, пока не будут просканированы все порты.
Однако перед запуском программы необходимо учесть некоторые исключения.
except KeyboardInterrupt:
Это означает, что мы можем вручную остановить программу в любое время, нажав Ctrl+C. Когда мы используем KeyboardInterrupt, наша программа выведет сообщение.
print("\nExiting program")
sys.exit()
Это приведет к завершению работы программы.
Следующее исключение, которое мы рассмотрим, это:
except socket.gaierror:
Это исключение возникает, когда имя хоста не может быть разрешено. Если мы введем недопустимое имя хоста или IP-адрес, программе будет дано указание напечатать сообщение об ошибке.
print("Hostname could not be resolved.")
После вывода сообщения об ошибке, связанной с недопустимым именем хоста или IP-адресом, программа завершит работу.
sys.exit()
Последнее исключение, которое следует рассмотреть:
except socket.error
Если программе не удается подключиться к серверу, она выводит сообщение.
print("could not connect to server")
После печати сообщения об ошибке при неудачном соединении программа завершит работу.
Чтобы запустить этот код, нам сначала понадобится IP-адрес нашего локального маршрутизатора. Мы можем найти его, открыв терминал и набрав “ip r”, а затем найдя IP-адрес, указанный в разделе “default”.
После запуска сценария мы должны увидеть, что порт 53 и порт 80 открыты.
Отличные новости! Сканер успешно определил два открытых порта на нашем маршрутизаторе. Если у вас возникнут какие-либо проблемы, обратитесь к скриншоту всего сценария ниже.
Поздравляем! Вы успешно создали свой собственный сканер портов.
До следующего раза! 😉