Исследователи из американского Университета штата Мэриленд и китайского Университета Циньхуа опубликовали научную работу, в которой описан новый метод атаки по сторонним каналам (side-channel attack), использующий ранее неизвестную аппаратную уязвимость в процессорах Intel. Хотя уязвимость предположительно затрагивает и самые свежие процессоры этой компании, наиболее эффективно она позволяет атаковать более старые модели, подверженные также и уязвимости Meltdown. Данное исследование, возможно, представляло бы чисто научный интерес, если бы не одна особенность: кража секретной информации в ходе атаки происходит через изменение данных в регистре флагов.
Можно попроще?
Активное исследование аппаратных процессорных уязвимостей, связанных со спекулятивным выполнением инструкций, ведется уже больше пяти лет. Максимально упрощая, все предложенные атаки можно описать следующим образом: мы каким-то образом заставляем процессор считать данные, к которым не имеем доступа. Представьте себе такой теоретический сценарий. У программы атакующего нет доступа к ключу шифрования, с помощью которого защищены важные данные. Если дать процессору инструкцию «считай ключ шифрования по такому-то адресу», она не будет выполнена. На помощь приходит технология спекулятивного выполнения инструкций: одна из важных функций современных процессоров, используемая почти три десятилетия. Для ускорения работы процессор не ждет окончания выполнения одной инструкции, а параллельно выполняет следующую.
Если первая инструкция проверяет права доступа к секретной информации, она, по идее, не должна позволить выполнять следующую команду на считывание этой информации. Но уже поздно: следующая инструкция выполнена спекулятивно. Важный момент: мы все еще не имеем доступа к этим данным, но процессор уже имеет. В известных уязвимостях типа Spectre данные временно загружаются в кэш-память процессора, считать информацию из которой просто так нельзя. Но можно делать это по сторонним каналам. Например: много раз выполнять какую-то инструкцию, время обработки которой меняется в зависимости от данных в кэш-памяти. Если повторить такую операцию много (тысяч!) раз, можно восстановить данные, просто наблюдая за тем, как быстро или медленно выполняется какая-то вроде бы безобидная команда.
Мы понимаем, что это так называемое «простое» описание уже звучит достаточно сложно. Новая работа еще сложнее: авторы решили не тратить время на подробное описание атаки. В целом она вся показана на этой схеме:
Давайте попробуем разобраться. EFLAGS — это регистр флагов в процессоре Intel, который отслеживает состояние работы процессора. В нем может сохраняться результат вычислений, в частности если он равен нулю (так называемый Zero Flag или ZF). Дальше происходит магия: представьте, что ваш коллега загадал число от 1 до 10. Вы по очереди называете ему все числа от 1 до 10, но он не хочет делиться с вами правильным ответом и на каждый из вариантов говорит слово «хризантема». Но когда вы называете правильное число, он говорит «хризантема» чуть позже, чем в других случаях!
Примерно так и происходит в процессе новой атаки: мы проводим множество вычислений с секретными данными. Все эти вычисления выполняются спекулятивно. Результат записывается в флаг ZF (равен или не равен нулю). Мы даже не можем напрямую узнать состояние этого флага. Но затем мы выполняем, в общем, довольно бесполезную команду из состава инструкций JCC (а именно команду JZ: «переход, если результат равен нулю»), которая выполняется чуть медленнее, если мы угадали! Именно это промедление, задержка с ответом, которую можно измерить, и является уязвимостью.
Пока не проблема
Самое интересное, что сама по себе эта атака не работает. Чтобы обеспечить саму возможность спекулятивного выполнения нужных нам инструкций, требуется проэксплуатировать еще одну уязвимость. В данной работе используется уязвимость Meltdown, обнаруженная в 2018 году. Она как раз и позволяет обращаться к информации, доступ к которой запрещен. В результате на старых процессорах, подверженных этой уязвимости (использовались Intel Core i7 шестого и седьмого поколения), секретные данные удалось прочитать со 100% надежностью. В процессоре десятого поколения эксперимент не удался, хотя и там присутствует вот эта задержка при выполнении определенной инструкции из набора JCC.
На самом деле даже более универсальные атаки типа Spectre, похищающие информацию из кэш-памяти процессора, в реальности имеют достаточно узкое применение. Но в их случае по крайней мере было очевидно, что с ними надо что-то делать: вероятность проведения сложной атаки с похищением действительно важных данных была ненулевая. В случае с новой работой мы имеем дело скорее с идеей, которая если и сработает, то на старых процессорах Intel.
Но сама новость важная: появился новый механизм извлечения данных по стороннему каналу — с использованием состояния регистра флагов. Не исключено, что в будущем такой подход в комбинации с какой-то другой уязвимостью станет актуальным и для новых процессоров. А может, проблему закроют еще до появления новой атаки: зависимость времени выполнения инструкции от данных — достаточно серьезная проблема. В криптографии существует отдельная дисциплина, защищающая алгоритмы шифрования от атак по времени.
В любом случае, исследование особенностей работы современных процессоров продолжается. Атаки на аппаратные уязвимости сложны как для понимания, так и для практического исполнения. Пока не была найдена уязвимость, которую можно было бы эксплуатировать массово. Но людям, обеспечивающим безопасность в организациях, работающим с максимально конфиденциальными данными, имеет смысл учитывать подобные атаки и как минимум отслеживать их эволюцию.