В августе этого года в ssh(1) (клиент OpenSSH) внесено изменение с поддержкой обфускации тайминга нажатий клавиш, то есть интервалов между временем нажатия клавиш на клавиатуре.
Спрашивается, почему разработчики озаботились такими нюансами информационной безопасности? Но причина есть. И на самом деле такие меры должны предпринять все программы, которые допускают ввод паролей в интернете (или вообще любого конфиденциального текста). В первую очередь, браузеры и мессенджеры.
Тайминг нажатий клавиш в консоли — известный вектор атаки ещё с 80-х. Грубо говоря, по паттерну появления звёздочек на экране можно примерно определить нажатые клавиши, что на порядок сокращает количество вариантов для брутфорса. Например, рядом стоящие клавиши обычно нажимаются медленнее, чем дальние, если человек работает двумя руками. Или быстрее, если пользователь обучен профессиональным методам набора (но таких меньшинство), см. диаграмму внизу.
Распределение времени между нажатиями клавиш v-o (слева) и v-b (справа), источник
Абсолютно для всех буквенных пар есть среднее время между нажатиями:
Гауссово распределение для 142 символьных пар английского языка (слева) и количество бит информации, которые мы можем извлечь, наблюдая каждый конкретный тайминг (справа)
Кроме того, в 90-е годы появились программы, которые с высокой точностью идентифицировали человека по таймингу нажатий, а сейчас это вообще тривиальная задача, тем более когда можно обучить ИИ-модель именно для этой задачи. Теперь любой школьник может взять нейросетку, скормить ей звуки нажатий целевых личностей, а потом легко распознать этого человека по таймингу буквенных пар, на какой бы клавиатуре он ни работал, и даже удалённо через интернет — просто наблюдая, как человек набирает текст на экране (или перехватывая пакеты его трафика).
То есть утечка информации через интервал между нажатиями несёт как минимум двойной риск:
- Деанонимизация пользователя.
- Распознавание пароля (помощь в брутфорсе).
Угроза конкретно для SSH была описана в далёком 2001 году в научной статье «Анализ тайминга нажатий клавиш и соответствующие атаки на SSH» авторства учёных из Калифорнийского университета в Беркли.
После этого в 2008 году разработчики развернули обсуждение той научной статьи. Дело в том, что в качестве примера она приводила протокол SSH1, который к моменту обсуждения уже вывели из использования. Некоторые из разработчиков предположили, что этот факт в значительной степени аннулирует слабое место. Но топикстартер парировал, что «нет никаких оснований полагать, что такие атаки будут невозможны против второй версии протокола там, где они работают против первой. Просто могут немного усложниться».
На самом деле очень много информации можно собрать, просто просматривая записи зашифрованных сессий, особенно если вы накопили достаточное их количество. В некоторых странах запись таких сессий поставлена на поток. В интерактивных сеансах связи есть достаточно чёткие закономерности, которые можно извлечь и использовать вместе с информацией о времени между нажатиями клавиш (то есть между соответствующими пакетами). Специфические скачки трафика позволяют понять, что пользователь набрал команду куда-то подключиться, а потом — пароль.
▍ Что конкретно внедрили в ssh(1)
Чтобы скрыть промежуток между нажатиями, ssh
в случае малого количества трафика отправляет его по сети с фиксированными интервалами 20 мс, а также добавляет «фальшивые» нажатия.
В документации появилась опция ObscureKeystrokeTiming:
Аргументом для опции может быть yes
, no
или спецификатор интервала в виде interval:milliseconds
(например, interval:80
). Несложно догадаться, что это фиксированный интервал времени между пакетами, как и было описано выше.
▍ Какой интервал выбрать?
Указано, что по умолчанию используется интервал между пакетами 20 мс. При этом чем меньше интервал, тем больше будет фальшивых пакетов и тем больше объём трафика. По идее, любое значение обладает одинаковой защитной функцией, кроме чрезмерно больших, когда наблюдатель сможет примерно угадать количество символов в пароле.
Скажем, чем отличается 20 мс от 50 мс, если вы всё равно не способны набирать пароль со скоростью больше десяти символов в секунду. А если у вас реально набор с такой скоростью, то при интервале 50 мс это даёт десять фальшивых и десять настоящих нажатий в секунду, что вполне эффективно скрывает длину пароля. И дополнительный паддинг (набивка) в конце даже не требуется.
Размер пакета с одним символом составляет 61 байт, так что при интервале 50 мс у нас генерируется 1,2 КБ трафика в секунду (4,19 МБ в час), а при 20 мс — 3 КБ в секунду (10,47 МБ в час). Возможно, для кого-то эта разница существенна. Если что, функцию можно отключить.
В общем, значение параметра можно устанавливать в зависимости от вашей скорости набора пароля. Учтите, что обычно скорость набора пароля гораздо выше, чем скорость набора обычного текста. Комбинация просто проникает в мышечную память и набивается на клавиатуре автоматически.
▍ Буфер и звёздочки
Некоторое время существовал богатый выбор приложений, принимающих пароли в небуферизованном режиме. То есть нажатия откликаются на экране эхом как звёздочки (*) по мере ввода пользователем, символ за символом. Эта простая функция выглядит красиво и даёт интерактивный фидбек… Но в таком случае происходит утечка данных не только о тайминге нажатий, но и о количестве клавиш, что соответствует длине пароля. Понятно, что это критически важная информация.
Поэтому большинство терминальных приложений сменили эту порочную практику и начали использовать буферизованный ввод/вывод для ввода пароля, что является важной функцией безопасности. В этом режиме компьютер ничего не отправляет по сети, пока пользователь не нажмёт Enter
. То есть предполагаемый злоумышленник MiTM видит только один пакет, независимо от того, что происходило на стороне клиента, сколько он клавиш нажимал и с каким таймингом, а из-за набивки «пустыми» символами пакет до стандартного размера злоумышленник не сможет определить длину пароля.
Ещё одна мера защиты: всегда выводить на экран одинаковое количество звёздочек, независимо от длины пароля, чтобы защитить экран от постороннего наблюдателя, который может узнать длину пароля. Это, конечно, смущает некоторых пользователей. Тогда практически теряется смысл этих звёздочек.
Буфер — очень важная функция безопасности, и он лучше обфускации, которую делает ssh
. Но в ssh
буфер по неким причинам не добавляют. Видимо, чтобы сохранить консистентный интерфейс. Иначе на картинке с сервера, которую вы видите, в поле пароля не будет отображаться вообще ничего, пока со стороны клиента набор пароля не завершится — и он не нажмёт кнопку Enter
(а потом какой смысл отображать что-то в этом поле, если мы уже увидим ответ сервера на введённый пароль?). Наверное, отсутствие звёздочек на экране — не самый логичный UI, ведь все мы привыкли, что ssh
точно транслирует события на экране, то есть с одной стороны всё выглядит точно так же, как с другой.
Поэтому пока не существует SSH-клиентов с поддержкой буфера.
Так что внедрение обфускации — это очень полезное и приятное событие, так что можно понять восторг пользователей в комментариях к этой новости в OpenBSD Journal. Там пишут, что это ещё один отличный пример «безопасности через обман» (security by trickery), по примеру «безопасность через неясность» (security by obscurity).
Кстати, даже при наличии буфера обфускация тоже важна для защиты содержимого, которое не может быть буферизовано, например, вывод из командной строки или редактора. То есть это в любом случае полезная функция, есть там буфер или нет.
▍ Вывод
Итак, известная с 80-х годов атака была конкретно описана против SSH в 2001 году, затем в 2008 году начали обсуждать возможность защиты от таких атак, а в 2023 году наконец-то вышел патч. Приятно, что разработчики SSH всё-таки умеют доводить дело до конца, пусть и спустя десятилетия.
Если отвлечься от брутфорса паролей, то распознавание литературной речи по времени между нажатиями клавиш вообще почти тривиальная задача, потому что энтропия связного текста крайне низкая: для английского это 0,6−1,3 бита на символ (Клод Шеннон «Прогнозирование и энтропия литературного английского»), а наша атака позволяет извлечь 1,2 бита на символ. То есть чисто по времени между пакетами в сети можно свободно распознавать весь текст пользователя, и никакое шифрование не поможет. Возможно, злоумышленники уже пользуются этой возможностью.
Отсюда вывод: не нужно набирать тексты в интернете. Лучше набрать сообщение в офлайновой программе (в «Блокноте», например), а в браузер/мессенджер вставить копипастом.
Автор:
ru_vds