![](https://habrastorage.org/webt/32/86/rv/3286rvioxsavz1pt8i6sqrd0n4c.jpeg)
В конкурсе на самое популярное слово года призером IT-сферы наверняка бы стало слово «блокчейн». Несмотря на то, что идет
В этой статье мы рассмотрим атаку «Timejacking», основанную на уязвимости в обработке временных меток блоков в системе криптовалюты Bitcoin, и попытаемся объяснить, почему атака есть, а ее успешной реализации нет.
P.S. Тут будет много производных от слова «время». Очень много.
В двух словах
Впервые об атаке «Timejacking» написал Алекс Боверман. С его публикацией вы можете ознакомиться здесь. В чем суть: атака эксплуатирует уязвимости механизма проверки временных меток блоков и счётчика времени в Bitcoin. Злоумышленник манипулирует одним из счётчиков времени узла-жертвы и создает «отравленный» блок. Жертва этот блок отбросит, а остальная сеть успешно примет, и пожалуйста — у нас спровоцирован форк! Вся сеть использует цепочку блоков, строящуюся за «отравленным», а жертва считает валидной альтернативную цепочку с повторной тратой токенов (a.k.a. double-spending), в которой «отравленный» блок не фигурирует.
Атака проводится в два этапа. Чтобы было понятнее, поговорим о каждом из них отдельно.
Акт 1. Создание форка и изолирование жертвы
Злоумышленнику необходимо сгенерировать «яБЛОКо раздора» — тот самый «отравленный» блок, который проигнорирует жертва. Точно так же жертва отбросит и другие блоки, которые будут добавляться последовательно за «отравленным».
Как обмануть жертву и заставить отбросить корректный блок?
В заголовке каждого блока есть временная метка, которую узел проверяет при верификации. Это значение должно попадать в определенный диапазон, мы назовем его временным окном. Диапазон временного окна представлен на рисунке ниже:
![](https://habrastorage.org/webt/fs/mu/go/fsmugohtfy3uilmc0iyf2u7fp6a.jpeg)
У временного окна есть две границы:
- нижняя — tmin , она равна медиане временных меток 11 блоков, предшествующих верифицируемому блоку
- верхняя — равна значению времени сети t0 + 2 часа
Значение временной метки блока верифицируется не относительно системного времени узла, а относительно медианного времени его соседей — времени сети (a.k.a. network-adjusted time).
Как считается время сети:
- При установке нового соединения узлы обмениваются своим системным временем
- Каждый узел вычисляет отклонение собственного системного времени от системного времени каждого своего соседа
- Для вычисленных отклонений выбирается медианное значение
- Собственное системное время + медианное отклонение = время сети
Вот как выглядит пример вычисления времени сети:
![](https://habrastorage.org/webt/zw/dm/eu/zwdmeuayfjs0vslokmwolesugo4.jpeg)
Таким образом, злоумышленник может манипулировать значением времени сети жертвы, подключив к ней достаточное количество соседей, анонсирующих отстающее системное время. Уменьшается значение времени сети жертвы — уменьшается и верхняя граница диапазона допустимых значений временной метки верифицируемого блока. Но если отклонение времени соседа превышает 70 минут, то его время не будет учитываться при вычислении времени сети. Поэтому максимальное значение, на которое можно уменьшить время сети жертвы, равно 70 минутам.
![](https://habrastorage.org/webt/wn/yq/dk/wnyqdkckyddzalio-mzl9m-i7b0.jpeg)
Соответственно, наш «отравленный» блок — это блок, временная метка которого должна попадать во временное окно всех узлов сети, кроме жертвы. Только тогда вся сеть его успешно примет, а жертва, время сети которой модифицировано, не менее успешно отбросит. На рисунке ниже — временное окно жертвы vs временное окно остальных узлов.
![](https://habrastorage.org/webt/-k/jf/yc/-kjfycci5-wji1inohzrlxujg4e.jpeg)
Заметим, что, благодаря протоколу NTP, можно считать, что у большинства узлов системное время приблизительно одинаково, т.е., время сети каждого узла близко по значению к их системному времени.
В итоге, жертва изолируется от основной сети и считает некорректной основную цепочку блоков, которая будет строиться остальными узлами от «отравленного» блока. При этом другие блоки, услужливо генерируемые злоумышленником для альтернативной цепочки, жертва будет уверенно принимать.
![](https://habrastorage.org/webt/44/7z/6t/447z6t74qbyjwqnzzjhnxgog6le.jpeg)
Акт 2. Double-spending
На этом этапе злоумышленник генерирует альтернативную цепочку, в которую добавляет транзакцию, переводящую токены на кошелек жертвы. Блоки альтернативной цепочки отправляются жертве. На рисунке ниже — диапазон значений временной метки «отравленного» блока.
![](https://habrastorage.org/webt/gb/lx/ig/gblxigftue4b3qftdlldapqed40.jpeg)
Жертва примет эту цепочку, поскольку значение временных меток выбрано нарушителем из ее же временного окна, а остальные узлы ее справедливо проигнорируют — ведь они уже строят свою цепочку от «отравленного» блока, которая длиннее, чем альтернативная. В результате жертва считает, что получила токены, и отправляет товар. А основная сеть уверена, что токены не покидали кошелёк злоумышленника, и тот получает товар за «спасибо» — ведь большинство не может ошибаться. Финал, герой темной стороны торжествует!
Но не все так просто
Подводный камень № 1
В майнинг Bitcoin сегодня вовлечены огромные вычислительные мощности. Вероятность успешной генерации «отравленного» блока можно оценить по следующей формуле:
![](https://habrastorage.org/webt/dd/js/4u/ddjs4uoct9fzcc3lajt9qwz8_ca.png)
Сегодня общий хэшрейт сети Bitcoin приблизительно равен H=34∙1018 хэш/с. В таком случае, используя самое производительное устройство из этого списка, заявленный хэшрейт которого равен h=18∙1012 хэш/с, вероятность сгенерировать «отравленный» блок за 1 год (t=365∙24∙60) приблизительно равна 3%. А если взять из этой статистики относительно небольшой майнинг-пул, обладающий 0,3% от общего хэшрейта, то вероятность успешной генерации блока в течение 3 суток равна 73%.
Подводный камень № 2
С ходом времени сети жертвы временная метка «отравленного» блока, наконец, попадёт во временное окно жертвы. Тогда жертва сменит альтернативную цепочку на основную, поскольку на нее работает вся сеть и высота её будет больше. «Отравленный» блок попадёт во временное окно жертвы не более чем через 70 минут — это максимальное время, за которое необходимо завершить второй этап.
Для того, чтобы жертва приняла транзакцию с double-spending, блок с ней должен быть подтверждён ещё 6 блоками (для стандартного клиента). Генерировать подтверждающие блоки нарушителю придётся самостоятельно, и при этом надо уложиться в вышеупомянутые 70 минут. Боверман рассматривает ситуацию, когда злоумышленник владеет 10% мощности всей сети. В такой ситуации, для генерации 6 блоков понадобятся ~5,5 часа с вероятностью успеха 10%. Для 3,3 часа вероятность успеха падает до 1%, для 140 минут — 0,147%. Согласно этим оценкам, успешно сгенерировать 6 блоков за 70 минут — это из области фантастики.
Подводный камень № 3
Когда узел вычисляет время сети, он учитывает системное время только первых 200 соседей — потом медианное отклонение пересчитываться уже не будет. Значит, атаку необходимо реализовывать, пока количество уже подключенных к жертве соседей не превышает 99 — иначе время, анонсированное злоумышленником, не будет медианным. Такое количество соседей набежит примерно за 24 часа, а после жертву уже надо будет перезагружать — например, с помощью DoS.
Конец
В заключение можно сказать, что атака «Timejacking» — это очень хорошо, но в суровых реалиях Bitcoin становится неприменимой. А что насчет других систем, использующих блокчейн? Оставим этот вопрос для ваших дальнейших исследований!