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

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

BLACK CODE

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

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

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


Прошлый части:

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

В прошлой части мы в разы ускорили программу, а добились мы этого многопоточностью библиотеки threading.

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

До завершения программы осталось уже совсем немного. И я решил посвятить эту часть визуальному оформлению. Сегодня мы будем использовать 2 новых библиотеки - colorama и os.

С помощью colorama мы добьёмся цветного текста в программе, а с помощью системной библиотеки os сделаем кое-что другое.

Colorama и os

Colorama

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

Открываете терминал/cmd и пишем следующее:

Windows

pip install colorama

Linux/Mac OS

pip3 install colorama

Ждём установки и двигаемся дальше.

Давайте разберём только лишь тот функционал библиотеки, который мы будем сегодня использовать.

Импортируем 3 модуля в программу:

from colorama import Fore, Style, init

И за одно импортируем name из os:

from os import name

Она нам пригодится в модуле colorama

Так вот, Fore служит для того, чтобы делать цветной текст, вам нужно добавить название цвета на англ. к 'Fore.', чтобы получить какой-либо цвет, пример: Fore.YELLOW, а вот как это должно примерно выглядеть в питоне:

print(Fore.GREEN + 'Hello') # Вывод зелёным цетом надпись "Hello"

В библиотеке colorama существует всего 8 цветом, вот их список:

Цвета colorama(из документации)

Но! Просто так на windows colorama не работает, поэтому мы еще импортируем функцию init из colorama и за одно name из os:

from colorama import Fore, init # импорт Fore и init из colorama

from os import name # импорт name из os


if name == 'nt': # Если система - Windows, то...

init() # Выполнение функции init

print(Fore.CYAN + 'Hello') # Вывод цветного текста

Объясняю, мы проверяем систему, если система называется nt(это windows), то выполняем функцию init(), без которой colorama на windows работать не будет

Вот так всё просто.

Теперь разбёрем еще и Style из colorama

Его мы будем использовать только для сброса цветов, при выходе из программы:

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

from colorama import Fore, Style, init

from os import name


if name == 'nt': # если windows, то выполняем функцию init

init()

print(Fore.RED + 'BLACK CODE') # Вывод текста красным цветом

print(Style.RESET_ALL) # Сброс цветов


Если кто-то не понял, то это нужно, чтобы цвет не оставался при выходе программы.

Os

Библиотека os является стандартной в python, так что устанавливать её не придётся.

Перейдем сразу к модулям, который мы будем использовать - name, system.

Думаю вы уже поняли, что name - выдает кодовое название вашей системы.

Вот, что он может выдавать -  'posix', 'nt', 'mac', 'os2', 'ce', 'java'.

from os import name

print(name)


У меня выдаёт 'posix'(Mac OS).

Так, name разобрали, теперь очередь за system. system выполняет системные команды(cls, clear, ls, echo и тд...)

К примеру, у нас есть файл hello.txt, в котором есть одна строчка - "Hello from BLACK CODE'

И мы хотим прочитать содержание этого файла в программе(следующий пример не работает на windows, так как там не команды 'cat')

cat - выводит содержание файла


from os import system

system('cat hello.txt')


Всё, теперь в нашей программе произойдет вывод содержания 'hello.txt', а то есть - Hello from BLACK CODE.

С библиотеками разобрались, теперь приступим к написанию нашей новой функции.

Функция clear

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

Надеюсь, что вы знаете команду, которая очищает экран вашей операционной системы. Если нет, то вот, держите:

clear - Команда для unix-like систем(linux, mac os и тд)

cls - Команда очистка для Windows

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

Давайте напишем данную функцию:


def clear(): # создание функции очитски экрана

if name == 'nt': # Если у пользователя windows, то...

system('cls') # Выполнение системной команды 'cls' для очистки экрана

else: # В противном случае...

system('clear') # Выполнение системной команды 'clear' для очистки экрана 


Всё очень просто, мы смотрим систему, а потом выполняем нужную команду.

В принципе, на этом новаторство закончилось, далее я просто подставлял цвета под каждый print и input, а в конце их сбросил, еще вставил 2 раза функцию clear, но не вижу смысла это подробно рассматривать, там везде есть комментарии.

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

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



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

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

from colorama import Fore, Style, init # импорт модулей Fore, Init и Style из библиотеки colorama

from os import name, system # импорт модуля name для определения системы, импорт system для выполнения системных команд



if name == 'nt': # Если у пользователя windows, то...

init() # Выполнение функции init из библиотеки colorama



def clear(): # создание функции очитски экрана

if name == 'nt': # Если у пользователя windows, то...

system('cls') # Выполнение системной команды 'cls' для очистки экрана

else: # В противном случае...

system('clear') # Выполнение системной команды 'clear' для очистки экрана 



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

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): # функцию сканирования одного порта

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

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

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

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

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

print(Fore.RED + '[-] Port: ' + str(port) + ' - CLOSED') # вывод о том, что порт закрыт (красный цвет)

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

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

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

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

print(Fore.GREEN + '[+] 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(Fore.GREEN + '[+] ' + ' Port: ' + str(port) + '(' + ports[port] + ') - OPEN') # если все прошло успешно, то вывод о том, что порт открыт (зеленый цвет)

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

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


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

clear() # Вызов функции очистки экрана

print(Fore.GREEN + '''

|-------------------|

|  PortScanner  |

|          |

|          |

|  BLACK CODE  |

|-------------------|

''') # Вывод зеленым цветом приветсвенное сообщение

print(Fore.YELLOW + '''

1 - Single Port Scanning

2 - All Ports Scanning

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

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

clear() # Вызов функции очистки экрана

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

host = input(Fore.YELLOW + '[*] Enter Host: ') # запрос цели у пользователя(желтый цвет)

port = int(input(Fore.YELLOW + '\n[*] Enter Port: ')) # запрос порта у пользователя(желтый цвет)

print(Fore.YELLOW + '\n[*] Scanning...\n') # (желтый цвет)

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

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

host = input(Fore.YELLOW + '[*] Enter Host: ') # запрос цели у пользователя(жетый цввет)

print(Fore.YELLOW + '\n[*] Scanning...') # (желтый цвет)

print(Fore.GREEN + '\n[*] Open Ports:\n') # (зеленый цвет)

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

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

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

thread.join() # подсоединени потока к основному(чтобы программа дальше работала)

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

print(Fore.RED + '[!] ERROR: Wrong Mode!') # Вывод сообщения о ошибке (красный цвет)

print(Style.RESET_ALL) # Сброс цветов

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

print(Style.RESET_ALL) # Сброс цветов



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



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

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

Функционал остался почти тот же, изменилось лишь оформление:

Первый режим:

Выбираю сканирование одного порта
Сканирование одного порта 1
Сканирование одного порта 2

Второй режим:

Выбираю сканирование всех портов в словаре
Сканирование всех портов в словаре

Неправильный режим:

Выбираю режим, которого нет
Ошибк

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

python3 port_scanner4.py -t google.com -p 20

И так далее, но я вообще их не люблю, мне почему-то комфортнее запускать программы так.



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

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

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


Канал: BLACK CODE

Литература Хакера: @archivehacker

Админ: @blackcode_admin

Report Page