"Сканер Портов" на Python. 3 часть.

"Сканер Портов" на Python. 3 часть.

BLACK CODE

Пишем свой аналог NMAP на Python. Часть 3.

Предупреждение! Я не профессионал, так что в теории могу ошибиться!

Всем привет! Это канал BLACK CODE. Сегодня мы продолжим серию статьей по созданию своего сканера портов на Python.

Прошлая часть

В прошлой части мы написали уже сканер портов, который уже можно использовать. Но у него был один большой недостаток - маленькая скорость, потому что он работает всего в один поток. А сегодня мы усовершенствуем его, чтобы он стал многопоточным и быстрым.

Полный код программы из прошлой части - Полный код программы.


Сегодня мы разберём новую библиотеку - threading. Она находится в стандартном паке библиотек, так что устанавливать её отдельно не придётся.

Думаю, вы уже догадались, что модель threading используется для достижения многопоточности.

Модуль threading

Импортирование threading:

import threading

Теперь давайте напишем простую функцию:

def main():
print('BLACK CODE')

Всё, для примера мы будем использовать эту функцию.

Теперь создадим 10 потоков, которые будут вызывать эту функцию:
for i in range(10): # цикл, который будет "прокручиваться" 10 раз
t = threading.Thread(target=main) # создание потока
t.start() # запуск потока

Вот и всё, мы создали простой пример многопоточности, 10 потоков на функцию main, которая выводит "BLACK CODE".

Переписываем функцию

В этот раз придётся практически полностью переписать функцию "all_scanning".

Сейчас она принимает 2 аргумента - host, port, а также в ней больше нет цикла, теперь она выглядит так:

def all_scanning(host, port): # сканирование всех портов в словаре

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # создание сокета

s.settimeout(0.5) # Ставим таймаут для сканирования

try: # пробуем сделать следующее...

connection = s.connect((host, port)) # пробуем подключиться к порту

print('[+] ' + ' Port: ' + str(port) + '(' + ports[port] + ') - OPEN') # если все прошло успешно, то вывод о том, что порт открыт

except socket.error: # если ошибка socket'а, то...

pass # заглушка(ничего не делаем)

Теперь она стала выглядеть очень проста, сейчас она очень схожа с функцией "single_scanning". Кстати, "single_scanning" мы никак не трогаем.

Теперь придётся немного переделать главную функцию

Главная функция

Переделаем мы только блок, где идет обработка ответа, если пользователь выбрал "2"(сканирование всех портов).

Вот как теперь выглядит этот блок:

elif mode == '2': # если пользователь ввёл 2, то...

host = input('\n[*] Enter Host: ') # запрос цели у пользователя

print('\n[*] Scanning...\n')


for port in ports: # перебор всех портов из словаря 

thread = threading.Thread(target=all_scanning, kwargs={'host': host, 'port': port}) # создание потока, цель которого - функция "all_scanning", с аргументами - host, port

thread.start() # запускем поток

Как раз тут и применяется многопоточность, мы запускаем кол-во потоков, которое равно кол-ву портов. Из-за этой многопоточности программа будет работать в разы быстрее. Если хотите прочувствовать эту скорость, то сначала запустите сканирование всех портов на программе из 2-ого урока, а потом из текущего, уверяю, что вы почувствуете большую разницу, эта разница будет особенно заметна, когда мы возьмём куда больше портов(а это в следующих часьях).

Полный код программы

# -*- coding: utf-8 -*-



import socket # импорт библиотеки socket

import threading # импорт библиотеки для многопоточности



# Слоаврь с портами и их обозначениями

ports = {

  20: 'FTP-DATA', 21: 'FTP', 22: 'SSH', 23: 'Telnet', 25: 'SMTP', 42: 'NAMESERVER',

  43: 'WHOIS', 53: 'DOMAIN (DNS)', 67: 'BOOTPS', 69: 'TFTP', 80: 'HTTP', 110: 'POP3', 139: 'NETBIOS-SSN', 443: 'TCP - HTTPS',

  1080: 'SOCKS', 3128: 'HTTP used by Web caches', 3389: 'RAdmin', 5900: 'Virtual Network Computing (VNC)',

  8000: 'iRDMI', 8008: 'HTTP_ALT', 8080: 'WEBCACHE', 8888: 'NewsEDGE server'}



def single_scanning(host, port): # функцию сканирования одного порта

print('\n[*] Scanning...\n')


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # создание сокета

s.settimeout(0.5) # Ставим таймаут для сканирования

try: # пробуем сделать следующее

connection = s.connect((host, port)) # пробуем подключиться к порту

except socket.error: # если ошибка, то...

print('[-] Port: ' + str(port) + ' - CLOSED') # вывод о том, что порт закрыт

else: # если ошибки не было, то...

try: # пробем получить ключ из словаря

print('[+] Port: ' + str(port) + '(' + ports[port] + ')' + ' - OPEN') # пробуем вытянуть порт из словаря(такого порта может не быть в словаре)

except: # если ошибка, то...

print('[+] Port: ' + str(port) + ' - OPEN') # Выводим, что порт открыт, не берём значение из словаря



def all_scanning(host, port): # сканирование всех портов в словаре

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # создание сокета

s.settimeout(0.5) # Ставим таймаут для сканирования

try: # пробуем сделать следующее...

connection = s.connect((host, port)) # пробуем подключиться к порту

print('[+] ' + ' Port: ' + str(port) + '(' + ports[port] + ') - OPEN') # если все прошло успешно, то вывод о том, что порт открыт

except socket.error: # если ошибка socket'а, то...

pass # заглушка(ничего не делаем)


def main(): # главная функция

print('''

1 - Single Port Scanning

2 - All Ports Scanning

''') # Вывод о выборе режима

mode = input('\n[*] Enter Mode (1/2): ') # пользователю выбирает режим


if mode == '1': # если пользователь ввёл 1, то...

host = input('\n[*] Enter Host: ') # запрос цели у пользователя

port = int(input('[*] Enter Port: ')) # запрос порта у пользователя

single_scanning(host, port) # запуск функции сканирования одного порта

elif mode == '2': # если пользователь ввёл 2, то...

host = input('\n[*] Enter Host: ') # запрос цели у пользователя

print('\n[*] Scanning...\n')


for port in ports: # перебор всех портов из словаря 

thread = threading.Thread(target=all_scanning, kwargs={'host': host, 'port': port}) # создание потока, цель которого - функция "all_scanning", с аргументами - host, port

thread.start() # запускем поток

else: # если пользователь ввёл что-то другое, то...

print('[!] ERROR: Wrong Mode!')

exit(1) # выход из программы



main() # Вызов главной функции


Полный код программы(кликабельно)

Тестируем программу

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

Тестируем нашу программу

Всё работает! Разница по результату от прошлого незаметна, но по скорости очень ощутима.



На этом всё, в этой части мы написали уже хороший сканер портов, который довольно быстрый. В следующих статьях продолжим усовершенствовать нашу программу. Подписывайтесь на BLACK CODE, чтобы не пропустить следующие статьи.

Надеюсь, что вы узнали что-то новое для себя.

Вся информация предоставлена исключительно с целью ознакомления. Мы не несём ответственности за ваши действия.


Канал: BLACK CODE

Админ: @blackcode_admin

Report Page