СМС-сообщения — популярнейший способ двухфакторной аутентификации (2FA). Ее используют банки, электронные и крипто-кошельки, почтовые ящики и всяческие сервисы; число пользователей метода приближается к 100%.
У меня такой расклад событий вызывает негодование, ведь этот метод небезопасный. Переназначать номер с одной SIM-карты на другую стали еще в начале мобильной эры — так восстанавливают номер при потере симки. “Специалисты по отъему цифровых денег” осознали: опцию «перезаписи симки» можно использовать в мошеннических схемах. Ведь тот, кто контролирует сим-карту, может управлять и чужим онлайн-банкингом, и электронными кошельками, и даже криптовалютой. А завладеть номером другого лица можно через подкуп сотрудника телекома, с помощью обмана или поддельных документов.
Раскрыты тысячи эпизодов SIM-свопинга — так назвали эту схему мошенничества. Масштабы бедствия говорят о том, что скоро мир откажется от 2FA по СМС. Но этого не происходит — в исследовании рассказывают, что выбирают метод 2FA не пользователи, а владельцы сервисов.
Мы предлагаем использовать безопасный метод 2FA с доставкой одноразовых кодов через блокчейн, и расскажем, как владельцу сервиса его подключить.
В 2019 году мошенничество SIM-свопингом выросло на 63% по данным лондонской полиции, а “средний чек” злоумышленника — 4,000 GBP. Статистики в России я не нашел, однако предполагаю, что она еще хуже.
SIM-свопинг используется для кражи популярных аккаунтов Twitter, Instagram, Facebook, VK, банковских аккаунтов, а недавно добрались и до криптовалют — сообщает газета Таймс со слов биткоин-предпринимателя Джоби Уикса. Громкие дела о краже криптовалют с помощью SIM-свопинга всплывают в прессе с 2016 года; на 2019-й пришелся настоящий пик.
В мае прокуратура США в восточном округе Мичигана предъявила обвинения девяти молодым людям в возрасте от 19 до 26 лет: они предположительно входят в хакерскую банду под названием “The Community” («Сообщество»). Банде вменяется семь свопинг-атак, в результате которых хакеры присвоили криптовалюту на сумму свыше $2,4 миллиона. А в апреле студент из Калифорнии Джоэл Ортиз получил 10 лет тюрьмы за SIM-свопинг; его добычей стали $7.5 млн. в криптовалютах.
Фото Джоэла Ортиза на пресс-конференции в университете. Спустя два года он будет задержан за кибермошенничество.
«Свопинг» — значит обмен. Во всех подобных схемах преступники присваивают себе телефонный номер жертвы, обычно через перевыпуск SIM-карты, и пользуются им для сброса пароля. Типичный SIM-свопинг в теории выглядит так:
В реальной жизни все еще более сурово. Злоумышленники выбирают жертву, а затем ежедневно отслеживают местонахождение телефона — один запрос на получение информации о том, что абонент перешел в роуминг стоит 1-2 цента. Как только владелец сим-карты уехал за границу, они договариваются с менеджером в салоне связи на выдачу новой сим-карты. Стоит это около $50 (я находил информацию — в разных странах и у разных операторов от $20 до $100), при этом менеджер в худшем случае будет уволен — за это нет ответственности.
Теперь все СМС будут получать злоумышленники, а владелец телефона ничего не сможет с этим сделать — он за границей. А дальше злодеи получают доступ ко всем аккаунтам жертвы и при желании меняют пароли.
Банки иногда идут навстречу жертвам и отзывают переводы с их счетов. Поэтому вернуть фиатные деньги удается, даже если преступник не найден. Но с криптовалютными кошельками все сложнее — и технически, и законодательно. Пока ни одна биржа/кошелек не выплатили компенсации жертвам свопинга.
Если пострадавшие хотят отстоять свои деньги в суде, то обвиняют оператора: он создал условия для кражи денег со счета. Именно так поступил Майкл Терпин, который потерял из-за свопинга $224 млн. Сейчас он судится с телекоммуникационной компанией AT&T.
Пока ни у одного государства нет рабочих схем, чтобы законодательно защитить владельцев криптовалют. Застраховать свой капитал или получить компенсацию за его потерю невозможно. Поэтому предотвратить свопинг-атаку проще, чем бороться с ее последствиями. Самый очевидный способ — использовать более надежный «второй фактор» для 2FA.
Коды подтверждения в СМС небезопасны и с технической точки зрения. Сообщения можно перехватить из-за неустранимых уязвимостей в сигнальной системе Signaling System 7 (SS7). 2FA по SMS официально признана небезопасной (Национальный институт стандартов и технологий США говорит об этом в своем Руководстве по цифровой аутентификации).
При этом наличие 2FA часто внушает пользователю чувство ложной безопасности, и он выбирает более простой пароль. Поэтому такая аутентификация не затрудняет, а облегчает доступ злоумышленника к аккаунту.
А еще нередко СМС приходят с большой задержкой или не приходят совсем.
Разумеется, на смартфонах и СМС свет клином не сошелся. Есть и другие способы 2FA. Например, одноразовые TAN-коды: способ примитивный, но рабочий — он до сих пор используется в некоторых банках. Есть системы с применением биометрических данных: отпечатков пальцев, сканов сетчатки. Еще один вариант, который кажется разумным компромиссом по удобству, надежности и цене — специальные приложения для 2FA: RSA Token, Google Authenticator. А еще есть физические ключи и другие методы.
В теории все выглядит логичным и надежным. Но на практике у современных 2FA-решений есть проблемы, и из-за них реальность отличается от ожиданий.
Согласно исследованию, использование 2FA является неудобством в принципе, а популярность 2FA по СМС объясняют “меньшим неудобством по сравнению с другими методами” — получение одноразовых кодов понятно для пользователя.
Многие способы 2FA пользователи связывают со страхом, что доступ будет утерян. Физический ключ или список TAN-паролей можно потерять или их могут украсть. У меня лично есть негативный опыт использования Google Authenticator. Первый смартфон с этим приложением у меня сломался — оцените мои труды по восстановлению доступа к аккаунтам. Другая проблема — переход на новое устройство. Google Authenticator не имеет возможности экспорта из-за соображений безопасности (если ключи можно экспортировать, какая тут безопасность?). Один раз я переносил ключи вручную, а дальше решил, что проще оставлять старый смартфон в коробке на полке.
Метод 2FA должен быть:
Мы считаем, что блокчейн — подходящее решение.
Для пользователя 2FA на блокчейне выглядит так же, как и получение одноразовых кодов по СМС. Отличие только в канале доставки. Способ получения 2FA-кода зависит от того, что предлагает блокчейн. В нашем проекте (информация есть в моем профиле) это Web-приложение, Tor, iOS, Android, Linux, Windows, MacOS.
Сервис генерирует одноразовый код и посылает его в мессенджер на блокчейне. Дальше — по классике: пользователь вводит полученный код в интерфейсе сервиса и авторизуется.
В статье Как работает децентрализованный мессенджер на блокчейне я написал, что блокчейн обеспечивает безопасность и приватность передачи сообщений. По вопросу отправки кодов 2FA я выделю:
Для сравнения с некоторыми другими методами 2FA я составил таблицу:
Аккаунт в блокчейн-мессенджере для получения кодов пользователь получает за секунду — для входа используется только пассфраза. Поэтому и способы применения могут быть разными: можно использовать один аккаунт для получения кодов для всех сервисов, а можно для каждого сервиса создать отдельный аккаунт.
Есть и неудобство — аккаунт должен иметь хотя бы одну транзакцию. Для того, чтобы пользователь получил шифрованное сообщение с кодом, нужно знать его публичный ключ, а он появляется в блокчейне только с первой транзакцией. Мы выкрутились так: дали возможность получить в кошельке бесплатные токены. Однако более правильное решение — именовать аккаунт публичным ключом. (Для сравнения у нас номер аккаунта U1467838112172792705 является производным публичного ключа cc1ca549413b942029c4742a6e6ed69767c325f8d989f7e4b71ad82a164c2ada. Для мессенджера это удобнее и читабельнее, а вот для системы отправки 2FA-кодов — ограничение). Думаю, в будущем кто-нибудь сделает такое решение и переведет “Удобство и доступность” в зеленую зону.
Цена отправки 2FA-кода реально низкая — 0.001 ADM, сейчас это 0.00001 USD. Опять же, можно поднять свой блокчейн и сделать цену нулевой.
Надеюсь, я смог заинтересовать нескольких читателей, чтобы добавить блокчейн-авторизацию на их сервисы.
Я расскажу как это сделать на примере нашего мессенджера, а по аналогии вы можете использовать и другой блокчейн. В демо-приложении 2FA мы используем postgresql10 для хранения информации об аккаунтах.
Этапы подключения:
1 Создание аккаунта
Создание аккаунта в блокчейне — это генерация приватного ключа, публичного ключа, и производного от него адреса аккаунта.
Сначала генерируется пассфраза BIP39, из нее считается SHA-256-хэш. Хэш используется для генерации приватного ключа ks и публичного ключа kp. Из публичного ключа тем же SHA-256 с инверсией получаем адрес в блокчейне.
Если вы хотите отправлять коды 2FA каждый раз с нового аккаунта, код для создания аккаунта нужно будет добавить на сервер:
В демо-приложении мы упростили — создали один аккаунт в веб-приложении, и отправляем коды с него. В большинстве случаев это удобнее и пользователю: он знает, что сервис отправляет 2FA-коды с конкретного аккаунта, и может его именовать.
2 Генерация кодов 2FA
Код 2FA нужно генерировать для каждого входа пользователя. Мы используем библиотеку speakeasy, но вы можете выбрать любую другую.
Проверка валидности кода 2FA, введенного пользователем:
3 Отправка кода 2FA
Для отправки 2FA-кода можно использовать API узла блокчейна, библиотеку JS API или консоль. В этом примере мы используем консоль — это Command Line Interface, утилита, которая упрощает взаимодействие с блокчейном. Чтобы отправить сообщение с 2FA-кодом, нужно использовать команду
Альтернативный способ отправки сообщений — использовать метод
4 Интерфейс пользователя
Пользователю нужно дать возможность ввода кода 2FA, это можно сделать различными способами в зависимости от платформы вашего приложения. В нашем примере это Vue.
Исходный код демонстрационного приложения двухфакторной авторизации на блокчейне можно посмотреть в GitHub. В Readme есть ссылка на Live demo, чтобы попробовать.
У меня такой расклад событий вызывает негодование, ведь этот метод небезопасный. Переназначать номер с одной SIM-карты на другую стали еще в начале мобильной эры — так восстанавливают номер при потере симки. “Специалисты по отъему цифровых денег” осознали: опцию «перезаписи симки» можно использовать в мошеннических схемах. Ведь тот, кто контролирует сим-карту, может управлять и чужим онлайн-банкингом, и электронными кошельками, и даже криптовалютой. А завладеть номером другого лица можно через подкуп сотрудника телекома, с помощью обмана или поддельных документов.
Раскрыты тысячи эпизодов SIM-свопинга — так назвали эту схему мошенничества. Масштабы бедствия говорят о том, что скоро мир откажется от 2FA по СМС. Но этого не происходит — в исследовании рассказывают, что выбирают метод 2FA не пользователи, а владельцы сервисов.
Мы предлагаем использовать безопасный метод 2FA с доставкой одноразовых кодов через блокчейн, и расскажем, как владельцу сервиса его подключить.
Счет идет на миллионы
В 2019 году мошенничество SIM-свопингом выросло на 63% по данным лондонской полиции, а “средний чек” злоумышленника — 4,000 GBP. Статистики в России я не нашел, однако предполагаю, что она еще хуже.
SIM-свопинг используется для кражи популярных аккаунтов Twitter, Instagram, Facebook, VK, банковских аккаунтов, а недавно добрались и до криптовалют — сообщает газета Таймс со слов биткоин-предпринимателя Джоби Уикса. Громкие дела о краже криптовалют с помощью SIM-свопинга всплывают в прессе с 2016 года; на 2019-й пришелся настоящий пик.
В мае прокуратура США в восточном округе Мичигана предъявила обвинения девяти молодым людям в возрасте от 19 до 26 лет: они предположительно входят в хакерскую банду под названием “The Community” («Сообщество»). Банде вменяется семь свопинг-атак, в результате которых хакеры присвоили криптовалюту на сумму свыше $2,4 миллиона. А в апреле студент из Калифорнии Джоэл Ортиз получил 10 лет тюрьмы за SIM-свопинг; его добычей стали $7.5 млн. в криптовалютах.
Фото Джоэла Ортиза на пресс-конференции в университете. Спустя два года он будет задержан за кибермошенничество.
Принцип работы SIM-свопинга
«Свопинг» — значит обмен. Во всех подобных схемах преступники присваивают себе телефонный номер жертвы, обычно через перевыпуск SIM-карты, и пользуются им для сброса пароля. Типичный SIM-свопинг в теории выглядит так:
- Разведка. Мошенники узнают персональные данные жертвы: имя и телефон. Их можно найти в открытых источниках (соцсети, друзья) или получить от сообщника — сотрудника сотового оператора.
- Блокировка. SIM-карта жертвы деактивируется; для этого достаточно позвонить в техподдержку провайдера, сообщить номер и сказать, что телефон был утерян.
- Захват, перевод номера на свою симку. Обычно это тоже делается через сообщника в телеком-компании либо с помощью подделки документов.
В реальной жизни все еще более сурово. Злоумышленники выбирают жертву, а затем ежедневно отслеживают местонахождение телефона — один запрос на получение информации о том, что абонент перешел в роуминг стоит 1-2 цента. Как только владелец сим-карты уехал за границу, они договариваются с менеджером в салоне связи на выдачу новой сим-карты. Стоит это около $50 (я находил информацию — в разных странах и у разных операторов от $20 до $100), при этом менеджер в худшем случае будет уволен — за это нет ответственности.
Теперь все СМС будут получать злоумышленники, а владелец телефона ничего не сможет с этим сделать — он за границей. А дальше злодеи получают доступ ко всем аккаунтам жертвы и при желании меняют пароли.
Шансы вернуть украденное
Банки иногда идут навстречу жертвам и отзывают переводы с их счетов. Поэтому вернуть фиатные деньги удается, даже если преступник не найден. Но с криптовалютными кошельками все сложнее — и технически, и законодательно. Пока ни одна биржа/кошелек не выплатили компенсации жертвам свопинга.
Если пострадавшие хотят отстоять свои деньги в суде, то обвиняют оператора: он создал условия для кражи денег со счета. Именно так поступил Майкл Терпин, который потерял из-за свопинга $224 млн. Сейчас он судится с телекоммуникационной компанией AT&T.
Пока ни у одного государства нет рабочих схем, чтобы законодательно защитить владельцев криптовалют. Застраховать свой капитал или получить компенсацию за его потерю невозможно. Поэтому предотвратить свопинг-атаку проще, чем бороться с ее последствиями. Самый очевидный способ — использовать более надежный «второй фактор» для 2FA.
SIM-свопинг — не единственная проблема 2FA через СМС
Коды подтверждения в СМС небезопасны и с технической точки зрения. Сообщения можно перехватить из-за неустранимых уязвимостей в сигнальной системе Signaling System 7 (SS7). 2FA по SMS официально признана небезопасной (Национальный институт стандартов и технологий США говорит об этом в своем Руководстве по цифровой аутентификации).
При этом наличие 2FA часто внушает пользователю чувство ложной безопасности, и он выбирает более простой пароль. Поэтому такая аутентификация не затрудняет, а облегчает доступ злоумышленника к аккаунту.
А еще нередко СМС приходят с большой задержкой или не приходят совсем.
Другие способы 2FA
Разумеется, на смартфонах и СМС свет клином не сошелся. Есть и другие способы 2FA. Например, одноразовые TAN-коды: способ примитивный, но рабочий — он до сих пор используется в некоторых банках. Есть системы с применением биометрических данных: отпечатков пальцев, сканов сетчатки. Еще один вариант, который кажется разумным компромиссом по удобству, надежности и цене — специальные приложения для 2FA: RSA Token, Google Authenticator. А еще есть физические ключи и другие методы.
В теории все выглядит логичным и надежным. Но на практике у современных 2FA-решений есть проблемы, и из-за них реальность отличается от ожиданий.
Согласно исследованию, использование 2FA является неудобством в принципе, а популярность 2FA по СМС объясняют “меньшим неудобством по сравнению с другими методами” — получение одноразовых кодов понятно для пользователя.
Многие способы 2FA пользователи связывают со страхом, что доступ будет утерян. Физический ключ или список TAN-паролей можно потерять или их могут украсть. У меня лично есть негативный опыт использования Google Authenticator. Первый смартфон с этим приложением у меня сломался — оцените мои труды по восстановлению доступа к аккаунтам. Другая проблема — переход на новое устройство. Google Authenticator не имеет возможности экспорта из-за соображений безопасности (если ключи можно экспортировать, какая тут безопасность?). Один раз я переносил ключи вручную, а дальше решил, что проще оставлять старый смартфон в коробке на полке.
Метод 2FA должен быть:
- Безопасным — получить доступ к аккаунту должны только вы, а не злоумышленники
- Надежным — вы получаете доступ к аккаунту всегда, когда это нужно
- Удобным и доступным — использование 2FA понятно и занимает минимум времени
- Дешевым
Мы считаем, что блокчейн — подходящее решение.
Используйте 2FA на блокчейне
Для пользователя 2FA на блокчейне выглядит так же, как и получение одноразовых кодов по СМС. Отличие только в канале доставки. Способ получения 2FA-кода зависит от того, что предлагает блокчейн. В нашем проекте (информация есть в моем профиле) это Web-приложение, Tor, iOS, Android, Linux, Windows, MacOS.
Сервис генерирует одноразовый код и посылает его в мессенджер на блокчейне. Дальше — по классике: пользователь вводит полученный код в интерфейсе сервиса и авторизуется.
В статье Как работает децентрализованный мессенджер на блокчейне я написал, что блокчейн обеспечивает безопасность и приватность передачи сообщений. По вопросу отправки кодов 2FA я выделю:
- Один клик для создания аккаунта — никаких телефонов и электронных почт.
- Все сообщения с кодами 2FA шифруются End-to-End curve25519xsalsa20poly1305.
- MITM-атака исключена — каждое сообщение с кодом 2FA является транзакцией в блокчейне и подписывается Ed25519 EdDSA.
- Сообщение с кодом 2FA попадает в свой блок. Последовательность и timestamp блоков не исправишь, а следовательно и порядок сообщений.
- Нет центральной структуры, которая делает проверки на “достоверность” сообщения. Это делает распределенная система узлов на основе консенсуса, а она принадлежит пользователям.
- Невозможность отключения — аккаунты нельзя блокировать, а сообщения удалять.
- Доступ к кодам 2FA с любого устройства в любое время.
- Подтверждение доставки сообщения с кодом 2FA. Сервис, отправляющий одноразовый пароль, точно знает, что он доставлен. Никаких кнопок “Отправить еще раз”.
Для сравнения с некоторыми другими методами 2FA я составил таблицу:
Аккаунт в блокчейн-мессенджере для получения кодов пользователь получает за секунду — для входа используется только пассфраза. Поэтому и способы применения могут быть разными: можно использовать один аккаунт для получения кодов для всех сервисов, а можно для каждого сервиса создать отдельный аккаунт.
Есть и неудобство — аккаунт должен иметь хотя бы одну транзакцию. Для того, чтобы пользователь получил шифрованное сообщение с кодом, нужно знать его публичный ключ, а он появляется в блокчейне только с первой транзакцией. Мы выкрутились так: дали возможность получить в кошельке бесплатные токены. Однако более правильное решение — именовать аккаунт публичным ключом. (Для сравнения у нас номер аккаунта U1467838112172792705 является производным публичного ключа cc1ca549413b942029c4742a6e6ed69767c325f8d989f7e4b71ad82a164c2ada. Для мессенджера это удобнее и читабельнее, а вот для системы отправки 2FA-кодов — ограничение). Думаю, в будущем кто-нибудь сделает такое решение и переведет “Удобство и доступность” в зеленую зону.
Цена отправки 2FA-кода реально низкая — 0.001 ADM, сейчас это 0.00001 USD. Опять же, можно поднять свой блокчейн и сделать цену нулевой.
Как подключить 2FA на блокчейне к вашему сервису
Надеюсь, я смог заинтересовать нескольких читателей, чтобы добавить блокчейн-авторизацию на их сервисы.
Я расскажу как это сделать на примере нашего мессенджера, а по аналогии вы можете использовать и другой блокчейн. В демо-приложении 2FA мы используем postgresql10 для хранения информации об аккаунтах.
Этапы подключения:
- Создать аккаунт в блокчейне, с которого вы будете отправлять коды 2FA. Вы получите пассфразу, которая используется как приватный ключ для шифрования сообщений с кодами и для подписания транзакций.
- Добавить на ваш сервер скрипт для генерации кодов 2FA. Если вы уже используйте какой-либо другой метод 2FA с доставкой одноразовых паролей, этот этап у вас уже выполнен.
- Добавить на ваш сервер скрипт для отправки кодов пользователю в блокчейн-мессенджер.
- Создать пользовательский интерфейс для отправки и ввода кода 2FA. Если вы уже используйте какой-либо другой метод 2FA с доставкой одноразовых паролей, этот этап у вас уже выполнен.
1 Создание аккаунта
Создание аккаунта в блокчейне — это генерация приватного ключа, публичного ключа, и производного от него адреса аккаунта.
Сначала генерируется пассфраза BIP39, из нее считается SHA-256-хэш. Хэш используется для генерации приватного ключа ks и публичного ключа kp. Из публичного ключа тем же SHA-256 с инверсией получаем адрес в блокчейне.
Если вы хотите отправлять коды 2FA каждый раз с нового аккаунта, код для создания аккаунта нужно будет добавить на сервер:
import Mnemonic from 'bitcore-mnemonic'
this.passphrase = new Mnemonic(Mnemonic.Words.ENGLISH).toString()
…
import * as bip39 from 'bip39'
import crypto from 'crypto'
adamant.createPassphraseHash = function (passphrase) {
const seedHex = bip39.mnemonicToSeedSync(passphrase).toString('hex')
return crypto.createHash('sha256').update(seedHex, 'hex').digest()
}
…
import sodium from 'sodium-browserify-tweetnacl'
adamant.makeKeypair = function (hash) {
var keypair = sodium.crypto_sign_seed_keypair(hash)
return {
publicKey: keypair.publicKey,
privateKey: keypair.secretKey
}
}
…
import crypto from 'crypto'
adamant.getAddressFromPublicKey = function (publicKey) {
const publicKeyHash = crypto.createHash('sha256').update(publicKey, 'hex').digest()
const temp = Buffer.alloc(8)
for (var i = 0; i < 8; i++) {
temp[i] = publicKeyHash[7 - i]
}
return 'U' + bignum.fromBuffer(temp).toString()
}
В демо-приложении мы упростили — создали один аккаунт в веб-приложении, и отправляем коды с него. В большинстве случаев это удобнее и пользователю: он знает, что сервис отправляет 2FA-коды с конкретного аккаунта, и может его именовать.
2 Генерация кодов 2FA
Код 2FA нужно генерировать для каждого входа пользователя. Мы используем библиотеку speakeasy, но вы можете выбрать любую другую.
const hotp = speakeasy.hotp({
counter,
secret: account.seSecretAscii,
});
Проверка валидности кода 2FA, введенного пользователем:
se2faVerified = speakeasy.hotp.verify({
counter: this.seCounter,
secret: this.seSecretAscii,
token: hotp,
});
3 Отправка кода 2FA
Для отправки 2FA-кода можно использовать API узла блокчейна, библиотеку JS API или консоль. В этом примере мы используем консоль — это Command Line Interface, утилита, которая упрощает взаимодействие с блокчейном. Чтобы отправить сообщение с 2FA-кодом, нужно использовать команду
send message
консоли.const util = require('util');
const exec = util.promisify(require('child_process').exec);
…
const command = `adm send message ${adamantAddress} "2FA code: ${hotp}"`;
let { error, stdout, stderr } = await exec(command);
Альтернативный способ отправки сообщений — использовать метод
send
в JS API library.4 Интерфейс пользователя
Пользователю нужно дать возможность ввода кода 2FA, это можно сделать различными способами в зависимости от платформы вашего приложения. В нашем примере это Vue.
Исходный код демонстрационного приложения двухфакторной авторизации на блокчейне можно посмотреть в GitHub. В Readme есть ссылка на Live demo, чтобы попробовать.