...

пятница, 20 декабря 2019 г.

Взлом с помощью Юникода (на примере GitHub)

Юникод исключительно сложен. Мало кто знает все хитрости: от невидимых символов и контрольных знаков до суррогатных пар и комбинированных эмодзи (когда при сложении двух знаков получается третий). Стандарт включает 216 кодовых позиций в 17-ти плоскостях. По сути, изучение Юникода можно сравнить с изучением отдельного языка программирования.

Неудивительно, что веб-разработчики упускают из вида некоторые нюансы. С другой стороны, злоумышленники могут использовать особенности Юникода в своих целях, что и делают.

Специалист по безопасности Джон Грейси продемонстрировал на примере GitHub баг проверки адреса электронной почты для восстановления забытого пароля. Подобные баги можно встретить и на других сайтах.
Джон Грейси объясняет, что такое «коллизия трансляции знаков», когда два разных знака после конвертации транслируются в один и тот же знак.

В данном случае он использовал турецкий символ 'ı' ('i' без точки), который транслируется в латинскую 'i', так что почтовый адрес John@Gıthub.com после обработки превращается в John@Gıthub.com:

'ß'.toLowerCase() // 'ss'
'ß'.toLowerCase() === 'SS'.toLowerCase() // true

// Note the Turkish dotless i
'John@Gıthub.com'.toUpperCase() === 'John@Github.com'.toUpperCase()

Такие коллизии можно найти по всем плоскостям Юникода: вот полный список.

Нас интересуют в первую очередь те знаки, которые транслируются в латинские символы. Таких всего одиннадцать вариантов. На третьем месте в таблице как раз турецкий знак 'i' без точки.


GitHub позволял злоумышленнику получить пароль от чужого аккаунта, потому что процедура восстановления забытого пароля работала некорректно.

В рамках этой процедуры выполнялось сравнение введённого адреса электронной почты с адресом, который хранится в базе. Алгоритм проверки:

  1. Введённый адрес переводится в нижний регистр с помощью метода toLowerCase.
  2. Введённый адрес сравнивается с адресом в базе зарегистрированных пользователей.
  3. Если найдено совпадение, пароль из базы данных высылается на введённый адрес.

Очевидно, разработчики не знали о коллизии трансляции адресов при использовании метода toLowerCase.

В данном случае исправить ошибку просто. Достаточно высылать пароль не на введённый адрес, а на адрес из базы данных.

Конечно, это не полное исправление ошибки, а только быстрый патч. Более полным решением будет трансляция в Punycode для проверки: John@Gıthub.comxn—john@gthub-2ub.com. Punycode был разработан для однозначного преобразования доменных имен в последовательность ASCII-символов. Адрес электронной почты можно проверять таким же способом, но большинство веб-приложений этого не делает.

За найденную уязвимость Джон Грейси получил денежное вознаграждение и 2500 очков в рейтинг, хотя ему ещё далеко до главного гитхабовского хакера Александра Добкина <img src=404 onerror=alert(document.domain)>: пользователь с таким необычным именем заработал уже 30 750 очков, в том числе за выполнение произвольного кода на серверах GitHub, на которых генерируются страницы GitHub Pages.


Сбой в мессенджере при получения эмодзи с чёрной точкой (Messenger в iOS, WhatsApp под Android)

Связанные с Юникодом баги имеют такое свойство, что их можно встретить в любом приложении, которое обрабатывает текст, введённый пользователем. Уязвимости есть и в веб-приложениях, и в нативных программах под Android и iOS. Одним из самых известных стал баг iOS от 2015 года, когда несколько знаков Юникода в текстовом сообщении вызывали сбой операционной системы. В прошлом году похожий юникодовский баг обнаружили в iOS 11.3, он известен как «чёрная точка». Похожий сбой происходил в приложении WhatsApp под Android, если прикоснуться к эмодзи.

Let's block ads! (Why?)

Комментариев нет:

Отправить комментарий