Сетевой сканер Python
Сканирование портов можно определить как метод наблюдения, который используется для определения открытых портов, доступных на определенном хосте. Этот прием может использовать сетевой администратор, тестер проникновения или хакер. Мы можем настроить сканер портов в соответствии с нашими требованиями, чтобы получить максимум информации от целевой системы.
Теперь рассмотрим информацию, которую мы можем получить после запуска сканирования порта -
Информация об открытых портах.
Информация о сервисах, запущенных на каждом порту.
Информация об ОС и MAC-адресе целевого хоста.
Сканирование портов похоже на вора, который хочет проникнуть в дом, проверяя каждую дверь и окно, чтобы увидеть, какие из них открыты. Как обсуждалось ранее, набор протоколов TCP / IP, используемый для связи через Интернет, состоит из двух протоколов, а именно TCP и UDP. Оба протокола имеют от 0 до 65 535 портов. Поскольку всегда рекомендуется закрывать ненужные порты нашей системы, по сути, необходимо заблокировать более 65000 дверей (портов). Эти 65535 портов можно разделить на следующие три диапазона:
Системные или общеизвестные порты: от 0 до 1023
Пользовательские или зарегистрированные порты: от 1024 до 49151
Динамические или частные порты: все> 49151
Сканер портов с использованием сокета
В нашей предыдущей главе мы обсуждали, что такое сокет. Теперь мы создадим простой сканер портов, используя сокет. Ниже приведен сценарий Python для сканера портов с использованием сокета.
from socket import *
import time
startTime = time.time()
if __name__ == '__main__':
target = input('Enter the host to be scanned: ')
t_IP = gethostbyname(target)
print ('Starting scan on host: ', t_IP)
for i in range(50, 500):
s = socket(AF_INET, SOCK_STREAM)
conn = s.connect_ex((t_IP, i))
if(conn == 0) :
print ('Port %d: OPEN' % (i,))
s.close()
print('Time taken:', time.time() - startTime)
Когда мы запускаем приведенный выше сценарий, он запрашивает имя хоста. Вы можете указать любое имя хоста, например имя любого веб-сайта, но будьте осторожны, потому что сканирование портов может рассматриваться или истолковываться как преступление. Мы никогда не должны запускать сканер портов для любого веб-сайта или IP-адреса без явного письменного разрешения владельца сервера или компьютера, на который вы нацеливаетесь. Сканирование портов похоже на посещение чьего-то дома и проверки его дверей и окон. Поэтому желательно использовать сканер портов на локальном хосте или на собственном сайте (если есть).
Вывод
Приведенный выше сценарий генерирует следующий вывод -
Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
Port 135: OPEN
Port 445: OPEN
Time taken: 452.3990001678467
Выходные данные показывают, что в диапазоне от 50 до 500 (как указано в сценарии) этот сканер портов обнаружил два открытых порта - порт 135 и 445. Мы можем изменить этот диапазон и проверить наличие других портов.
Сканер портов с использованием ICMP (живые хосты в сети)
ICMP - это не сканирование портов, но он используется для проверки связи с удаленным хостом, чтобы проверить, работает ли он. Это сканирование полезно, когда нам нужно проверить несколько активных хостов в сети. Он включает отправку ICMP ECHO-запроса на хост, и если этот хост активен, он вернет ICMP ECHO-ответ.
Вышеупомянутый процесс отправки запроса ICMP также называется сканированием ping, которое обеспечивается командой ping операционной системы.
Концепция Ping Sweep
На самом деле, в том или ином смысле, проверка связи также известна как проверка связи. Единственное отличие состоит в том, что проверка связи - это процедура определения доступности нескольких машин в определенном сетевом диапазоне. Например, предположим, что мы хотим протестировать полный список IP-адресов, а затем, используя сканирование ping, то есть команду ping операционной системы, сканирование IP-адресов один за другим займет очень много времени. Вот почему нам нужно использовать скрипт ping sweep. Ниже приведен сценарий Python для поиска живых хостов с помощью проверки связи.
import os
import platform
from datetime import datetime
net = input("Enter the Network Address: ")
net1= net.split('.')
a = '.'
net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
oper = platform.system()
if (oper == "Windows"):
ping1 = "ping -n 1 "
elif (oper == "Linux"):
ping1 = "ping -c 1 "
else :
ping1 = "ping -c 1 "
t1 = datetime.now()
print ("Scanning in Progress:")
for ip in range(st1,en1):
addr = net2 + str(ip)
comm = ping1 + addr
response = os.popen(comm)
for line in response.readlines():
if(line.count("TTL")):
break
if (line.count("TTL")):
print (addr, "--> Live")
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: ",total)
Приведенный выше сценарий состоит из трех частей. Сначала он выбирает диапазон IP-адресов для сканирования методом ping-развертки, разделяя его на части. Затем следует использование функции, которая выберет команду для проверки связи в соответствии с операционной системой, и, наконец, она даст ответ о хосте и времени, затраченном на завершение процесса сканирования.
Вывод
Приведенный выше сценарий генерирует следующий вывод -
Enter the Network Address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 100
Scanning in Progress:
Scanning completed in: 0:00:02.711155
Приведенный выше вывод не показывает активных портов, потому что брандмауэр включен и параметры входящего ICMP также отключены. После изменения этих настроек мы можем получить список активных портов в диапазоне от 1 до 100, представленный на выходе.
Сканер портов, использующий сканирование TCP
Чтобы установить TCP-соединение, хост должен выполнить трехстороннее рукопожатие. Выполните следующие действия, чтобы выполнить действие -
Step 1 − Packet with SYN flag set
На этом этапе система, которая пытается инициировать соединение, запускается с пакета, для которого установлен флаг SYN.
Step 2 − Packet with SYN-ACK flag set
На этом этапе целевая система возвращает пакет с установленными флагами SYN и ACK.
Step 3 − Packet with ACK flag set
Наконец, инициирующая система вернет пакет исходной целевой системе с установленным флагом ACK.
Тем не менее, возникает вопрос, можем ли мы выполнять сканирование портов с использованием метода эхо-запроса и ответа ICMP (сканер ping sweep), тогда зачем нам сканирование TCP? Основная причина этого заключается в том, что, предположим, если мы отключим функцию ответа ICMP ECHO или используем брандмауэр для пакетов ICMP, тогда сканер ping sweep не будет работать, и нам понадобится сканирование TCP.
import socket
from datetime import datetime
net = input("Enter the IP address: ")
net1 = net.split('.')
a = '.'
net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
t1 = datetime.now()
def scan(addr):
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket.setdefaulttimeout(1)
result = s.connect_ex((addr,135))
if result == 0:
return 1
else :
return 0
def run1():
for ip in range(st1,en1):
addr = net2 + str(ip)
if (scan(addr)):
print (addr , "is live")
run1()
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: " , total)
Приведенный выше сценарий состоит из трех частей. Он выбирает диапазон IP-адресов для сканирования методом ping-развертки, разделяя его на части. Затем следует использование функции сканирования адреса, которая в дальнейшем использует сокет. Позже он дает ответ о хосте и времени, затраченном на завершение процесса сканирования. Результат = s. Оператор connect_ex ((addr, 135)) возвращает индикатор ошибки. Индикатор ошибки равен 0, если операция завершилась успешно, в противном случае это значение переменной errno. Здесь мы использовали порт 135; этот сканер работает в системе Windows. Другой порт, который здесь будет работать, - это 445 (Microsoft-DSActive Directory), и он обычно открыт.
Вывод
Приведенный выше сценарий генерирует следующий вывод -
Enter the IP address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 10
127.0.0.1 is live
127.0.0.2 is live
127.0.0.3 is live
127.0.0.4 is live
127.0.0.5 is live
127.0.0.6 is live
127.0.0.7 is live
127.0.0.8 is live
127.0.0.9 is live
127.0.0.10 is live
Scanning completed in: 0:00:00.230025
Сканер портов с резьбой для повышения эффективности
Как мы видели в приведенных выше случаях, сканирование портов может быть очень медленным. Например, вы можете увидеть время, затраченное на сканирование портов от 50 до 500, при использовании сканера портов сокетов, составляет 452.3990001678467. Чтобы повысить скорость, мы можем использовать потоки. Ниже приведен пример сканера портов с использованием потоковой передачи.
import socket
import time
import threading
from queue import Queue
socket.setdefaulttimeout(0.25)
print_lock = threading.Lock()
target = input('Enter the host to be scanned: ')
t_IP = socket.gethostbyname(target)
print ('Starting scan on host: ', t_IP)
def portscan(port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
con = s.connect((t_IP, port))
with print_lock:
print(port, 'is open')
con.close()
except:
pass
def threader():
while True:
worker = q.get()
portscan(worker)
q.task_done()
q = Queue()
startTime = time.time()
for x in range(100):
t = threading.Thread(target = threader)
t.daemon = True
t.start()
for worker in range(1, 500):
q.put(worker)
q.join()
print('Time taken:', time.time() - startTime)
В приведенном выше скрипте нам нужно импортировать модуль потоковой передачи, который встроен в пакет Python. Мы используем концепцию блокировки потока,thread_lock = threading.Lock()чтобы избежать множественных изменений за раз. По сути, threading.Lock () позволяет одному потоку получать доступ к переменной за раз. Следовательно, двойной модификации не происходит.
Позже мы определим одну функцию threadader (), которая будет получать работу (порт) от рабочего цикла for. Затем вызывается метод portscan () для подключения к порту и печати результата. Номер порта передается как параметр. После выполнения задачи вызывается метод q.task_done ().
Теперь, после запуска приведенного выше сценария, мы можем увидеть разницу в скорости сканирования от 50 до 500 портов. Это заняло всего 1,3589999675750732 секунды, что намного меньше 452,3990001678467, времени, затраченного сканером портов сокета для сканирования того же количества портов localhost.
Вывод
Приведенный выше сценарий генерирует следующий вывод -
Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
135 is open
445 is open
Time taken: 1.3589999675750732