Приветствую всех читателей!
Начну с того, а зачем изобретать велосипед, если их уже куча написана? Все мы понимаем, что велосипеды разные - чёрные, белые, красные )))
Когда я посмотрел примеры многопоточных сканеров, то понял, что большая часть из них имеет диапазон типа
Сканеры же, имеющий подобранные порты типа [21, 22, 23, 25, 38, 43, и т.д. были однопоточными, и работали весьма медленно...
В итоге я решил собрать новый велосипед из старых запчастей. Я хотел следующее:
1) Простой короткий код
2) Многопоточность
3) Указания нужных портов
Погнали:
Подключаем модуль threading для работы с потоками. Подключаем модуль socket для работы с сокетами (интерфейс для обеспечения обмена данными между процессами)
Вводим хост для сканирования
Создаём функцию сканирования портов, в которой создаём сокет, и выставляем таймаут
Продолжаем функцию, добавляем в блоке обработки исключений попытку приконнектиться к хосту, и в случае соединения, пишем что порт открыт. Открытое соединение закрываем. Ставим оператор-заглушку pass, в случае отсутствия соединения, ничего не выполняем.
Пишем список портов (можете добавить любые по желанию).
Ну вот и подошли к самому главному и интересному.
Делаем следующую запись, в которой мы запускаем перебор в цикле портов, создаём и запускаем потоки.
Рассмотрим подробнее, что происходит в этом блоке
Для этого я пошагово запустил скрипт в Pycharm. Хост взял наобум из сети, поэтому я его закрасил. Смотрим внимательнее на скрин - когда у нас шаг прошёл создание потока, появилась надпись, в которой мы видим инициализацию нового потока. Значит всё работает как надо.
На следующем шаге поток запустился.
Если в потоке поставленная задача выполнена, то он останавливается
Результат работы программы наглядно показывает, что потоки закрываются не в том порядке, что открывались. То есть они действительно работают параллельно. На каждый порт запускается отдельный поток. В процессе сканирования, количество потоков разное, взависимости от количества уже отработанных потоков.
На моём стареньком компе 2010 года и модемной связи от сотового оператора, скрипт выполняется за мгновенье.
Получилось всё как было задумано.
Исходный код с подробными комментариями
Начну с того, а зачем изобретать велосипед, если их уже куча написана? Все мы понимаем, что велосипеды разные - чёрные, белые, красные )))
Когда я посмотрел примеры многопоточных сканеров, то понял, что большая часть из них имеет диапазон типа
for port in range(1,100):
, значит перебор портов будет с 1 по 99. Если мне понадобится порт например 20000, то при попытке записи ]for port in range(1,20001):
сканер загнётся от переполнения памяти и невозможности создания нового потока.Сканеры же, имеющий подобранные порты типа [21, 22, 23, 25, 38, 43, и т.д. были однопоточными, и работали весьма медленно...
В итоге я решил собрать новый велосипед из старых запчастей. Я хотел следующее:
1) Простой короткий код
2) Многопоточность
3) Указания нужных портов
Погнали:
Подключаем модуль threading для работы с потоками. Подключаем модуль socket для работы с сокетами (интерфейс для обеспечения обмена данными между процессами)
Python:
import threading
import socket
Вводим хост для сканирования
Python:
print('-' * 35)
target = input('Enter host:\n\n')
print('-' * 35)
Создаём функцию сканирования портов, в которой создаём сокет, и выставляем таймаут
Python:
def portscan(port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(0.5)
Продолжаем функцию, добавляем в блоке обработки исключений попытку приконнектиться к хосту, и в случае соединения, пишем что порт открыт. Открытое соединение закрываем. Ставим оператор-заглушку pass, в случае отсутствия соединения, ничего не выполняем.
Python:
try:
connection = s.connect((target, port))
print('Port :', port, "is open.")
connection.close()
except:
pass
Пишем список портов (можете добавить любые по желанию).
Python:
ports = [21, 22, 23, 25, 38, 43, 80, 109, 110, 115, 118, 119, 143, # Список портов
194, 220, 443, 540, 585, 591, 1112, 1433, 1443, 3128, 3197,
3306, 4000, 4333, 5100, 5432, 6669, 8000, 8080, 9014, 9200]
Ну вот и подошли к самому главному и интересному.
Делаем следующую запись, в которой мы запускаем перебор в цикле портов, создаём и запускаем потоки.
Python:
for element in ports:
t = threading.Thread(target=portscan, kwargs={'port': element})
t.start()
input()
Рассмотрим подробнее, что происходит в этом блоке
Для этого я пошагово запустил скрипт в Pycharm. Хост взял наобум из сети, поэтому я его закрасил. Смотрим внимательнее на скрин - когда у нас шаг прошёл создание потока, появилась надпись, в которой мы видим инициализацию нового потока. Значит всё работает как надо.
На следующем шаге поток запустился.
Если в потоке поставленная задача выполнена, то он останавливается
Результат работы программы наглядно показывает, что потоки закрываются не в том порядке, что открывались. То есть они действительно работают параллельно. На каждый порт запускается отдельный поток. В процессе сканирования, количество потоков разное, взависимости от количества уже отработанных потоков.
На моём стареньком компе 2010 года и модемной связи от сотового оператора, скрипт выполняется за мгновенье.
Получилось всё как было задумано.
Исходный код с подробными комментариями
Python:
import threading # Подключаем модуль threading для работы с потоками
import socket # Подключаем модуль socket для работы с сокетами (интерфейс для обеспечения обмена данными между процессами)
print('-' * 35)
target = input('Enter host:\n\n') # Ввод хоста для сканирования
print('-' * 35)
def portscan(port): # Создаём функцию сканирования портов
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Создаём сокет
s.settimeout(0.5) # Выставляем таймаут
try:
connection = s.connect((target, port)) # Пытаемся приконнектиться к хосту
print('Port :', port, "is open.") # В случае соединения, пишем что порт открыт
connection.close() # Закрываем соединение
except:
pass # Оператор-заглушка, в случае отсутствия соединения, ничего не выполняем
ports = [21, 22, 23, 25, 38, 43, 80, 109, 110, 115, 118, 119, 143, # Список портов
194, 220, 443, 540, 585, 591, 1112, 1433, 1443, 3128, 3197,
3306, 4000, 4333, 5100, 5432, 6669, 8000, 8080, 9014, 9200]
for element in ports: # Перебор в цикле портов
t = threading.Thread(target=portscan, kwargs={'port': element}) # Создаём поток
t.start() # Запуск потока
input()