Статья [ Пишем Hack-Tools ] - многопоточный сканер портов

Приветствую всех читателей!

Начну с того, а зачем изобретать велосипед, если их уже куча написана? Все мы понимаем, что велосипеды разные - чёрные, белые, красные )))

Когда я посмотрел примеры многопоточных сканеров, то понял, что большая часть из них имеет диапазон типа for port in range(1,100): , значит перебор портов будет с 1 по 99. Если мне понадобится порт например 20000, то при попытке записи ]for port in range(1,20001): сканер загнётся от переполнения памяти и невозможности создания нового потока.

Сканеры же, имеющий подобранные порты типа [21, 22, 23, 25, 38, 43, и т.д. были однопоточными, и работали весьма медленно...

horsebike.jpg


В итоге я решил собрать новый велосипед из старых запчастей. Я хотел следующее:

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. Хост взял наобум из сети, поэтому я его закрасил. Смотрим внимательнее на скрин - когда у нас шаг прошёл создание потока, появилась надпись, в которой мы видим инициализацию нового потока. Значит всё работает как надо.

scan3.png


На следующем шаге поток запустился.

scan5.png


Если в потоке поставленная задача выполнена, то он останавливается

scan6.png


Результат работы программы наглядно показывает, что потоки закрываются не в том порядке, что открывались. То есть они действительно работают параллельно. На каждый порт запускается отдельный поток. В процессе сканирования, количество потоков разное, взависимости от количества уже отработанных потоков.

scan.png


На моём стареньком компе 2010 года и модемной связи от сотового оператора, скрипт выполняется за мгновенье.
Получилось всё как было задумано.

1457872e557e464.jpg


Исходный код с подробными комментариями

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()
 

Pernat1y

Well-known member
05.04.2018
1 443
135
BIT
0
знаю, но нужен был именно свой, для дальнейшего разбора и добавлением своих "фишек":)
Рекомендую
 
  • Нравится
Реакции: Lisenok

Lisenok

Green Team
02.04.2016
133
75
BIT
1
  • Нравится
Реакции: Pernat1y
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!