Sunday, July 12, 2015

Извлечение контейнера закрытого ключа из APDU-трафика

Уже скоро год с момента доклада, однако интересующиеся до сих пор пишут вопросы, что и послужило причиной написания этого поста.

Проблема с которой ко мне обратились - утилита dumpContfromAPDU.pl не дампит контейнер из правильно созданного с помощью Smartcard Sniffer-а лога команд и ответов APDU.
Причин такой неработы dumpContfromAPDU.pl могут быть две:
1.  используется отличная от имеющейся у меня на момент исследования модель токена - разные модели токенов имеют несколько разный набор команд APDU, поэтому скрипт не находит нужные регексы;
2. дамп не содержит пересылки контейнера.
Вообще, скрипт писался на скорую руку в качестве PoC исключительно для целей разовой демонстрации и делать из него полноценный инструмент "на все (ну, или, по крайней мере, на многие) случаи жизни" не планирую по нескольким причинам:
а)  наверно, это своего рода "хак" (реализация неавторизованного доступа), а распространять инструменты для неавторизованного доступа - неправильно;
б) лень.

В качестве компромисса - просто расскажу как извлечь контейнер из трафика APDU вручную и предположу почему это работает.

Как это сделать.
1. Получаем дамп Smartcard Sniffer-а, при выполнении операции Проверки (можно выполнить любую другую операцию, провоцирующую передачу ключа в приложение, например, вычисление электронной подписи), как это показано в видео.
2. Далее, как выше отмечено, скрипт dumpContfromAPDU.pl не работает, поэтому что-то запустить и получить контейнер - не получится :), но для анализа, традиционно на скорую руку, я написал другой скрипт - writeBinaryAPDU.pl,  который делает элементарную вещь: дамп Smartcard Sniffer-а записывает в виде бинарных файлов диалога APDU между приложением и карточкой (токеном). Понятно, что диалог такой есть всегда, поэтому этот скрипт работает с любым токеном. В результате его работы появляется дериктория с именем эквивалентному времени ее создания, в которой лежат файлы вида "001_out(4)39_6A_42_32", где
001 - идентификатор последовательности запрос-ответ;
out - означает, что эти байты передавались из карточки в приложение, соответственно, от приложения в карточку - будет "in";
(4) - количество переданных\полученных байтов;
39_6A_42_32 - первые 4 байта.
3. Такие файлики (001_out(4)39_6A_42_32) далее смотрим глазами и\или в шестрнадцатиричном редакторе. Кто такого редактора не имеет и никогда не планирует - можно использовать FAR.
4. Опытным путем установлено, что контейнер секретного ключа представляет из себя набор файлов с расширением .key (см. слайд 11):
  • primary.key - должен иметь размер 36 байт, начало - 30_22_04_20, поэтому в нашей директории ищем файл следующего вида: №_out(36)30_22_04_20. Скорее всего такой файл будет один - сохраняем его с именем primary.key
  • masks.key - имеет размер 56 байт и начало - 30_36_04_20, соответствующий файл в нашем бинарном дампе - №_out(56)30_36_04_20. Также, скорее, этот файл будет один - это искомый masks.key
  • header.key - файл, похоже, со всяким описанием, однако его целостность как-то контролируется, поэтому если его собрать не полностью\неправильно контейнер работать не будет. О нем известно, что он содержит много информации, причем, в основном текстовой, через APDU передается порциями по 256 байт. Соответственно, в нашем дампе собираем в отдельную папочку все файлы вида №_out(256?)какие-то_байты. Я написал 256? не случайно, поскольку видел, как header.key передавался порциями по 253 байта, какая там логика выбора размера порций - не известно, но в любом случае эти порции будут радикально отличаться по размеру от всего остального трафика из карточки. Дополнительно к этим файлам надо обязательно добавить предыдущий порциям из 256 байтов ответ от карточки длиной 10 байт и с началом 30_82, а также, возможно, оставшийся "хвостик", следующий за порциями по 256 байт (или 253 или еще сколько, но обычно - больше всех остальных, и равных).  Все эти файлы надо слить в один в порядке следования (поскольку вначале названия файла стоит номер последовательности - упорядочивание по алфавиту дает порядок следования) - это можно сделать утилиткой cat.
  • name.key - содержит имя контейнера, передаваемое обычно одной порцией (в рамках исследования я делал контейнер с очень длинным именем, это видно на видео, чтобы спровоцировать передачу имени контейнера в нескольких порциях - это удалось, передача проводилась аналогично передаче header.key: сначала первые 10 байт, затем - все остальное), искомый файл - следующего вида №_out(длина имени)30_длина имени_16_длина имени - 2. Интересен тот факт, что содержимое этого файла, в целом, не важно, поэтому можно сгенерить свой файл name.key, с соблюдением формата его первых четырех байт.

В тех случаях, что я видел, можно игнорировать запросы к карточке №_in(размер)00_04*  и ответы на них. В некоторых случаях можно игнорировать и другие "стандартные" команды и ответы на них из спецификации GlobalPlatform.

Итак, собрав все 4 файлика, копируем их на флешку и проверяем контейнер, выполняя операцию "Проверка", аналогично той, что делали в момент работы Smartcard sniffer-а (при этом уже никакой пароль на контейнер спрашиваться не будет). Если проверка не прошла, то надо попробовать различные "оконечные условия" для файла header.key - если после одинаковых порций вы добавляли "хвостик", с порцией меньше предыдущих - попробуйте без него - если проверка снова неуспешна, добавьте еще следующую порцию (еще один "хвостик") - в общем, поупражняйтесь с разными комбинациями порций файлов №_out(размер)* для сбора header.key.

Почему это работает (предположения).
Криптопровайдер (CSP) - это не только как реализована математика для выполнения различных криптографических преобразований, но и как ключи хранятся. Именно поэтому для хранения ключей на токене мы используем специальный "токенный" провайдер и т.п. 

Криптопровайдер КриптоПРО CSP (не КриптороПРО eToken CSP и не КриптоПРО Rutoken CSP!! - предположительно, на них не пройдет описываемая атака, но надо поисследовать...), умеет хранить хранить ключи в файликах, указанных выше, причем, не важно в какой среде - реестр ли Windows (посмотрите внимательно видео в районе 2:28, где видно как устроено хранилище в реестре :) и сравните с упомянутым выше слайдом 11), флешка с файловой системой или токен используется. Работа с ключами происходит в приложении (криптопровайдере), а, следовательно, они туда передаются - поэтому они дампятся из трафика APDU.

Что же делать?
Да, как видите, недостаточно иметь токен, даже с отечественной криптографией на борту, надо еще иметь криптопровайдер, который для операций с ключом будет использовать не свои стеки и кучи, а бортовую криптографию токена, что прогарантирует выполнение вычислений с ключом внутри токена, что, в свою очередь, обеспечит отсутствие передачи ключа из токена, соответственно, его нельзя будет перехватить из трафика APDU.

Tuesday, July 7, 2015

Модульный подход к эксплуатационной документации

Как и обещал, излагаю свое предложение по организации эксплуатационной документации в части описания конфигурации, которое, на мой взгляд, позволяет сохранить необходимо высокий уровень детализации описания и, в то же время, сделать эту документацию удобной для поддержания в актуальном состоянии. Суть подхода очень проста: разделить на модули и в рамках каждого изменении выпускать новые версии затронутых изменением модулей. 
В презентации также содержится предложение по переходу на этот "революционный подход" со стандартного, соответствующего несколько подустаревшим и тяжелыми для использования на практике ГОСТами и СТР-К, заключающееся в организации надлежащего документирования изменений, в рамках которого старые эксплуатационные документы когда-нибудь будут заменены новыми, состоящими из взаимосвязанных модулей.

Wednesday, July 1, 2015

Детализация описания конфигурации

Достаточно часто приходится читать различную документацию на различные проектируемые/внедряемые/поддерживаемые системы. Хочется думать, что мне просто не везло, но постоянно попадается документация, которая ужасна, и причины я бы выделил две: а) проблемы у авторов с формальной логикой, б) непонимание цели разрабатываемого документа. Не берусь лечить проблемы с логикой, буду оптимистично надеяться, что эволюция это исправит, но постараюсь посражаться со второй причиной.

Сразу оговорюсь, что я здесь не буду цитировать какие-то ГОСТ-ы, ISO и т.п., а покажу минимальный набор документов, полезный с практической точки зрения и попытаюсь объяснить свое мнение. Касательно контента документов и их детализации, понятно, что все здесь примерно, возможны перекрытия и углубления в детали, однако я пишу о минимальных потребностях, чтобы вся эта история с проектами вообще работала, понятно, что если где-то будет больше конкретики, чем необходимо - это, скорее, не повредит, и ничего страшного, если будут повторы (хотя копи-пейста, из документа в документ, конечно же, надо избегать!)

Все начинается с того, что Бизнес хочет что-то автоматизировать (опустим тот факт, что необходимость этой автоматизации ему долго доказывали ИТшники - это тема отдельного поста). Свое желание он излагает в Функциональных и технических требованиях (ФТТ). Основными особенностями этого документа являются следующие:
- написан на бизнес-языке;
- объясняется бизнес-процесс, что в нем плохо и что надо улучшить;
- предъявляются требования к результату;
- степень детализации - небольшая, но достаточная, чтобы с точки зрения бизнеса понять что же должно получиться в итоге;
- ФТТ обычно пишет Заказчик, все остальные - Подрядчик.
При разработки ФТТ нужно понимать, что этот документ будет использоваться Подрядчиком для оценки трудозатрат, поэтому Заказчику нужно приложить все усилия, чтобы детализация ФТТ была достаточной для этого - ошибочные оценки трудоемкости как в меньшую, так и в большую сторону отразятся проблемами на Заказчике, а кому нужны лишние проблемы?

Пришел Подрядчик, и уже в рамках проекта на основании потребности, изложенной в ФТТ, он разрабатывает Техническое задание (ТЗ). В целом, под ТЗ нормально понимать детализированное ФТТ, поэтому особенности следующие:
- более технический документ;
- определяет уже из чего будет делаться целевая Система (исходные материалы);
- скорее всего (так и надо делать - это правильная практика!), было проведено какое-то обследование (~понимание среды/условий, уточнение требований из ФТТ), поэтому помимо требований к результату указываются требования к проектированию, причем уже с учетом выбранных исходных материалов;
- степень детализации - максимально возможная - результат и важные моменты в рамках проектирования должны быть учтены до мельчайших потребностей.
Важно: Поскольку ТЗ полностью определяет что должно получиться в результате, а, при грамотном подходе (со стороны Подрядчика), может определить и ключевые моменты проектирования, чтобы не иметь проблем с возможными изменениями потребностей Заказчика по ходу проекта (ведущим к изменению объема) - проектирование следует начинать только после полного согласования ТЗ.


ТЗ является исходным материалом для процесса проектирования, в рамках которого разрабатывается Технический проект (ТПр). ТПр:
- полностью технический документ;
- определяет КАК мы будем делать нашу Систему из выбранных исходных материалов;
- степень детализации ТПр должна быть достаточной для того, чтобы превратить исходные материалы в Систему, полностью соответствующую ТЗ и ФТТ; Фактически под ТПр можно понимать детальный план такого приведения - действительно сначала дешевле поупражняться "на бумаге", а уже потом, все 7 раз отмерив, пойти работать ручищами "на железе".
Будучи результатом раздумий "на бумаге" ТПр - это то, "что хотели" получить. Еще важно, что ТПр - во всех подробностях описывает процесс перевода исходных материалов в желаемую Систему.

Закончив проектирование и написав максимально подробный ТПр можно переходить к разворачиванию\внедрению\настройке Системы, т.е. превращению исходных материалов в нашу Систему, соответствующую ТЗ и ФТТ уже в полях.

Если вы - мудрый гений или данный проект для вас далеко не первое упражнение то ваша пусконаладка пройдет в полном соответствии с ТПр, но, к сожалению (а может и к счастью, ибо без приключений наша жизнь скучна) по ходу могут возникать особенности, поэтому, вполне возможно, что получится не совсем то, что планировалось. Ну, конечно, не так, ибо по-любому надо соответствовать ФТТ и ТЗ, но что касается требований к реализации проекта, частенько "все не так на этот раз...".

Поэтому, помимо Проектной документации, которую можно заканчивать на ТПр, есть еще и эксплуатационная, которая описывать "что в итоге получилось" и как это поддерживать\обслуживать\сопровождать. Важными особенностями эксплуатационной документации являются:
- она динамична, т.е. в процессе своего жизненного цикла Система изменяется, - должна изменяться и эксплуатационная документация, чтобы всегда соответствовать актуальной конфигурации. На практике лучше апдейт необходимых разделов документации производить в рамках процесса управления изменениями (как можно организовать документацию, чтобы ее удобнее и дешевле было апдейтить я как-нибудь напишу);
- она не описывает процесс, она характеризует результат, т.е. Систему.

Как правило, в эксплуатационной документации полезно иметь следующие документы:
- Технический паспорт (ТПс);
- Инструкция пользователя (ИП);
- Инструкция администратора (ИА) - если администраторов несколько может быть несколько ИА для всех возможных групп сопровождения, можно и совместить все эти инструкции в одном документе - тут как удобнее организовать использование этих документов;
- Регламент обеспечения непрерывности бизнеса (РОНБ или BCP-DRP).

ТПс содержит полное техническое описание Системы. Его детализация должна быть достаточной для выполнения всего комплекса работ по сопровождению от планового сервисного обслуживания до "мелкого ремонта" и устранения инцидентов.

ИП - понятно, наглядный документ (кстати, совсем не обязательно, чтобы это была бумага (хотя ее наличие не повредит!) - это может быть совокупность видео-роликов на типовые задачи (не больше 3-х минут, опыт показывает - это около предела терпения), набор красивых презентаций (мы красочное воспринимаем\усваиваем лучше) и любая другая форма, удобная для пользователя ), рассчитанный на потенциального потребителя сервисов Системы, с детализацией, достаточной для использования этих сервисов.

ИА, помимо всего прочего, должна содержать описание всех плановых сервисных работ, полезно включать информацию по трабшутингу и решениям типовых ситуаций. Дальновидные руководители обяжут своих админов актуализировать раздел по траблшутингу в рамках процессов "Lessons learned" после каждого инцидента, что позволит ИА превратить в некую элементарную базу знаний для грядущих поколений админов, а также снизить зависимость от конкретных исполнителей.

РОНБ должен содержать подробненькое описание процедур восстановления из резервных копий и всяческих других применяемых механизмов обеспечения непрерывности. Из РОНБ должно быть однозначно понятно к каким типам несчастья мы (вся группа эксплуатации) готовы и что в этих случаях мы делаем применительно к нашей системы.
На заметку: при приемка подобного документа полезно проводить упражнение по полной симуляции наиболее страшного несчастья - "... а ну-ка давайте грохнем файлы данных БД из-под СУБД и попросим наших админов восстановиться по вашей эксплуатационной документации в заявленные вами 3 часа..." - всегда лучше поупражняться сейчас, почти еще в проекте, чем потом, когда беда придет "на боевом дежурстве".
Еще: если сервис супер-критечен и его падение смерти подобно, то полезно не только заниматься тренировкой админов, но и пользователей (вообще, конечно, BCP-DRP тема обширная и даже не отдельного поста, а целой книги (!), тем более не рассказать ее в абзаце). Например, если у вас есть трейдеры которые должны постоянно торговать вашими продуктами на всяких биржах через Интернет, можно подумать о том, что на период недоступности нужной им ИТ-инфраструктуры их можно отправить домой с ноутом и быстрым мобильным Интернетом или посадить в автобус с теми же ноутами и хорошим wi-fi-ем в салоне и прочими минимальными ИТ-сервисами, и увезти туда, где пока еще спокойно и откуда можно продолжать крутить колеса корпорации (причем, куда везти также должно быть хорошо продумано заранее, чтобы минимизировать необходимость придумывания решения по ходу).
Да, еще момент, можно, в принципе, размазывать РОНБ по инструкциям администраторов и пользователей, но, я вас уверяю, лучше, чтобы в час Х все было под рукой, в одном месте, причем, наличие единого Плана придумали задолго до этого поста (возьмите любой гайд для подготовки, например, к CISSP).

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

И последнее - простой пример.
ФТТ: Бизнес: "Нужна деревянная кукла!"
ТЗ: мы должны получить Буратино из сосны, он должен передвигаться, издавать звуки, "думать", в меру возможности.
ТПр: идем в лес, находим говорящую сосну, вырубаем из нее полено, несем в столяную мастерскую, обрабатываем топором, рубанком, наждаком.... рисуем лицо и все остальное... одеваем на "голову" носок.... отдаем в школу....
ТПс: Буратино, сделан из говорящей сосны, полные ТТХ и т.п.
ИП: играть на шарманке, подпевать....
ИА: царапины зачищать наждаком, глубокие - рубанком, сколы красить, подрисовывать лицо по мере истирания, кормить луком раз в месяц....
РОНБ: утерянные конечности восстанавливаются так-то с использованием остатков говорящей сосны, в случае тяжелых потерь - есть 17 братьев-близнецов, полностью обученных и упакованных аналогичным образом, приводимых в рабочее состояние так-то...