Как-то оплачивая что-то в магазине я задумался над вопросом:
Какой шанс, что бит в памяти терминала оплаты не превратится из нуля в единицу? Скажем, была цена на экране $1, а стала $32769, когда информацию отправили в банк?💸
Сразу уточню - речь не про баги, а про физический уровень. Память - это устройство, которое может выйти из строя: перегрев, изнашивание, удары. Может ли пресловутый космический луч в момент оплаты изменить транзистор, где хранилась моя цена?
Примерно все программы, которые я видел в своей жизни, доверяют своей памяти и рассчитывают, что если записали значение, то потом оттуда его и прочитают.
Могут ли данные просто так поменяться? Оказывается, это происходит не так уж и редко 😰
Поэтому production grade сервера используют более дорогую память с ECC - дополнительным слоем, который может заметить изменение и скорректировать его (или завершить программу аварийно, если ошибка некорректируемая).
В 2015 Facebook опубликовал исследование на своем масштабе - за месяц около 2% их серверов сталкивались с корректируемыми ошибками, а 0.03% с некорректируемыми (обычно шли под замену) - вероятно тысячи машин ежемесячно.
А вот обычная пользовательская электроника (вроде телефонов и ноутбуков) до сих пор часто идет с более дешевой памятью без полноценной ECC 👨💻
Интересный подход из 2011, доказывающий, что ошибки происходят регулярно - Bitsquatting. Ресерчер зарегистрировал десятки доменов популярных сайтов с отличием в 1 бите (например Aeazon вместо Amazon). Внезапно туда стали стучаться устройства со всего мира. Дальше был проведен анализ запросов и попытка доказать, что многие из них не были человеческими опечатками, а были от машин со случайными изменениями в памяти.
Логичный следующий вопрос - можно ли повредить память специально и использовать в своих целях? 💻
В 2015 Google Project Zero показали, что обычная программа на Linux может получить полный доступ к системе на протестированных ноутбуках.
Идея в том, чтобы долбить память на чтение и запись в определенном паттерне - отсюда и название Rowhammer.
Иногда электрический заряд будет "протекать" в соседние ряды транзисторов и менять биты в других адресах. Если в этих адресах окажется служебная информация операционной системы, то этим можно воспользоваться!
Кому интересны технические детали - краткое описание под спойлером. Можете попробовать подумать сами в какие данные мы целимся. Как ни странно, для понимания идеи хватит базовых знаний устройства операционных систем.
(Для простоты считаем, что умеем флипать случайный бит в памяти всей машины. И делать это много раз)
Подсказка: какие метаданные о процессе сами могут занимать довольно много памяти?
Идея:
1) Пусть мы поменяли бит в памяти, где была Page Table Entry одной из страниц нашего процесса и её физический адрес стал указывать на... Page Table нашего же процесса
2) Теперь можно перенаправлять наши страницы на любые физические адреса в системе, ещё и с write-доступом!
3) Можно просканить kernel память, найти там данные про наш pid и прописать себе root-a
Понятно, что вероятность повредить бит, чтобы сложились обстоятельства (1) мала (её умеют хитрыми способами увеличивать) Если научиться быстро делать много попыток, то шансы становятся практичными (нужны минуты/часы, а не столетия)
Наверное было 10 лет назад и уже неактуально?
Производители памяти от такого офигели и в последующих чипах фиксили уязвимости, но ресерчеры находили новые способы. Свежий результат под названием Phoenix был опубликован совсем недавно - в 2025 году.
В ETH Zurich нашли способ получать root на машинах с моделями SK Hynix DDR5 памяти буквально за минуты - эта память выпускалась в 2021-2024 и активно сегодня используются.
Есть ли мораль у этой истории?
Шанс получить неверное списание с карты я так и не узнал, но и ладно🙂 Интересно снова видеть как любые абстракции в программировании строятся на реальных физических вещах!
Ну и +1 причина не запускать что попало у себя на компьютере...
https://en.wikipedia.org/wiki/Row_hammer