"Сканер Портов" на Python. 2 часть.
BLACK CODEПишем свой аналог NMAP на Python. Часть 2.

Предупреждение! Я не профессионал, так что в теории могу ошибиться!
Всем привет! Это канал BLACK CODE. Сегодня мы продолжим серию статьей по созданию своего сканера портов на Python.
Прошлая часть
В первой части мы написали простейший сканер портов на Python, который может сканировать только по одному порту.
Полный код программы из прошлой части - Полный код программы.
Сегодня мы же напишем уже более функциональный сканер портов, в котором будет выбор между сканированием одного порта и сканирования одних из самых популярных портов.
Новых библиотек и функций не будет, из нового - цикл "for", который перебирает порты из списка портов.
Пишем программу
Про функцию сканирования одного порта писать не буду, так как так практически нет ничего нового, только появилась передача значений в функцию.
Давайте лучше разберём функцию со сканированием всех портов.
В новой программе появился словарь с портами, он выглядит так :
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',
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'}
В нём хранятся порты и ключи портов, в которых хранится обозначения портов.
Например:
80-ый порт - это порт HTTP, он открыт у всех сайтов.
Функция сканирования всех портов
Начнем, сначала создаём саму функцию, она будет называться "all_scanning" и в неё будет передаваться только адрес сайта.
def all_scanning(host): # функцию сканирования всех портов из словаря
pass # заглушка для функции
Теперь наполним саму функцию:
Начнём с цикла, который будет перебирать все порты из словаря:
for port in ports: # перебор всех портов из словаря "ports"
pass # заглушка
Объясняю, мы перебираем каждый порт из словаря и записываем в переменную port, эта переменная будет меняться, пока не закончится цикл.
Теперь наполним цикл:
for port in ports: # перебор всех портов из словаря "ports"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # создание сокета
s.settimeout(0.5) # Задаём таймаут для сканирования
try:
connection = s.connect((host, port)) # пробуем подключиться к одному из портов
except socket.error: # если ошибка, то просто пропускаем и ничего не выводим
pass # заглушка
else: # если ошибки не было, то...
print('[+] Port: ' + str(port) + '(' + ports[port] + ') - OPENED') # сообщаем о том, что порт открыт
Всё содержание цикла - это практически тоже самое, что мы писали в первой части, так что не вижу смысла всё это разбирать, в крайнем случае есть комментарии на каждую строку.
Главная функция
Теперь разберём главную функцию. Её задача в том, чтобы пользователь выбрал режим и ввёл данные, а потом она просто перенаправляет программу на нужную функцию.
Код главной функции:
def main(): # главная функция
print('''
1 - Single Port Scanning
2 - All Ports Scanning
''') # Вывод о выборе режима
mode = input('[*] Enter Mode (1/2): ') # пользователю выбирает режим
if mode == '1': # если пользователь ввёл 1, то...
host = input('[*] Enter Host: ') # запрос цели у пользователя
port = int(input('[*] Enter Port: ')) # запрос порта у пользователя
single_scanning(host, port) # запуск функции сканирования одного порта
elif mode == '2': # если пользователь ввёл 2, то...
host = input('[*] Enter Host: ') # запрос цели у пользователя
all_scanning(host) # запуск функции сканирования всех портов
else: # если пользователь ввёл что-то другое, то...
print('[!] ERROR: Wrong Mode!')
exit(1) # выход из программы
Вот и всё, программа не сильно отличается по коду от прошлой, но по функционалу отличается довольно сильно.
Полный код программы
# -*- coding: utf-8 -*-
import socket # импорт библиотеки socket
# Слоаврь с портами и их обозначениями
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',
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('[*] Scanning...')
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] + ')' + ' - OPENED') # пробуем вытянуть порт из словаря(такого порта может не быть в словаре)
except: # если ошибка, то...
print('[+] Port: ' + str(port) + ' - OPENED') # Выводим, что порт открыт, не берём значение из словаря
def all_scanning(host): # сканирование всех портов в словаре
print('[*] Scanning...')
for port in ports: # перебор всех портов из словаря "ports"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # создание сокета
s.settimeout(0.5) # Задаём таймаут для сканирования
try:
connection = s.connect((host, port)) # пробуем подключиться к одному из портов
except socket.error: # если ошибка, то просто пропускаем и ничего не выводим
pass
else: # если ошибки не было, то...
print('[+] Port: ' + str(port) + '(' + ports[port] + ') - OPENED') # сообщаем о том, что порт открыт
def main(): # главная функция
print('''
1 - Single Port Scanning
2 - All Ports Scanning
''') # Вывод о выборе режима
mode = input('[*] Enter Mode (1/2): ') # пользователю выбирает режим
if mode == '1': # если пользователь ввёл 1, то...
host = input('[*] Enter Host: ') # запрос цели у пользователя
port = int(input('[*] Enter Port: ')) # запрос порта у пользователя
single_scanning(host, port) # запуск функции сканирования одного порта
elif mode == '2': # если пользователь ввёл 2, то...
host = input('[*] Enter Host: ') # запрос цели у пользователя
all_scanning(host) # запуск функции сканирования всех портов
else: # если пользователь ввёл что-то другое, то...
print('[!] ERROR: Wrong Mode!')
exit(1) # выход из программы
main() # Вызов главной функции
Полный код программы(кликабельно)
Тестируем программу
Чтобы запустить программу на Python через Терминал(cmd) нужно переместиться в папку с программой при помощи "cd". (cd папка).
А после вводите python3 названиефайла.py(если не сработает, то пишите просто python).
Чтобы запустить python файл в IDE (Wing 101) нужно просто нажать на кнопку "Run".
Давайте протестируем программу, которую мы сегодня написали:

Видим, что всё отлично работает! Тестирование проводил на специальном сайте, который используется для тестирование Nmap: scanme.nmap.org
На этом всё, в этой части мы написали уже неплохой сканер портов, который уже можно использовать, в следующих статьях продолжим усовершенствовать нашу программу. Подписывайтесь на BLACK CODE, чтобы не пропустить следующие статьи.
Надеюсь, что вы узнали что-то новое для себя.

Канал: BLACK CODE
Админ: @blackcode_admin