[PART 0] Address Poisoning - курица, несущая золотые яйца? Устройство "русской рулетки" изнутри. Голая математика и цифры, ничего более.

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0

Спойлер: soundcloud
https://soundcloud.com/beachbunnymusic%2Fsets%2Fbeach-bunny-on-audiotree-live

Написано - chiefchain
Для - XSS.is


1. Введение
1.1 О чём статья?

Здрасте, поговорим про "Отравление адресов", тема для обсуждения достаточно интересная. Много кто относится к ней отрицательно, считая людей, продающих ПО под эту атaку, идиотами, ведь зачем продавать курицу, несущую золотые яйца? Этот вопрос, кажется мне, является одним из главных, которые еще можно рассмотреть внутри этой темы. Немного проанализируем, посчитаем, рассмотрим уже успешные истории и немного посчитаем цифры, прибегая к индукции, а после ответим на вопрос: есть ли всё же тут некая закономерность, или же это все же просто вопрос удачи, времени, настойчивости? Cтатья будет разбита на две части, материала много, не хочется перегружать ни себя, ни вас. Напишем один из модулей в этой статье, а во второй, думаю завершим вместе со всеми модулями. При желании, можно будет все модули собрать в одно целое, основываясь на статью и немного своих возможностей.
1.2 И что это значит "Отравить адрес"?
Этот термин появился еще в далеком 2023 году, именно тогда такие случае обрели популярность в криптосообществе. В основе атаки лежит самая обыкновенная человеческая невнимательность, чтоб денюжки пришли не тому человеку, которому он отправил, а нам. Поспособствовало продвижению этой темы возможность генерировать vanity-адреса, их особенность в том, что можно задать параметры для "генерации" адреса, то есть можно написать задать наличие "hiha" в адресе и будут искаться такие, а после вы получите приваткей для доступа к нему . Воспользоваться этим можно даже в интернете, достаточно забить в поиск любого поисковика: "vanity address generator". Один из сайтов позволяет это сделать прям на нём с указанными вами параметрами. Примера ради, сгенерировал вот такой вот интересный адрес: "1EVGT9GsqsK3L1x1Mu7DigaitsGUzDSxss", в конце видим "xss", и так можно сделать кучу похожих адресов на какой нибудь другой.
1734037109439.png


Но проблема заключается в другом, в том как различные кошельки отображают переводы. Большинство показывает n-ое кол-во первых символов и последних, именно таким образом мы и пытаемся обмануть пользователя, чтоб он запутался, и как говорилось ранее по невнимательности своей, отправил деньги не туда уже куда надо.
1734037204845.png


Сгенерировать можно абсолютно любой адрес, но тут уже начинает назревать вопрос, а какое количество мощности мы готовы выделить на эту генерацию? В частом случае повторяют первые три символа и два последних, но это конечно исключительно желание того, кто будет генерировать такие адреса. Есть у таких адресов конечно и свои слабости, они легче поддаются взлому, связано это с тем, что процесс генерации не является случайным, ведь мы отталкиваемся от определенных шаблонов, которые задаем. Так же возможны уязвимости и в самих таких инструментах, а именно не очень безопасные псевдогенераторы чисел, в таком случае можно зареверсить алгоритм, и уже доставать нужные приват ключи, которые были созданы с него. Такая история произошла в сентябре 2022 года, когда всё случилось именно так как описано предложением ранее, софт этот назывался "Profanity". По этому, если вы не хотите потерять свои кровные, не понтуйтесь лишний раз, не используйте vanity-адреса в целях хранения средств, высока вероятность остаться без штанов.

1.3 Как это работает со стороны технического устройства?
У‎ нас‎ есть‎ кошелек-донор,‎ на‎ котором‎ лежит‎ n-ая‎ сумма‎ денежек,‎ которую‎ мы‎ будем‎ раскидывать‎ по‎ жертвам.‎ Так‎ же‎ есть‎ функция,‎ которая‎ используется‎ для‎ мониторинга‎ транзакций‎ в‎ выбранной‎ нами‎ сети.‎ Мы‎ отслеживаем‎ транзакции,‎ анализируем‎ суммы‎ и‎ ,‎ если‎ они‎ соответствуют‎ нашим‎ критериям,‎ которые‎ так‎ же‎ настраиваются,‎ чтоб‎ понять‎ "ожидаемый"‎ выхлоп,‎ а‎ так‎ же‎ не‎ стоит‎ забывать,‎ что‎ нам‎ надо‎ избегать‎ "горячих"-кошельков‎ бирж,‎ эти‎ данные‎ мы‎ можем‎ собрать‎ в‎ интернете,‎ чтоб‎ быть‎ уверенным‎ на‎ 100%,‎ либо‎ же‎ можем‎ выставить‎ верхний‎ потолок‎ по‎ количеству‎ денег‎ на‎ кошельке,‎ ибо‎ денег‎ на‎ таких‎ кошельках‎ выше‎ крыши,‎ и‎ только‎ в‎ случае‎ всех‎ успешных‎ проверок,‎ начинаем‎ процесс‎ генерации‎ похожего‎ адреса‎ как‎ говорил‎ ранее.‎ После‎ генерации‎ адреса‎ мы‎ отправляем‎ небольшую‎ сумму‎ с‎ кошелька-донора‎ на‎ этот‎ сгенерированный‎ адрес,‎ а‎ после‎ уже‎ перечисляем‎ нашей‎ жертве.‎ И‎ тут‎ уже‎ начинается‎ лишь‎ вопрос‎ времени,‎ ведь‎ для‎ нас‎ лучшим‎ исходом‎ будет,‎ когда‎ жертва,‎ отправляя‎ средства‎ в‎ будущем,‎ может‎ случайно‎ скопировать‎ один‎ из‎ этих‎ самых‎ "отравленных"‎ адресов‎ вместо‎ правильного,‎ тем‎ самым‎ переводя‎ деньги‎ нам.‎ Выглядит‎ это‎ все‎ банально‎ просто‎ и‎ по‎ дурацки,‎ но‎ что‎ если‎ мы‎ посмотрим‎ на‎ сумму‎ ущерба‎ от‎ таких‎ атак?‎ Дело‎ в‎ том,‎ что‎ зачастую‎ именно‎ самые‎ тупые‎ и‎ примитивные‎ "схемы"‎ работают‎ в‎ безумных‎ объемах.
1734041352692.png


1.4 Главная уязвимость компьютера - нахождение человека за ним. Сколько было потеряно на таких атаках?
Человеческий фактор является "вечной" уязвимостью в области кибербезопасности. В 2024 году на отравлении адресов, согласно данным, опубликованным в отчетах Cyvers и Chainalysis, было потеряно $71,475,000 на основе 361 случая. Однако это лишь заявленные случаи, и реальные потери, я более чем уверен, значительно выше, так как не все жертвы сообщают об этом, ведь еще опозорятся какой они глупенькие, да, и шансы вернуть деньги крайне малы. Если сравнить эту цифру с 2023 годом, то рост потерь увеличился более чем на 100%. Примером одной из крупных атак можно рассказать о случае на $68,000,000, история вышла с неплохим концом, если вкратце то один из "китов" отправил денюжки на "отравленный" адрес, но всё обошлось, видимо, наш "коллега" испугался, ведь цифры до ужаса огромные, я не знаю кто бы не испугался, и смог бы спокойно спать после такого, ведь такие случаи, зачастую просто с рук ни кому не сходят. По итогу он вернул все деньги спустя 66 дней, но при этом всё равно смог заработать на этом $1,500,00 за счёт того, что биток вырос.
1734041732865.png


1.5 Посчитаем с точки зрения математической индукции? Да, какая к черту точная наука в социологии. Нутро "русской" рулетки.
Никогда, никогда не думайте, что можно связать атаку, основанную на социологии, с математикой. Ведь это больше похоже на бред сумасшедшего, ведь человек сам по себе - существо непредсказуемое, и никогда не знаешь, что может произойти спустя даже минуту. Математика бессильна в этом случае, ведь человеческий фактор - это не формула. Люди не живут строго по алгоритму, как предполагает математика. Внимательность, эмоции и даже усталость играют ключевую роль. Математика не учитывает такие переменные. Непредсказуемость поведения - ключевая проблема. Математическая индукция предполагает, что жертва будет действовать предсказуемо, но в реальности поведение людей может быть абсолютно непредсказуемым. Атака с отравлением адресов - это не точная наука, а игра с человеческим фактором, где успех зависит от лишь от удачи. Отбросьте все мысли, что это курица, несущая золотые яйца. На самом деле, это лишь вопрос вашего везения, бюджета и настойчивости.
1734041519576.png


1.6 Почему так важен выбор сети, с которой будем работать?
Вы хотите попробовать работать на долгую или же хотите слить весь бюджет сразу, а? У нас выполняется аж два перевода, первый с донора на сгенерированный, а следующий уже с него на жертву. Комиссия тоже денег стоит, хоть и отправлять мы будем абсолютные копейки, ради того, чтоб наш перевод просто закрепился в истории у человека, а комиссия уже это вопрос.. Давайте возьмем примера ради три самых популярных сети: TRC-20, ERC-20, и BTC. Давайте возьмём так, мы берем только голые сравнения, все будут на равных, я не буду брать в учет, что в TRC-20 можно экономить на комиссии за счёт энергии, вырабатываемой в стейкинге TRX, ведь тогда это уже будет не объективное сравнение. Так же стоит понимать, что желательно выполнять все эти махинации в рамках атаки как можно скорее, чтоб закрепиться у человека в памяти, пока он еще хорошо помнит о транзакции. Всего возьмем условно 100 транзакций, посчитаем сколько в "теории" можно потратить (комиссия всегда крайне волатильна, по этому теория взята в ковычки). Данные по комиссиям я буду брать простым запросом в google: average fee in {сеть} for 2023. По TRC-20 у нас вышло за одну транзакцию 14 тронов, по словам интернета, формула у нас будет везде единая, банально умножаем комиссию на два, предварительно переведя её в доллары, из-за двух переводов, и добавляем $0.01.
1734043100227.png


Бамц, получаем бешенные цифры на 100 жертв, аж 829$ спущенных с высокой вероятностью в пустоту, или же все таки выиграете джекпот.
1734043345425.png



Проделываем такие же действия для оставшихся сетей и получаем такое вот.

В ERC-20 выходят такие показатели:

  • Комиссия за транзакцию: $1.088.
  • Двойная комиссия (два перевода): 1.088 ∗ 2 = 2.176.
  • Дополнительные 0.01: 0.01 + 2.176 = 2.186
Итого за 100 транзакций: 2.186 * 100 = 218.6

В BTC же практически на уровне TRC-20

  • Комиссия за транзакцию: $3.939.
  • Двойная комиссия (два перевода): 3.939 ∗ 2 = 7.878.
  • Дополнительные 0.01: 0.01 + 7.878 = 7.888.
Итого за 100 транзакций: 7.888 * 100 = 788.8
Выглядит всё это, конечно, грустно. Комиссии конские, но что уж поделать.


2. Практическая часть.
2.1 А на чём пишем? Как пишем? Что пишем? Какая структура?

По итогу мы остаёмся работать с сетью BTC, так как самые большие заработки судя по ресерчам от крипто-детективов именно здесь. Писать будем на Python. Нужны будут модули, которые: будут отвечать за отправку денежек на нужные адреса, парсинг транзакций и их проверку по нашим критериям, сбор оптимальной комиссии на актуальное время, логирование в телеграм о работе софта, и конечно само генерирование наших vanity-адресов с последующим сохранение приват кеев от них, с целью потом гонять в чекере и проверять капнула ли денюжка. Я не любитель подавать всё готовое на блюдечке, к сожалению. По этому всё будет разбито по модулям a.k.a отдельным функциям, при желании вы сможете собрать это всё целиком и полностью.
2.2 Собираем транзакции в BTC. Выстраиваем критерии. API или нода?
Бадабумц, критерии. Помним в первую очередь, что нам нужна фильтрация от определенной n-ой суммы. Так же в связи с реализацией биткоина таким образом, что при переводе кому-либо, можно еще сказать, что ты переводишь и все оставшиеся деньги, но это сдача, и по этому из выходов транзакции, надо будет удалять адреса с которых идёт вход. По основным критериям всё, а теперь вопрос, как это можно реализовать? В голове у меня возникла мысль, и она мне кажется верной, по этому использовать мы будем её. Цель заключается в том, чтоб получать высоту последнего подтвержденного блока, после получаем его хэш, который записываем, чтоб потом мы не гоняли его по второму разу, а затем уже запрашиваем у блока все транзакции, которые есть в нём. Там же у нас появляется еще одна потребность в переводе всего в вечнозеленые тугрики, ради удобства и комфорта, нежели считать в сатоши, по этому нам постоянно нужен будет актуальный курс, чтоб наверняка не ошибиться, в конце, как всё перевели, сравниваем с нашими критериями, и делаем вывод, подходит ли нам такой вариант, аля нет? Для более удобной передачи между модулями, будем использовать JSON-формат, идеально вписывается вот сюда. Данные, которые нам придется сохранять со 100% вероятность это: все кошельки входов и выходов, сумма в сатоши и USD. Некоторую мета-информацию я всё равно оставляю, ибо есть некая привычка комиссию считать в сатоши, а битки в деньгах) Теперь задаемся вопросом, а что использовать, готовое API или ставить ноду? Честно, выбор каждого, но здесь я выбрал работу через API, ибо ставить ноду это ёмко по ресурсам, и ставится она тоже достаточно долго из-за синхронизации блоков, начиная с далекого 2009. API будем пользоваться от https://mempool.space/ как минимум бесплатное и мне понравилась скорость его работы, остановился на этом. Все хардовые переменные засунем отдельно в конфиг для удобства. Ссылки у нас это нужные эндпоинты, min_amount - минимальная сумма, чтоб парс записал транзакцию, а timeout - это количество секунд, раз в которое будем проверять новые блоки.
1734053274929.png


Насчёт кода, я пытался расписать всё максимально понятно, без бредовых названий, разбил на много функций, чтоб легче было понимать (хотя, мне это кажется только ухудшением). Если у вас всё же есть какие-то вопросы, задавайте в тему, я отвечу на них.
Спойлер: code
from curl_cffi import requests
import json
import time
from dotenv import load_dotenv
import os
load_dotenv('config.env')
latest_block_url = os.getenv("latest_block_url")
txids_of_block_url = os.getenv("txids_of_block_url")
info_of_tx_url = os.getenv("info_of_tx_url")
price_url = os.getenv("price_url")
hash_block_url = os.getenv("hash_block_url")
min_amount = int(os.getenv("min_amount", 10000000))
timeout = int(os.getenv("timeout", 1200))
processed_blocks = set()
def get_last_block():
try:
response = requests.get(latest_block_url)
return response.json()
except:
return None
def get_block_hash(block_height):
try:
url = hash_block_url.format(block_height=block_height)
response = requests.get(url)
return response.text
except:
return None
def get_block_txids(block_hash):
try:
url = txids_of_block_url.format(block_hash=block_hash)
response = requests.get(url)
return response.json()
except:
return []
def get_transaction_details(txid):
try:
url = info_of_tx_url.format(txid=txid)
response = requests.get(url)
return response.json()
except:
return None
def get_btc_to_usd_rate():
try:
response = requests.get(price_url)
data = response.json()
return data['USD']
except:
return None
def satoshi_to_btc(satoshi):
return satoshi / 100_000_000
def convert_satoshi_to_usd(satoshi):
btc_amount = satoshi_to_btc(satoshi)
usd_rate = get_btc_to_usd_rate()
if usd_rate:
usd_amount = btc_amount * usd_rate
return usd_amount
return None
def format_transaction_details(tx_details):
inputs = []
input_addresses = set()
total_input = 0
for vin in tx_details['vin']:
try:
if 'prevout' in vin:
input_address = vin['prevout']['scriptpubkey_address']
input_amount = vin['prevout']['value']
inputs.append({
"address": input_address,
"amount_satoshi": input_amount,
"amount_btc": satoshi_to_btc(input_amount)
})
input_addresses.add(input_address)
total_input += input_amount
except:
pass
outputs = []
total_output = 0
for vout in tx_details['vout']:
try:
output_address = vout['scriptpubkey_address']
output_amount = vout['value']
if output_address not in input_addresses:
outputs.append({
"address": output_address,
"amount_satoshi": output_amount,
"amount_btc": satoshi_to_btc(output_amount)
})
total_output += output_amount
except:
pass
fee = tx_details['fee']
fee_btc = satoshi_to_btc(fee)
fee_usd = convert_satoshi_to_usd(fee)
total_output_btc = satoshi_to_btc(total_output)
total_output_usd = convert_satoshi_to_usd(total_output)
return {
"txid": tx_details['txid'],
"inputs": inputs,
"outputs": outputs,
"fee_satoshi": fee,
"fee_btc": fee_btc,
"fee_usd": fee_usd,
"total_output_satoshi": total_output,
"total_output_btc": total_output_btc,
"total_output_usd": total_output_usd
}
def monitor_blocks():
while True:
latest_block_height = get_last_block()
if not latest_block_height:
time.sleep(timeout)
continue
block_hash = get_block_hash(latest_block_height)
if not block_hash:
time.sleep(timeout)
continue
if block_hash not in processed_blocks:
txids = get_block_txids(block_hash)
if txids:
for txid in txids:
tx_details = get_transaction_details(txid)
if tx_details:
formatted_tx = format_transaction_details(tx_details)
if formatted_tx['total_output_usd'] >= min_amount:
print(json.dumps(formatted_tx, indent=4))
processed_blocks.add(block_hash)
time.sleep(timeout)
if __name__ == "__main__":
monitor_blocks()

В итоге мы получаем JSON, вот такого вида, в котором у нас есть вся нужная информация, и еще чуть меты.
1734053841029.png


Спойлер: json
{
"txid": "29684f8b8770bedddc6925bba05e8a1621db4f483f9ffd980ea1eb8d51160fda",
"inputs": [
{
"address": "bc1qryhgpmfv03qjhhp2dj8nw8g4ewg08jzmgy3cyx",
"amount_satoshi": 3848594014,
"amount_btc": 38.48594014
}
],
"outputs": [
{
"address": "bc1q6fzgrattkmulesuqgdmm9dgqrsclwfhmpr5grk",
"amount_satoshi": 247032218,
"amount_btc": 2.47032218
}
],
"fee_satoshi": 5640,
"fee_usd": 5.64846,
"total_output_satoshi": 247032218,
"total_output_btc": 2.47032218,
"total_output_usd": 247402.76632700002
}‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎
‎‎‎‎‎‎‎‎‎‎‎‎

3. Заключение
Закончили с первой частью, честно, немного запарился, пиша эту статью. Но материала много, и материал интересен (как мне кажется). Впринципе, разобрали, и выяснили, что нет тут никакой курицы, несущей золотых яиц. Математика тут тоже неподвластна. Всё зависит сугубо от вашего везения, бюджета, и настойчивости. Нельзя сказать, что это золотые горы, хоть мы и посмотрели на статистику, которая с 2023 года только увеличивается, и увеличивается. Во второй статьей, допишем оставшиеся модули, доберем еще слегка теории при работе с генерацией адресов. Перепроверим всё, и закончим) Надеюсь, было не скучно, вторая часть предполагаемо выйдет на выходных. За прочтение спасибо, было бы интересно услышать отклик, по поводу написания, объяснения материала и так далее =)
 
Сверху Снизу