В данной статье хочу рассказать о небольшом исследовании безопасности касающегося использования электронной цифровой подписи (ЭЦП) на казахстанских ресурсах. В ней вы узнаете о последствиях некорректной реализации проверки ЭЦП в информационных системах в масштабах страны. Техническое описание и инструменты для выявления такой уязвимости прилагаются. Будет актуально всем, кто работает с похожими системами, а казахстанским компаниям и разработчикам — обязательно к прочтению.
Что такое ЭЦП и как ее использовать в общих чертах и в контексте Республики Казахстан кратко описано
В этой ИС использовалась подпись в формате
Пример подписи XML-Dsig
Здесь можно выделить 3 элемента XML:
Однако, я пошел дальше и понял, что подпись самого сертификата так же не проверялась, а значит я мог изменять любые значения в нем, в том числе и ИИН пользователя.
Сам сертификат
У сертифката есть набор свойств: серийный номер, алгоритм подписи, информация об издателе и владельце, срок действия, открытый ключ, цифровая подпись самого сертифката для его проверки и прочее. Для идентифкации свойств используятся Object identifier (
Например, для хранения ИИН владельша используется стандарнтый OID 2.5.4.5 (SerialNumber), 2.5.4.3 (CN) для имени и фамилии. Другие идентификаторы описаны в
Вот пример структуры сертификата физического лица, выданного НУЦ РК (значения изменены):
После изменения сертификата и упаковки его обратно в контейнер PKCS#12 (файл *.p12) NCALayer отказывался принимать его, что предсказуемо, ведь подпись сертификата теперь не может пройти проверку.
Хорошо, что количество цифр в ИИН фиксировано и эти 12 байт в бинарном виде сертификата можно поменять “налету”, не меняя структуру данных ASN.1. Что я и сделал в первом PoC для этой ИС: подменял ИИН в сертификате, кодировал его в BASE64, отправлял запрос на сервер с модифицированной подписью XML-Dsig, а в ответ получал идентификатор сессии.
Так я впервые обошел аутентификацию на основе ЭЦП. Забегая вперед, хочется сказать, что это была не худшая реализация работы с ЭЦП.
Используя Google-дорки, список авторизованных ИС для работы с ЭЦП и прочие порталы со списком популярных в РК сервисов для граждан, удалось найти больше 90 разных ИС. Однако проверить удалось только 80 из них. Остальные либо не работали, либо требовали закрытой регистрации.
В итоге 52 из 80 проверенных ИС оказались уязвимы и позволяли обойти механизм аутентификации ввиду отсутствия проверки сертификата пользователя. Уточню, что некоторые ресурсы использовали ЭЦП как один из факторов, и в этом случае риск был не так критичен.
В этом списке не учитывались ИС собщим бэкендом/провайдером аутентификации, если учитывать каждую, то можно смело увеличить этот список в двое.
Например, были найдены 4 системы документооборота, с которых работают крупнейшие организации страны, в том числе государственные органы (от 5 до 100 тысяч организаций (по данным официальных сайтов). Данные системы предоставляли доступ к платформе SaaS/PaaS, что позволяло (в теории) получить доступ к личным кабинетам клиентов, а в некоторых случаях и к административной части системы. В том числе была найдена система документооборота on-premises с множеством инстансов в РК.
Одна из проверенных ИС принадлежала банку, хотя и не была связана с ДБО. А также были ИС и порталы, вязанные со здравоохранением, образованием и социальными услугами для населения.
На одном из таких порталов мне удалось войти от имени пользователя с “очень большими“ привилегиями и доступом к персональным данными родителей и их детей общим количеством более миллиона записей. Не лучшая идея — делать административный интерфейс с такими привилегиями с доступом из публичной сети.
Ну и конечно же портал с электронными петициями, где также используется ЭЦП и из-за отсутствия нормальной проверки можно накрутить голоса. Вот
Все детали уязвимостей были отправлены на Bug Bounty платформу
Ситуацию усугубляет тот факт, что по некоторым ИС отчеты были отправлены еще в феврале, а устранены были единицы и даже МЦРИАП (Министерство цифрового развития и аэрокосмической промышленности) ничего не может с этим
На большей части ИС проверялась подпись данных, но не сертификат, пришлось разбираться как подписать данные на Python в формате XML-Dsig, CMS и CAdES. Пришлось также разбираться как модифицировать сертификат, разбирать и собирать заново структуру ASN.1, что с моим уровнем владения Python было непросто.
Ситуацию осложняло и то, что разработчики в некоторых ИС радовали изобретательностью. В некоторых ИС от одного разработчика был общий бэкенд аутентификации, с несколькими запросами и редиректами на разные хосты, да и формат данных был везде разный. На одной из ИС вообще была обфускация отправляемых данных и самого JS-скрипта для их отправки!
В общем требовалось много времени на PoC для каждой ИС, а учитывая список из 40 штук (на тот момент) руки начали опускаться. Пока в голову не пришла отличная идея.
Для получения официального SDK, надо подписывать NDA и другие бумаги с НУЦ РК, что не выглядело разумной идеей. На официальном форуме (
Так что в ход пошли DevTools и Burp для анализ общения браузера и NCALayer. Еще очень помог ресурс с интерактивной
Все общение сводилось к обмену сообщениями в формате JSON внутри WebSocket’a, и в обобщенном виде оно выглядело так:
Если не вдаваться в детали, то браузер сначала посылает запрос о статусе и получает в ответ готовность и версию, затем отправляет запрос на подписание данных.
В этом запросе указывается модуль для подписи, метод, сами данные для подписи и другие параметры. А в ответ получает цифровую подпись в запрошенном формате, либо сообщение об ошибке. Есть еще много нюансов, но они сейчас не важны.
Самих модулей и их методов много, но реализованы были лишь те, что попадались в проверяемых ИС.
Скрипт FCALayer.py получился довольно компактным, 1000+ строк, половина из которых комментарии. На данный момент в скрипте реализовано 17 методов в 4-х модулях и доступен следующий функционал:
Параметры запуска
Пример работы скрипта
В некоторых ИС для аутентификации требовался контейнер с ключами, а криптографические функции были реализованы на JavaScript. Некоторые ИС для аутентификации просто отправляли сертификат, без ЭЦП. В одной так и вовсе контейнер с ключами отправлялся на сервер, разумеется, перед этим спросив пользователя пароль от него (исправлено владельцем после отправки отчета).
А разработчики одной страховой компании совсем уж не стали заморачиваться со всей этой криптографией и решили отправлять только ИИН, открытым текстом без пароля и каких-либо проверок.
По этим причинам был создан еще один скрипт — make‑p12.py. Он просто генерирует сертификат с нужными свойствами и закрытый ключ, сохраняя все в контейнер PKCS#12.
Более подробную информацию можно найти в репозитории
Почему так случилось:
Собственно, такая попытка была со стороны одного SOC, но небольшой фикс и отчет был успешно отправлен на платформу. В текущей реализации я убрал этот фикс, позже верну.
Кому нужен FCALayer? Для аудиторов и разработчиков. Некоторые владельцы ИС заявляли модераторам платформы, что исправили уязвимость и просили перепроверить несколько раз. Но ничего не менялось. То есть отдельным разработчикам не только сложно реализовать проверку подлинности, но и проверить ее работу.
Еще я уверен, что такой инструмент должны разрабатывать те же люди что и NCALayer. При проверке некоторых ИС мне приходилось добиваться одинакового ответа как в NCALayer, буквально посимвольно: соблюдать длину строки для BASE64, правильно выбирать управляющие символы для конца строки (\r\n), соблюдать регистр тегов XML и многое другое.
На этом все, спасибо, что дочитали!
Предыстория
Впервые взглянуть на электронную цифровую подпись (ЭЦП) с технической точки зрения мне довелось осенью 2023 года во время проекта по тестированию на проникновение крупной государственной организации. В одной из ее информационных систем (ИС) была возможность использовать ЭЦП для входа в личный кабинет, с
Для просмотра ссылки необходимо нажать
Вход или Регистрация
в качестве посредника.Что такое ЭЦП и как ее использовать в общих чертах и в контексте Республики Казахстан кратко описано
Для просмотра ссылки необходимо нажать
Вход или Регистрация
и
Для просмотра ссылки необходимо нажать
Вход или Регистрация
. Но самое важное, что ЭЦП позволяет не только аутентифицировать ее владельца в различных ИС, она так же равнозначна собственноручной подписи и имеет такую же юридическую силу (статья 10,
Для просмотра ссылки необходимо нажать
Вход или Регистрация
об ЭЦП РК).В этой ИС использовалась подпись в формате
Для просмотра ссылки необходимо нажать
Вход или Регистрация
, как указано в примере на скриншоте ниже:Пример подписи XML-Dsig
Здесь можно выделить 3 элемента XML:
- DigestValue - хэш подписываемых данных;
- SignatureValue – сама подпись;
- X509Certificate – сертификат пользователя с открытым ключом.
Однако, я пошел дальше и понял, что подпись самого сертификата так же не проверялась, а значит я мог изменять любые значения в нем, в том числе и ИИН пользователя.
Сам сертификат
Для просмотра ссылки необходимо нажать
Вход или Регистрация
— это бинарный файл, кодированный с помощью Distinguished Encoding Rules (DER) и сериализованный в
Для просмотра ссылки необходимо нажать
Вход или Регистрация
. Править его руками в HEX-редакторе занятие непростое: при изменении длины строки вся структура смещается и нужно менять кучу значений во всей структуре. Для этих целей существует специальное ПО, например
Для просмотра ссылки необходимо нажать
Вход или Регистрация
.У сертифката есть набор свойств: серийный номер, алгоритм подписи, информация об издателе и владельце, срок действия, открытый ключ, цифровая подпись самого сертифката для его проверки и прочее. Для идентифкации свойств используятся Object identifier (
Для просмотра ссылки необходимо нажать
Вход или Регистрация
).Например, для хранения ИИН владельша используется стандарнтый OID 2.5.4.5 (SerialNumber), 2.5.4.3 (CN) для имени и фамилии. Другие идентификаторы описаны в
Для просмотра ссылки необходимо нажать
Вход или Регистрация
выдачи регистрационных свидетельств национальным удостоверяющим центром РК.Вот пример структуры сертификата физического лица, выданного НУЦ РК (значения изменены):
После изменения сертификата и упаковки его обратно в контейнер PKCS#12 (файл *.p12) NCALayer отказывался принимать его, что предсказуемо, ведь подпись сертификата теперь не может пройти проверку.
Хорошо, что количество цифр в ИИН фиксировано и эти 12 байт в бинарном виде сертификата можно поменять “налету”, не меняя структуру данных ASN.1. Что я и сделал в первом PoC для этой ИС: подменял ИИН в сертификате, кодировал его в BASE64, отправлял запрос на сервер с модифицированной подписью XML-Dsig, а в ответ получал идентификатор сессии.
Так я впервые обошел аутентификацию на основе ЭЦП. Забегая вперед, хочется сказать, что это была не худшая реализация работы с ЭЦП.
Больше уязвимостей богу уязвимостей
Исходя из опыта, я был уверен, что другие разработчики при работе с ЭЦП будут допускать аналогичные ошибки. А учитывая растущую популярность использования ЭЦП в различных организациях, таких систем должно быть немало.Используя Google-дорки, список авторизованных ИС для работы с ЭЦП и прочие порталы со списком популярных в РК сервисов для граждан, удалось найти больше 90 разных ИС. Однако проверить удалось только 80 из них. Остальные либо не работали, либо требовали закрытой регистрации.
В итоге 52 из 80 проверенных ИС оказались уязвимы и позволяли обойти механизм аутентификации ввиду отсутствия проверки сертификата пользователя. Уточню, что некоторые ресурсы использовали ЭЦП как один из факторов, и в этом случае риск был не так критичен.
В этом списке не учитывались ИС собщим бэкендом/провайдером аутентификации, если учитывать каждую, то можно смело увеличить этот список в двое.
Масштаб проблемы
Большинство уязвимых ИС принадлежат или созданы для государственных или квазигосударственных организаций. Часть из них принадлежала коммерческим организациям.Например, были найдены 4 системы документооборота, с которых работают крупнейшие организации страны, в том числе государственные органы (от 5 до 100 тысяч организаций (по данным официальных сайтов). Данные системы предоставляли доступ к платформе SaaS/PaaS, что позволяло (в теории) получить доступ к личным кабинетам клиентов, а в некоторых случаях и к административной части системы. В том числе была найдена система документооборота on-premises с множеством инстансов в РК.
Одна из проверенных ИС принадлежала банку, хотя и не была связана с ДБО. А также были ИС и порталы, вязанные со здравоохранением, образованием и социальными услугами для населения.
На одном из таких порталов мне удалось войти от имени пользователя с “очень большими“ привилегиями и доступом к персональным данными родителей и их детей общим количеством более миллиона записей. Не лучшая идея — делать административный интерфейс с такими привилегиями с доступом из публичной сети.
Ну и конечно же портал с электронными петициями, где также используется ЭЦП и из-за отсутствия нормальной проверки можно накрутить голоса. Вот
Для просмотра ссылки необходимо нажать
Вход или Регистрация
на новость на inbusiness.kz.Все детали уязвимостей были отправлены на Bug Bounty платформу
Для просмотра ссылки необходимо нажать
Вход или Регистрация
. И тут надо сказать спасибо команде ЦАРКА за их труд, ибо общение с владельцами ИС — это совершенно неблагодарное занятие.Ситуацию усугубляет тот факт, что по некоторым ИС отчеты были отправлены еще в феврале, а устранены были единицы и даже МЦРИАП (Министерство цифрового развития и аэрокосмической промышленности) ничего не может с этим
Для просмотра ссылки необходимо нажать
Вход или Регистрация
.Рутина
Иногда найти уязвимость бывает проще, чем эксплуатировать. Перехватить запрос из браузера, поменять пару символов в сертификате или подписи не трудно. Но почти всегда нужно подменять другие значения в сертификате: ИИН/БИН, ФИО, email и т.д. Модифицированный сертификат в NCALayer использовать нельзя, да и писать огромную инструкцию для PoC с использованием кучи утилит не вариант. Такой отчет будут проверять очень долго и не факт, что примут, поэтому для каждой ИС нужно было писать свой скрипт для подтверждения концепции.На большей части ИС проверялась подпись данных, но не сертификат, пришлось разбираться как подписать данные на Python в формате XML-Dsig, CMS и CAdES. Пришлось также разбираться как модифицировать сертификат, разбирать и собирать заново структуру ASN.1, что с моим уровнем владения Python было непросто.
Ситуацию осложняло и то, что разработчики в некоторых ИС радовали изобретательностью. В некоторых ИС от одного разработчика был общий бэкенд аутентификации, с несколькими запросами и редиректами на разные хосты, да и формат данных был везде разный. На одной из ИС вообще была обфускация отправляемых данных и самого JS-скрипта для их отправки!
В общем требовалось много времени на PoC для каждой ИС, а учитывая список из 40 штук (на тот момент) руки начали опускаться. Пока в голову не пришла отличная идея.
Fake Certification Authority Layer
Практически на всех найденных ИС (за некоторым исключением) вся работа с криптографией реализована на стороне NCALayer, именно для этого он и создан. А то, как данные передаются от фронтенда к бэкенду особого значения не имеет. Осталось сымитировать работу NCALayer, отправив браузеру модифицированный сертификат или подпись. Звучит просто.Для получения официального SDK, надо подписывать NDA и другие бумаги с НУЦ РК, что не выглядело разумной идеей. На официальном форуме (
Для просмотра ссылки необходимо нажать
Вход или Регистрация
и
Для просмотра ссылки необходимо нажать
Вход или Регистрация
), как и в репозитории на GitHub, информации по работе с NCALayer было мало. Буквально крохи информации.Так что в ход пошли DevTools и Burp для анализ общения браузера и NCALayer. Еще очень помог ресурс с интерактивной
Для просмотра ссылки необходимо нажать
Вход или Регистрация
по KAZTOKEN mobile. Это не официальная документация, но очень близко кто тому-что было по факту.Все общение сводилось к обмену сообщениями в формате JSON внутри WebSocket’a, и в обобщенном виде оно выглядело так:
Если не вдаваться в детали, то браузер сначала посылает запрос о статусе и получает в ответ готовность и версию, затем отправляет запрос на подписание данных.
В этом запросе указывается модуль для подписи, метод, сами данные для подписи и другие параметры. А в ответ получает цифровую подпись в запрошенном формате, либо сообщение об ошибке. Есть еще много нюансов, но они сейчас не важны.
Самих модулей и их методов много, но реализованы были лишь те, что попадались в проверяемых ИС.
Скрипт FCALayer.py получился довольно компактным, 1000+ строк, половина из которых комментарии. На данный момент в скрипте реализовано 17 методов в 4-х модулях и доступен следующий функционал:
- Имитация работы NCALayer через WebSocket;
- Подпись данных в различных форматах — XML‑Dsig/CMS/CAdES;
- Создание не валидного сертификата для физ и юр. лиц с нужными свойствами при запуске по шаблону:
- Сертификат физ. лица для аутентификации (AUTH_RSA256_*.p12);
- Сертификат физ. лица для подписи (RSA256_*.p12);
- Сертификат юр. лица для аутентификации (AUTH_RSA256_*.p12);
- Использование валидного сертификата и ключа из файла PKCS#12 (.p12);
- Установка задержки отправки подписи для проверки истечения токена аутентификации в ИС;
- Намеренная поломка цифровой подписи данных для проверки ее валидации на ИС.
Параметры запуска
Пример работы скрипта
В некоторых ИС для аутентификации требовался контейнер с ключами, а криптографические функции были реализованы на JavaScript. Некоторые ИС для аутентификации просто отправляли сертификат, без ЭЦП. В одной так и вовсе контейнер с ключами отправлялся на сервер, разумеется, перед этим спросив пользователя пароль от него (исправлено владельцем после отправки отчета).
А разработчики одной страховой компании совсем уж не стали заморачиваться со всей этой криптографией и решили отправлять только ИИН, открытым текстом без пароля и каких-либо проверок.
По этим причинам был создан еще один скрипт — make‑p12.py. Он просто генерирует сертификат с нужными свойствами и закрытый ключ, сохраняя все в контейнер PKCS#12.
Более подробную информацию можно найти в репозитории
Для просмотра ссылки необходимо нажать
Вход или Регистрация
(доступ быдет открыт позже).Почему так случилось и что с этим делать
Я не разработчик и не эксперт в криптографии и могу лишь предполагать о причинах таких проблем с реализацией работы ЭЦП. Также позволю себе несколько общих рекомендаций.Почему так случилось:
- В ТЗ не указали проверку ЭЦП и сертификата, хотя это прямо прописано в
Для просмотра ссылки необходимо нажать Вход или Регистрацияпроверки подлинности ЭЦП и вДля просмотра ссылки необходимо нажать Вход или Регистрациядля ИС НУЦ РК;
- Официальный SDK есть не для всех языков. Я видел много сообщений на форуме на эту тему. И вероятно в некоторых ИС работа с ЭЦП была реализована «на коленках»;
- Возможно, SDK позволяет получить поля сертификата без его валидации;
- Непонимание принципов инфраструктуры открытых ключей и ЭЦП у отдельных разработчиков.
- Использовать официальный SDK или проверенные и надежные библиотеки для криптографии;
- Делать все проверки согласно
Для просмотра ссылки необходимо нажать Вход или Регистрацияпроверки подлинности ЭЦП, так как это ответственность владельцев ИС;
- Повышать осведомленность разработчиков и людей принимающих решения об угрозах ИБ;
- Провести аудит ИС, работающих с ЭЦП используя FCALayer;
- Ну и сигнатурная защита, о ней чуть ниже.
Собственно, такая попытка была со стороны одного SOC, но небольшой фикс и отчет был успешно отправлен на платформу. В текущей реализации я убрал этот фикс, позже верну.
Кому и зачем все это нужно
Кому нужна эта статья? Всем нам. Все так боятся утечки персональных данных, но никого не волнуют проблемы безопасности, из-за которых эти утечки происходят.Кому нужен FCALayer? Для аудиторов и разработчиков. Некоторые владельцы ИС заявляли модераторам платформы, что исправили уязвимость и просили перепроверить несколько раз. Но ничего не менялось. То есть отдельным разработчикам не только сложно реализовать проверку подлинности, но и проверить ее работу.
Еще я уверен, что такой инструмент должны разрабатывать те же люди что и NCALayer. При проверке некоторых ИС мне приходилось добиваться одинакового ответа как в NCALayer, буквально посимвольно: соблюдать длину строки для BASE64, правильно выбирать управляющие символы для конца строки (\r\n), соблюдать регистр тегов XML и многое другое.
На этом все, спасибо, что дочитали!
Ссылки
-
Для просмотра ссылки необходимо нажать Вход или Регистрация
-
Для просмотра ссылки необходимо нажать Вход или Регистрация— Управление сертификатами и ключами
-
Для просмотра ссылки необходимо нажать Вход или Регистрация— Графический редактор Abstract Syntax Notation One (ASN.1) на основе.NET
-
Для просмотра ссылки необходимо нажать Вход или Регистрацияпроверки подлинности электронной цифровой подписи МИР РК
- ASN.1 простыми словами (
Для просмотра ссылки необходимо нажать Вход или Регистрация,Для просмотра ссылки необходимо нажать Вход или Регистрация,Для просмотра ссылки необходимо нажать Вход или Регистрация) — статья на Хабр
-
Для просмотра ссылки необходимо нажать Вход или Регистрация— статья на Хабр
-
Для просмотра ссылки необходимо нажать Вход или Регистрация— аккаунт НУЦ РК на GitHub.com
- Интерактивная
Для просмотра ссылки необходимо нажать Вход или Регистрацияпо KAZTOKEN mobile
P.S.
Небольшой дисклеймер:- Содержание статьи личное мнение автора;
- egov.kz и pki.gov.kz не подвержены уязвимости;
- Уязвимости найдены в реализации проверки ЭЦП в конкретных ИС, а не в NCALayer;
- Статья имеет образовательный характер, использовать приведенное ПО необходимо только с согласия владельца информационной системы.
Для просмотра ссылки необходимо нажать
Вход или Регистрация