- PVSM.RU - https://www.pvsm.ru -
Новые инструменты, старые методы. Проводим обратную разработку и находим фатальный недостаток 1Password.
Все любят менеджеры паролей. Они великолепны по многим причинам. Лично у меня в менеджере более 200 записей. С таким большим количеством конфиденциальных данных в одном месте важно понимать масштаб ущерба в случае компрометации вашей записи, будь то вредоносные программы, эксплоиты или просто компьютер, оставленный без присмотра на несколько минут. Washington Post [1] недавно опубликовала статью, основанную на нашем исследовании [2]. Эта статья помогает довести людей, что не все менеджеры паролей одинаковы.
Я свято верил, что заблокированный парольный менеджер надёжно защищён. Если кто-то получит доступ к моему компьютеру, то максимум может рассчитывать на кучку случайных байтов, поскольку информация надёжно вычищается из памяти.
Это верно для 1Password 4 (Обратите внимание, что последняя версия на сегодня седьмая). Прежде чем перейти на него несколько лет назад я проверил, что в памяти действительно нет паролей в открытом виде, когда менеджер в заблокированном состоянии. Так что в случае компрометации злоумышленнику придётся иметь дело с зашифрованным хранилищем.
Хранилище заперто!
В этом состоянии в памяти нет ни парольных записей, ни мастер-пароля. Очень разумно и правильно, и 1Password 4 прошёл эту проверку. Или нет?
Чтобы избавить от скучных деталей, скажу сразу: мы смогли восстановить мастер-пароль из заблокированного инстанса в 1Password 4, как показано ниже.
Разблокировка 1Password 4 и восстановление мастер-пароля
В анимации показано, что 1Password 4 сначала разблокируется нормальным способом, а затем запирается. После этого мы запускаем нашу утилиту multipass [3], которая успешно восстанавливает пароль. Утилита эксплуатирует неправильную обработку поля ввода пароля в 1Password 4, чтобы восстановить обфусцированный буфер мастер-пароля, деобфусцировать его, автоматически разблокировать 1Password 4 и, наконец, отобразить мастер-пароль в консоли.
Первый шаг при оценке менеджера паролей: проверить наличие мастер-пароля в памяти в открытом виде. Это возможно в любом hex-редакторе, который способен взаимодействовать с пространством памяти процесса. Например, бесплатный редактор HxD [4]. С его помощью можно открыть пространство памяти 1Password 4.
Мы сразу попадаем в первую читаемую область пространства памяти 1Password 4.
Пример представления памяти HxD
Пока ничего особенного. Но можно выполнить поиск. Например, как выглядит ситуация, если набрать пароль в окне разблокировки 1Password 4, но не нажать кнопку «Разблокировать»:
Запертое хранилище 1Password 4 с введённым мастер-паролем в поле
Наверняка пароль где-то в памяти?
Открываем HxD, но поиск строки с нашим мастер-паролем (“Z3Superpass#”) не даёт результатов.
Похоже, 1Password как-то шифрует или обфусцирует форму по мере её ввода. Если процедура работает правильно, то всё хорошо.
Чтобы узнать, почему мастер-пароль нельзя найти в памяти, когда он явно присутствует в диалоговом окне разблокировки, следует найти код, который с ним взаимодействует. Тут есть несколько способов. Можно отследить обработку событий клавиатуры и мыши путём локализации ‘GetMessage’, ‘PeekMessage’, ‘GetWindowText’ или других Windows API, которые обычно обрабатывают пользовательский ввод. Так мы найдём буфера, куда записываются нажатия клавиш, а через них выйдем на подпрограмму шифрования/обфускации. Но это долгий и подверженный ошибкам процесс, особенно с большими фреймворками, которые иногда очень странно управляют памятью, так что для отслеживания буфера придётся сделать множество копий и преобразований.
Вместо этого используем собственный инструмент Thread Imager, созданный для обратной разработки «странных» проприетарных протоколов на прикладном уровне. Он поможет определить, в каком месте памяти 1Password 4 взаимодействует с нашим мастер-паролем. Инструмент «автоматически» идентифицирует области кода в 1Password 4, которые взаимодействуют с обфусцированным паролем (он просто подсвечивает инструкции, которые взаимодействуют с интересующими данными, для дальнейшего анализа). Результат выглядит примерно так:
Thread Imager находит код 1Password 4, который взаимодействует с необфусцированным мастер-паролем
Поскольку мастер-пароль хранится в памяти в обфусцированном виде, то инструмент должен первым делом показать, в каком месте происходит обфускация.
Фрагмент из первого результата показывает, что первое появление мастер-пароля сопровождается переходом кода с адреса 0x7707A75D на 0x701CFA10.
Подробная запись в Thread Imager подсвечивает переход кода с с 0x7707A75D на 0x701CFA10, при этом на буфер с мастер-паролем ссылаются регистры EAX и ECX
Изучение этого места 0x7707A75D в отладчике (x64dbg) подтверждает нашу теорию. Действительно, впервые строка ‘Z3superpass#’ встречается при завершении работы функции декодирования ‘RtlRunDecodeUnicodeString’ из библиотеки ntdll.dll.
После небольшого анализа ясно, что для обфускации пароля используются именно эти две функции: ‘RtlRunEncodeUnicodeString’ и ‘RtlRunDecodeUnicodeString’. Так мастер-пароль прячут от примитивного копирования из памяти, вот почему раньше мы не могли найти его в hex-редакторе.
Если изучить закодированный буфер в конце работы функции RtlRunEncodeUnicodeString, то зашифрованная строка с мастер-паролем выглядит так:
Зашифрованный мастер-пароль
После RtlRunDecodeUnicodeString’ он декодируется:
Расшифрованный мастер-пароль
Интересно, что эта область сохраняется по тому же адресу 0x00DFA790 и мы буквально можем наблюдать её изменение при вводе пароля в окно разблокировки 1Password 4:
‘RtlRunEncodeUnicodeString’ и ‘RtlRunDecodeUnicodeString’ — простые функции, которые изменяют строку простой операцией XOR. Это не так уж плохо: похоже, это стандартный метод маскировки всех нативных редактирующих управляющих элементов Windows при установленном флаге ‘ES_PASSWORD'.
Проблема в том, что после разблокировки 1Password 4 зашифрованный мастер-пароль не очищается из памяти.
Хуже того, он остаётся в памяти и после блокировки 1Password 4. То есть у нас есть заблокированное хранилище паролей, но с зашифрованным мастер-паролем в памяти.
И что ещё хуже, поскольку мы взаимодействуем с диалоговым окном ввода мастер-пароля, одна и та же область памяти повторно используется вместе с тем же значением XOR, что даёт нам лёгкий доступ к закодированному буферу для создания эксплоита.
Чтобы создать надёжный эксплоит для 1Password 4, нужно получить более чёткое представление, как мастер-пароль обрабатывается рабочими процессами программы. С помощью вышеупомянутых инструментов мы построили диаграмму выходных данных (рисунок ниже).
По такой диаграмме легче понять, где и какие задействуются библиотеки, чтобы надёжно идентифировать области в памяти, откуда можно извлечь мастер-пароль.
Что мы имеем на данный момент? У нас запертое хранилище, а где-то в памяти хранится обфусцированный пароль, поскольку программа не почистила за собой память надлежащим образом.
Чтобы извлечь его, нужно вызвать процедуру в 1Password 4, которая инициирует ‘RtlRunEncodeUnicodeString’ и ‘RtlRunDecodeUnicodeString’. Таким образом она покажет расположение буфера памяти с закодированным мастер-паролем.
Область памяти с обфусцированным мастер-паролем
Без этого буфера пришлось бы погрузиться в бездну внутренних процедур и элементов управления Windows и связанных с ними механизмов управления памятью. Может, такой анализ и позволяет легко найти буфер, но мы не пошли по этому пути.
Похоже, единственный способ вызвать ‘RtlRunEncodeUnicodeString’ и ‘RtlRunDecodeUnicodeString’ — это ввести в символ в диалоговое окно ввода мастер-пароля. Так мы получаем нужный буфер. Но мы не знаем длину пароля.
Мы решили эту проблему путём перехвата кода, который обращается к первому символу нашего буфера, блокируя попытку изменения. Эта подпрограмма находится в цикле обработки сообщений управляющего элемента в comctl32, который обрабатывает управление буфером соответствующих элементов. Вызов ‘memmove’ со смещением 0x70191731 перезаписывает буфер введённым символом:
(Побочный эффект: выделенная строка (жёлтая) обновляет всю строку пароля)
Теперь мы, наконец, получили всё, что нужно для создания эксплоита. Следующие шаги позволят нам извлечь мастер-пароль:
Для выполнения всех этих действий создаём DLL с кодом обработчика всех этих хуков. Библиотека внедряется в процесс 1Password 4, отправляет один символ в диалоговое окно мастер-пароль, запуская шаги memmove, RtlRunEncodeUnicodeString и RtlRunDecodeUnicodeString, которые мы можем перехватить — и производя нашу магию по восстановлению обфусцированного мастер-пароля. Большая часть магии происходит в DetourRtlRunEncodeUnicodeString, это хук для функции ‘RtlRunEncodeUnicodeString’, показанный ниже:
Что приводит нас к окончательному результату: разблокировка запертого хранилища 1Password 4 любой версии при помощи глючной процедуры в используемых Windows API:
Когда мы впервые углубились во внутренности 1Password 4, то ожидали встретить какую-то сложную систему защиты и ожидали, что вся секретная информация будет очищаться из памяти, как это происходит в процедурах PBKDF2 и других областях, где используется мастер-пароль. Соответствующие записи тоже очищаются. Однако по недосмотру поле ввода пароля рассматривается как стандартный элемент управления Windows API со скрытым паролем, что подрывает безопасность 1Password 4.
Автор: m1rko
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/informatsionnaya-bezopasnost/309512
Ссылки в тексте:
[1] Washington Post: https://www.washingtonpost.com/technology/2019/02/19/password-managers-have-security-flaw-you-should-still-use-one/
[2] исследовании: https://www.securityevaluators.com/casestudies/password-manager-hacking/
[3] multipass: https://github.com/abednarek/Multipass
[4] HxD: https://mh-nexus.de/en/hxd/
[5] Источник: https://habr.com/ru/post/441166/?utm_source=habrahabr&utm_medium=rss&utm_campaign=441166
Нажмите здесь для печати.