Учебники

Сетевой сканер Python

Сканирование портов может быть определено как метод наблюдения, который используется для определения местоположения открытых портов, доступных на конкретном хосте. Сетевой администратор, тестер проникновения или хакер могут использовать эту технику. Мы можем настроить сканер портов в соответствии с нашими требованиями, чтобы получить максимум информации от целевой системы.

Теперь рассмотрим информацию, которую мы можем получить после запуска сканирования портов –

  • Информация об открытых портах.

  • Информация об услугах, работающих на каждом порту.

  • Информация об ОС и MAC-адресе целевого хоста.

Информация об открытых портах.

Информация об услугах, работающих на каждом порту.

Информация об ОС и MAC-адресе целевого хоста.

Сканирование портов похоже на вора, который хочет войти в дом, проверяя каждую дверь и окно, чтобы увидеть, какие из них открыты. Как обсуждалось ранее, набор протоколов TCP / IP, используемый для связи через Интернет, состоит из двух протоколов, а именно TCP и UDP. Оба протокола имеют от 0 до 65535 портов. Поскольку всегда желательно закрыть ненужные порты нашей системы, следовательно, по сути, существует более 65000 дверей (портов) для блокировки. Эти 65535 портов можно разделить на следующие три диапазона:

  • Системные или общеизвестные порты: от 0 до 1023

  • Пользовательские или зарегистрированные порты: от 1024 до 49151

  • Динамические или частные порты: все> 49151

Системные или общеизвестные порты: от 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 Request хосту, и если этот хост работает, он вернет ICMP ECHO Reply.

Сканер портов с использованием ICMP

Вышеуказанный процесс отправки ICMP-запроса также называется ping scan, который предоставляется командой ping операционной системы.

Концепция Ping Sweep

На самом деле в том или ином смысле, пинг-размах также известен как пинг-размах. Единственное отличие состоит в том, что ping sweeping – это процедура для определения доступности нескольких машин в определенном диапазоне сети. Например, предположим, что мы хотим протестировать полный список IP-адресов, а затем с помощью ping-сканирования, т. Е. Команды ping операционной системы, будет очень много времени для сканирования IP-адресов по одному. Вот почему нам нужно использовать скрипт ping sweep. Ниже приведен скрипт на Python для поиска живых хостов с помощью ping sweep –

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-соединение, хост должен выполнить трехстороннее рукопожатие. Выполните следующие действия, чтобы выполнить действие –

Шаг 1 – Пакет с установленным флагом SYN

На этом этапе система, которая пытается инициировать соединение, запускается с пакета, для которого установлен флаг SYN.

Шаг 2 – Пакет с установленным флагом SYN-ACK

На этом этапе целевая система возвращает пакет с наборами флагов SYN и ACK.

Шаг 3 – Пакет с установленным флагом ACK

Наконец, инициирующая система вернет пакет в исходную целевую систему с установленным флагом ACK.

Тем не менее, здесь возникает вопрос: если мы можем выполнить сканирование портов с использованием метода эхо-запроса ICMP и ответа (сканер ping-sweep), то зачем нам сканирование TCP? Основная причина этого заключается в том, что если мы отключим функцию ответа ICMP ECHO или используем брандмауэр для пакетов ICMP, то сканер ping-развертки не будет работать, и нам потребуется сканирование 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-сканирования, разбивая его на части. Затем следует использовать функцию сканирования адреса, которая дополнительно использует сокет. Позже, он дает ответ о хосте и времени, необходимом для завершения процесса сканирования. Результат = с. Оператор 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 () позволяет одному потоку одновременно обращаться к переменной. Следовательно, двойной модификации не происходит.

Позже мы определим одну функцию нитей (), которая будет извлекать работу (порт) из рабочего цикла for. Затем вызывается метод portscan () для подключения к порту и вывода результата. Номер порта передается как параметр. После выполнения задачи вызывается метод q.task_done ().

Теперь после запуска вышеуказанного скрипта мы можем увидеть разницу в скорости сканирования от 50 до 500 портов. Это заняло всего 1.3589999675750732 секунды, что намного меньше 452.3990001678467, времени, которое занимает сканер сокетов портов для сканирования того же количества портов localhost.

Выход

Приведенный выше скрипт генерирует следующий вывод: