
Привет, Хабр! На связи снова Иван Глинкин, руководитель группы аппаратных исследований из команды Бастиона.
«Флешка с кодовым замком», «флешка с аппаратным шифрованием», «зашифрованный USB-накопитель», наконец, эталонное название — «криптографический модуль» (Cryptographic Module). У криптофлешки aka encrypted USB много имен, но суть от этого не меняется.
Задача такого устройства — защитить чувствительную информацию от несанкционированного доступа на программно-аппаратном уровне: при помощи шифрования, механизмов антивскрытия и прочих «семи печатей». Однако так ли надежны эти защищенные USB-накопители, как принято считать, или это всё от лукавого?
Мы решили не доверять маркетинговым заявлениям и провели собственное исследование: попытались взломать несколько таких устройств методами аппаратного реверс-инжиниринга. Попробовали извлечь данные, определить применяемые типы шифрования, вскрыть криптофлешки и прочитать чипы памяти.
Результаты получились интересными. Подробности — под катом.
Разбираемся в стандартах
Прежде чем «хвататься за скальпель» и препарировать флешки, обратимся к теории и стандартам. Иначе как мы поймем, соответствует ли реальный уровень защиты устройств регламентным характеристикам?
В России действует общий стандарт, одно наименование которого тянет на шифровку: ГОСТ Р 54583-2011/ISO/IEC/TR 15443- 3:2007.
ГОСТ устанавливает методологию анализа и обоснования соответствия системы защиты информации требованиям безопасности. Однако российский стандарт не касается непосредственно криптофлешек, так что здесь все довольно туманно.
Зато в международной практике в этом плане больше конкретики. Стандарт NIST FIPS PUB 140 описывает принципы работы и защитные механизмы криптофлешки. В настоящее время действует ревизия документа 140-3.
Сам стандарт краткий и мало чем нам поможет. Другое дело — разработанное в рамках NIST FIPS PUB 140 «Руководство по внедрению» в 218 страниц убористого англоязычного текста.
Верхнеуровнево стандарт описывает 4 уровня защиты криптографических модулей (security levels):
Уровень защиты | Меры защиты | Ключи и SSP (sensitive security parameters) | Примеры устройств |
Level 1 (базовая) | Обычный корпус без специальных tamper-механизмов. Только программная/логическая защита | Могут храниться в памяти без дополнительных защит | Программные токены, обычные USB-флешки с шифрованием на ПО |
Level 2 (умеренная) | Tamper-evident наклейки/корпус, простая физическая защита, базовая аутентификация | Ключи защищены, но возможен ограниченный физический доступ к ним | Смарт-карты с базовой защитой от вскрытия, USB-токены среднего класса |
Level 3 (высокая) | Корпус с защитой от вскрытия, авто-стирание ключей при попытке вмешательства. Защита от побочных каналов связи (например, анализа энергопотребления) | Ключи недоступны извне даже при прямом физическом доступе | HSM, защищенные токены/флеш-накопители, корпоративные криптоключи |
Level 4 (максимальная) | Полная активная защита от вскрытия, устойчивость к экстремальным условиям (температура, влажность), активная защита от всех известных побочных каналов связи | Автоматическая нулевая защита ключей при попытках вмешательства (ключи стираются сразу же при попытке проникновения) | Военные/государственные HSM, модули для критически важных систем |
От теории к практике
Со стандартами и требованиями в общ��х чертах разобрались — самое время приступить к нашему исследованию. Для начала мы заглянули в прошлое и посмотрели, чего удалось добиться нашим коллегам, которые уже «ломали» защищенные USB-накопители. Как показал «исторический экскурс», возможно применение нескольких векторов атаки.
В некоторых случаях при физическом разборе флешки внутри оказывалась SD/microSD-карта, которая легко вынималась и вставлялась в картридер. При этом записанная на карте информация была в открытом виде.
Аппаратный пароль представлял защиту исключительно в виде подачи питания. Пароль верный — тумблер подачи электричества замыкался, неверный — получите 0 вольт. Коллеги-исследователи делали мост и подавали энергию в обход управляющего модуля, запитывая карту памяти.
В 2017 году команда исследователей из Google протестировала целый ряд таких защищенных флешек и нашла всего несколько уязвимостей. А что, если нам повезет больше? Мы закупили несколько криптофлешек на любой вкус, цвет и кошелек и начали собственное тестирование.
Дисклеймер: в силу юридических ограничений все упоминания российских брендов в статье обезличены, а их логотипы — скрыты.
«Пациент 1»: российская криптофлешка за 4 тысячи рублей

Первой на очереди стояла бюджетная отечественная флешка c 32 гигабайтами памяти. Для начала изучим инструкцию и как следует рассмотрим устройство.

Первичный осмотр
Флешка выполнена в металлическом, приятном на ощупь корпусе. Кнопки прорезинены и нажимаются легко. Динамик достаточно громкий, а звуковой сигнал, как и положено, режет слух.
Теперь снимаем колпачок и …

Как и сказано в инструкции, нажимаем кнопку включения и вводим пин-код (по дефолту 1122334). Потом жмем на кнопку замка — и флешка работает.
А что же с безопасностью? Цитируем инструкцию дословно:
«После десятикратного неверного ввода PIN-кода флеш-накопитель будет сброшен до заводских настроек. Данные при этом полностью стираются, а PIN-код — сбрасывается до заводского (1122334)».
Оригинал:
"After 10 times incorrect input, flash drive will be reset to factory settings. Data will be erased completely and PIN will be initiated (initial PIN1122334)".
О том, что данные будут стерты после десяти неудачных попыток ввода PIN-кода, нам дополнительно напоминают в следующей главе инструкции «Уведомления». Правда, замеры скорости полного уничтожения данных на дисках, которыми мы делились в предыдущей статье, заставляют в этом серьезно усомниться. Так что запомним это предупреждение и вернемся к нему позже.
Инициализация и первые попытки восстановить файлы
И снова повременим с «хирургическим вмешательством»: сперва проверим программную часть. Для этого вводим дефолтный пароль, активируем флешку и заходим внутрь.

Для исследования я подготовил ряд файлов, которые мы запишем на флеш, а потом попытаемся восстановить ☺ Не забудем и про контрольные суммы целостности, чтобы не сомневаться в полученном результате.


Записываем данные и рестартим флешку, 10 раз подряд введя неправильный пин-код. Не забываем отформатировать ее заголовок в FAT32 (всё по инструкции от производителя, иначе не определится в системе).

Далее действуем по стандартному сценарию: запускаем PhotoRec от TestDisk и пробуем найти какие-нибудь данные.

Первый улов оказался скудным: 1 файл Shockwave Flash на 2 гигабайта. Судя по моему прошлому опыту восстановления данных с шифрованного LUKS2 диска, это был false positive — софт увидел файл, который мы вообще не записывали на носитель.
Здесь я вспомнил совет моего бывшего руководителя: «Ты не рассуждай. Ты сначала сделай, а потом будешь рассуждать!». И вправду, почему бы не провести пару базовых тестов на принадлежность?
Сначала вычисляем хэш-сумму восстановленного файла и сравниваем с хэшами исходных тестовых файлов: мимо, что вполне ожидаемо.

Окей, попробуем по-другому и извлечем читаемые символы через strings.

Теперь попытаемся найти что-то похожее в наших тестируемых файлах.

И снова попали в молоко. Тут мне в голову пришла одна сумасшедшая идея насчет того, какой сценарий атаки попробовать (спасибо большое за помощь моему коллеге Алексею Трофимову — главному специалисту группы по анализу защищенности мобильных и веб-приложений Бастиона).
Повторение — мать учения
Вспомнив поговорку «Пушкин — наше всё», я скачал собрание сочинений классика и переложил в обычный текстовый файл, который по счастливой случайности весил аккурат 1 мегабайт. Выбрал формат ТХТ, потому что он одинаково выглядит как в приложениях, так и в «сырых» данных.

Скопировал этот файл на флешку и забил ее копиями до предела.

Интересный факт: на флешку записалось всего 16 383 файла, то есть около 16 гигабайт. Но где же вторая половина? cp говорит, что места не осталось, а в проводнике указано еще 13,5 свободных гига.
К слову, Винда рапортует нам то же самое.

Если же записать на флешку 7–8 файлов по 4 гига в среднем, то заполнится всё пространство целиком. То есть количество записанных на флеш файлов не должно превышать 16 тысяч. Как оказалось, это ограничение формата FAT32 — к слову, с exFAT таких проблем нет.
Снова рестартим флешку через 10 неправильных пин-кодов и пытаемся восстановить данные — и опять ничего.

Неужели из 16 тысяч файлов ни один не восстановился?
А что у нас в исходниках?

Что-то есть, но, в основном, это бессвязные наборы символов.
На всякий случай снова попытаемся прогнать флешку через strings.

На этот раз получилось множественное повторение одного и того же текста. А вот с этим уже можно работать. Но не будем сильно забегать вперед.
Я не делал snapshot «пушкинской» флешки перед рестартом, так что снова перезапускаем защищенный USB-накопитель через 10 неправильных пин-кодов и записываем туда тот же файл с собранием сочинений Александра Сергеевича. Получаем те же 16 383 файла копий и оригинал.

После этого делаем полный snapshot флешки через команду dd:
sudo dd if=/dev/sda of=pushkin_full.imgДалее опять перезапускаем флешку через 10 неправильных пин-кодов. Чтобы ничего не потерять и ускорить работу, также снимаем snapshot флешки — pushkin_full_recrypt.img.
И еще раз пытаемся найти повторения.

Бинго! Все 16 384 файла на месте, хотя и превратились в какие-то иероглифы.

Выявляем метод шифрования
Итак, есть повторяющиеся участки и их адреса хранения. Нужно сравнить это с исходным незашифрованным вариантом.
К сожалению, русский текст в исходниках в формате UTF8 отображался как точки. Поэтому находим латиницу и сверяемся по ней.


Файлы и вправду на месте.
Что это может значить, и какой алгоритм шифрования тут используется?
Еще раз взвесим факты. У нас есть, как минимум, 3 (а всего 16 384) разных участка исходного файла (разные смещения), которые после шифрования превратились в иероглифы, но остались идентичны друг другу: cipher(offset_1) = cipher(offset_2) = cipher(offset_3).
Соответственно, потоковый шифр (ChaCha20, RC4) сразу исключается, поскольку в нем используется непрерывный key stream, и при шифровании одного и тот же текста в разных местах файла ciphertext будет отличаться.
AES-CTR/GCM/XTS тоже отпадает. Эти алгоритмы используют счетчик/nonce, который гарантирует различные блоки на разных смещениях.
Метод исключения указывает на блочный шифр в режиме ECB (AES-ECB или любая другая ECB-схема): одинаковые plaintext-блоки → одинаковые ciphertext-блоки; никакого IV, nonce, счетчика; чистая блочная замена. Выходит, перед нами AES-256 в режиме ECB, с 32-байтным ключом.
Если ключ создается «по фэн-шую» и представляет собой случайные 256 бит, то извлечь его из пары (plaintext → ciphertext) практически невозможно (AES защищен от известных текстов). Но на практике ключ часто получается из пароля или плохо защищенной процедуры — тогда его можно подобрать перебором, по словарю или проверив гипотезы о KDF. Правда, наши попытки сбрутить флешку результатов не принесли: в этом плане устройство оказалось крепким орешком.
Восстанавливаем данные
Шифрование в формате AES-256 в режиме ECB уязвимо и позволяет восстановить файлы.
Для этого попробуем нарисовать абстракцию в стиле Малевича и Кандинского: создадим несколько большеразмерных рисунков в формате BMP с белым фоном и тремя разноцветными геометрическими фигурами. Как видно на скриншоте ниже, весит наша картинка 21,5 мегабайта.


Далее запишем первые 100 мегабайт на флешке нулями простой командой, чтобы наверняка отделить наши полезные файлы от мусора:
sudo dd if=/dev/zero of=/dev/sda bs=1M count=100Проверим, что всё прошло успешно, командой hexdump -C /dev/sda | head.
Как можно видеть, разделы флешки с 00000000 до 06400000 полностью забиты нулями.

Далее будем записывать наши файлы после 100 мегабайт нулей по очереди. Чтобы отделить файлы друг от друга, поместим между ними 1 мегабайт нулей. Делать это вручную — всё равно что рыть канал чайной ложкой. Лучше напишем баш-скрипт:
#!/bin/bash
DEVICE="/dev/sda"
offset=100 # стартовое смещение в MB
files=(
"1.bmp"
"1.png"
"secret72_1.bmp"
"secret72_1.png"
"secret72_2.bmp"
"secret72_2.png"
)
# --- Запись файлов ---
for f in "${files[@]}"; do
echo "Пишу 1 МБ нулей перед $f"
sudo dd if=/dev/zero of="$DEVICE" bs=1M seek=$offset count=1 conv=notrunc
offset=$((offset+1))
size_mb=$(du -m "$f" | cut -f1)
echo "Пишу файл $f, размер $size_mb MB"
sudo dd if="$f" of="$DEVICE" bs=1M seek=$offset conv=notrunc
offset=$((offset+size_mb))
done
# --- Запись нулей до конца диска ---
echo "Записываю нули до конца диска, начиная с offset ${offset} MB"
sudo dd if=/dev/zero of="$DEVICE" bs=1M seek=$offset conv=notrunc
echo "Готово."Запускаем код:

Теоретически всё в порядке — файлы записались, и со 199 мегабайт до конца пишем нули. Давайте проверим в исходниках:

Пока все выглядит как и задумано.
Теперь выгрузим первые 250 мегабайт нашей флешки в отдельный файл, чтобы можно было анализировать его после сброса пароля:
sudo dd if=/dev/sda of=clean_first_250MB.bin bs=1M count=250 status=progress
Вроде бы по пути ничего не потеряли.
Затем в очередной раз сбросим флешку в стандартные настройки путем десятикратного ввода неправильного PIN-кода. Флешка пропищала, а это значит, что все данные «удалены» и PIN-код сброшен в исходное состояние. Вводим заводскую комбинацию (1122334), вставляем флеш и читаем исходники:

И снова получаем «абракадабру». Однако здесь повторяющийся текст дублируется как нужно, то есть по аналогии с незашифрованным.
Выгружаем те же 250 мегабайт:
sudo dd if=/dev/sda of=crypted_first_250MB.bin bs=1M count=250 status=progress
Файлы нужно аккуратно достать с флешки, не потеряв ни единого байта. Что же, не проблема, ведь у нас есть оригиналы файлов и их размеры. Упростим себе задачу и напишем еще один баш-скрипт:
#!/bin/bash
DEVICE="crypted_first_250MB.bin"
offset=100 # стартовое смещение в MB
files=(
"1.bmp"
"1.png"
"secret72_1.bmp"
"secret72_1.png"
"secret72_2.bmp"
"secret72_2.png"
)
echo "Восстановление файлов с устройства $DEVICE"
for f in "${files[@]}"; do
offset=$((offset+1)) # пропускаем 1 МБ нулей перед файлом
size_mb=$(du -m "$f" | cut -f1)
echo "Извлекаю $f: offset=${offset} MB, size=${size_mb} MB"
sudo dd if="$DEVICE" of="restored_$f" bs=1M skip=$offset count=$size_mb status=progress
offset=$((offset+size_mb))
done
echo "Готово. Файлы восстановлены с префиксом restored_."Запускаем скрипт:

Файлы восстановлены, однако мы не можем их посмотреть. Давайте откроем их в исходниках через hexedit и посмотрим, что может быть не так.

Понятно, почему мы изначально не могли посмотреть рисунок: в заголовке вместо формата файла указано что-то странное. Поменяем заголовок нашего восстановленного файла на BMP.

Наконец, попробуем открыть восстановленный файл.

Потрясающе, мы восстановили нашу «абстракцию»! Даже некоторые цвета соответствуют оригиналу. А что, если взять другой восстановленный файл, который предположительно содержит текст?

И снова все восстановилось.
Здесь мы приходим к первому важному выводу: производитель лукавит, будто при рестарте флешки данные удаляются. На самом деле, они остаются на месте — просто меняется ключ шифрования. Как показывает наше исследование, данные можно частично восстановить.
К слову, эту уязвимость можно оформить как CVE. Так, флешка Verbatim имела схожий небезопасный дизайн, и исследователи из Германии успешно зарегистрировали CVE в международной базе NIST. Мы не стали скромничать и решили сделать то же самое по итогам своего исследования.
Возвращаясь к нашим изысканиям с «абстракциями», мы действовали в лабораторных условиях, зная, что и где искать. А что, если бы всё происходило в «дикой природе»? Вызов принят: давайте попробуем написать программу-анализатор.
Берем все тот же любимый мною баш-скрипт и напишем такой код:
#!/usr/bin/env bash
set -e
DUMP="$1"
shift
if [[ -z "$DUMP" || ! -f "$DUMP" ]]; then
echo "Использование: $0 dump.bin [width1 width2 ...]"
exit 1
fi
DUMP_SIZE=$(stat -c%s "$DUMP")
MAX_CHUNK=$((20*1024*1024)) # 20 MB
WIDTHS=("$@")
[[ ${#WIDTHS[@]} -eq 0 ]] && WIDTHS=(640 760 1000 1024 1500 2000 2480 3000 3328)
# little-endian helpers
le16() {
printf "%04x" "$1" | tac -rs .. | xxd -r -p
}
le32() {
printf "%08x" "$1" | tac -rs .. | xxd -r -p
}
for WIDTH in "${WIDTHS[@]}"; do
BYTES_PER_PIXEL=3
ROW_RAW_SIZE=$((WIDTH * BYTES_PER_PIXEL))
ROW_PAD=$(( (4 - (ROW_RAW_SIZE % 4)) % 4 ))
ROW_SIZE=$((ROW_RAW_SIZE + ROW_PAD))
echo "[*] WIDTH = $WIDTH"
OFFSET_BYTES=0
PART=1
while [[ $OFFSET_BYTES -lt $DUMP_SIZE ]]; do
MAX_ROWS=$((MAX_CHUNK / ROW_SIZE))
REMAIN_BYTES=$((DUMP_SIZE - OFFSET_BYTES))
REMAIN_ROWS=$((REMAIN_BYTES / ROW_SIZE))
HEIGHT=$(( REMAIN_ROWS < MAX_ROWS ? REMAIN_ROWS : MAX_ROWS ))
[[ $HEIGHT -le 0 ]] && break
IMAGE_SIZE=$((ROW_SIZE * HEIGHT))
FILE_SIZE=$((54 + IMAGE_SIZE))
OUT="out_${WIDTH}px_part${PART}.bmp"
echo " -> $OUT (${WIDTH}x${HEIGHT})"
SKIP_BLOCKS=$((OFFSET_BYTES / ROW_SIZE))
{
# BITMAPFILEHEADER
printf "BM"
le32 "$FILE_SIZE"
le16 0
le16 0
le32 54
# BITMAPINFOHEADER
le32 40
le32 "$WIDTH"
le32 "$HEIGHT"
le16 1
le16 24
le32 0
le32 "$IMAGE_SIZE"
le32 2835
le32 2835
le32 0
le32 0
# PIXELS
dd if="$DUMP" bs="$ROW_SIZE" skip="$SKIP_BLOCKS" count="$HEIGHT" status=none
} > "$OUT"
OFFSET_BYTES=$((OFFSET_BYTES + HEIGHT * ROW_SIZE))
PART=$((PART + 1))
done
doneОпишем подробнее принцип работы скрипта. Мы передаем в качестве аргумента шифрованную область (файл может быть как бинарником, так и /dev/sda). Скрипт разбивает его на равные части по 20 мегабайт, затем меняет заголовок получившихся кусков на заголовок BMP, а также указывает в нем ширину картинки (по дефолту поставил 640 760 1000 1024 1500 2000 2480 3000 3328) и сохраняет.
После грубого поиска ширины можно ввести точное значение, указав шифрованную область.
Далее запустим на ранее подготовленную область:


Отлично, файлы сгенерированы и сохранены. Переходим к самой трудной задаче —просмотру всех файлов (если бы мы говорили про реальные 100+ гигабайтные диски, это был бы тот еще квест).

Вот и первый улов. В части 8 (160–180 мегабайт после начала диска) файла шириной в 2480 пикселей проглядываются слова и цифры. Значит, мы нашли плюс-минус нужную ширину: будем пытаться поймать верную, и наш скрипт это позволяет.


Вот и еще одна находка: часть 6 (120–140 мегабайт после начала диска) файла шириной в 3328 пикселей.

Словом, и в «дикой природе» у исследуемой криптофлешки нет шансов против такой атаки. Да, в реальности приходится потратить больше времени на написание программ-анализаторов, но данные в итоге можно восстановить.
Если есть желание самостоятельно попробовать, как это работает, вот ссылка на файлы.
Препарируем устройство
Итак, «терапевтический осмотр» закончен, и пришло время для «хирургического вмешательства». Для начала откручиваем болты и вскрываем крышку.

Отвинчиваем еще 3 болта и полностью отделяем плату от корпуса.

Что у нас тут? Аккумулятор для поддержания работы, управляющий модуль, чип памяти, небольшая обвязка и динамик. Бросается в глаза отсутствие антитамперов (защиты от вскрытия). При этом, как показала проверка, флешка работает даже во вскрытом состоянии.
Изучаем чипы
Управляющий чип — i560-N200C — представляет собой SOC (System on Chip), то есть мини-компьютер с процессором, оперативкой и рядом других «плюшек», включая шифрование. Даташит на него сообщает, какие технологии шифрования поддерживаются:


В списке встречаем нашего «старого знакомого» — AES256 в режиме ECB. Встает вопрос: если чип поддерживает более сильные режимы шифрования, почему производитель не применил их? Ну да ладно, идем дальше.
На чипе есть UART, JTAG и другие отладчики, но первый выведен в отдельные пятаки на плате, что не может не радовать. Не откладывая в долгий ящик, достаем PCBite Probes и подключаемся к UART.


Запускаем Logic 2 и начинаем взаимодействовать с флешкой.

Устанавливаем стандартный baud rate 115200. При включении выводится лог, что флешка eMMC на месте. Вводим правильный пароль — получаем загадочное сообщение pressed fun; набираем неправильный — получаем вывод password error: 2. К сожалению, более детальной информации UART не предоставляет.
Я протестировал отключение электропитания после ввода нескольких неправильных паролей. Оказалось, что количество таких неудачных попыток хранится в энергонезависимой памяти. Если отключить аккумулятор, подождать пару минут (на случай, чтобы все кондеры разрядились) и снова включить, то обратный отсчет продолжится. Поэтому здесь за реализацию защиты ставим производителю «+».
Теперь взглянем на чип памяти. Это BGA153 чип от MMY G1DH07DA-301 на 32 гигабайта.


Тут ничего необычного и заслуживающего особого внимания.
Меняем «мозги»
По одной из методологий атак на флешки, нужно сменить управляющий чип на другой, из той же партии, чтобы получить доступ. Что же, попробуем. Тем более, у нас есть вторая аналогичная флешка в запасе.
Запишем разные данные/файлы и поставим разные аппаратные пароли на каждый USB-носитель. Затем попробуем поменять местами чипы SOC в надежде, что данные прочитаются. Да, шансы на успех такой атаки невелики, однако желание паять сильнее сухой теории.
Для начала обернем наши флешки термоскотчем, чтобы ненароком ничего не расплавить и не сдуть паяльным феном.

Далее отпаиваем SOC от обеих флешек.


Меняем чипы местами и припаиваем к платам.
А вот и первое недоразумение: я совсем забыл про пластиковые кнопки на обратной стороне платы, и они немного оплавились — не спас даже термоскотч. Впрочем, нам нужен не товарный вид, а информация…


Барабанная дробь! Запускаем первую флешку, вводим пароль от второй, и … аппаратный пароль подошел! Значит, он действительно хранится на SOC. Вставляем USB-накопитель в компьютер...
Компьютер определил флешку как /dev/sda, но не увидел ее файловую систему. Прохождение стрингами дало «абракадабру», что и следовало ожидать.
В общем, в результате этой атаки мы получили аналог рестарта путем ввода неправильного пароля 10 раз. Но на всякий случай я снял полный дамп через dd для дальнейших исследований.
Последний тест
Наш «пациент №1» уже препарирован вдоль и поперек — оставалось только выпаять флешку и попробовать снять с нее данные напрямую. Кто-то спросит: зачем такие отчаянные меры? Дело в том, что криптофлешка работает по принципу «не введен аппаратный пароль — компьютер не видит устройство». При этом SOC действует как тумблер: пароль верный — данные проходят, неверный — не взыщите.
Еще данные могут храниться на чипе не в том виде, в каком они отображаются в strings (возможно, вообще в открытом виде). Поэтому такой вектор тоже нельзя игнорировать.
За дело! Выпаиваем флеш-память с платы.

Как уже упоминалось, здесь используется форм-фактор BGA153.
Пришло время пустить в ход адаптер к XGecu, но в моем арсенале нужного не оказалось.

Пришлось пойти на китайский маркетплейс и выложить 4 тыс. рублей за адаптер.

Только вот оказалось, что у XGecu нет официальной поддержки данного чипа. Зато в адаптере есть универсальный считыватель — Auto EMMC. Что же, ухватимся за эту соломинку.

Итак, адаптер наконец доставили, и настал момент истины… Но нет, попытка снять данные напрямую с флеш-памяти провалилась — данные зашифрованы. Так что здесь тоже ставим устройству «+».
«Пациент 2»: отечественная флешка за 15 тысяч рублей
Следующей на очереди стала флешка от другого российского производителя радиоэлектроники — в этот раз на порядок более дорогая.

Первичный осмотр второго «пациента»
Флешка довольно увесистая и выполнена из добротного плотного материала: сам внешний вид устройства намекает на надежность и защищенность. А солидная картонная упаковка создает эффект дороговизны. Впрочем, криптофлешку покупают не ради коробки, так что перейдем к более важным моментам.

Этот USB-накопитель также поставляется с инструкцией. Вот только в комплекте с флешкой шел усеченный мануал — для доступа к полному требовалось отсканировать QR-код. Видимо, производитель таким образом проявляет заботу об экологии (ну или или просто экономит на бумаге).


Инициализация и попытки восстановить файлы
Начинаем с инициализации. Вводим код, вставляем флешку — система ничего не видит. Окей, быстро форматируем устройство в NTFS и проверяем.

Да, флешка инициализирована. Сперва проверим, на завалялись ли на носителе какие-нибудь забытые файлы.

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

Теперь перезапускаем флешку и смотрим, что получилось.


Перед нами вновь то самое небезопасное шифрование AES-256-ECB. Не стану описывать всю дальнейшую процедуру, так как она подробно описана на примере предыдущей флешки. Скажу только, что данные были успешно восстановлены.

Переходим к аппаратной части
На первый взгляд могло показаться, что наш «пациент» обладает защитой от вскрытия: все части корпуса плотно прилегают друг к другу, не видно ни одного болта.

Но нет, «Сим-Сим» довольно легко открылся. Для этого я оперся широкой частью корпуса около USB-разъема о стол и немного надавил плоской отверткой на отверстие для держателя. Крышка корпуса гостеприимно съехала в сторону.

Осматриваем внутренности
Внутри меня ждали аккумулятор, SDCard (внезапно) и знакомый нам по предыдущему исполнению чип управления i560-N200C. Первым делом я вытащил флешку и проверил содержимое. Информация на SDCard была зашифрована.

Снимем силиконовые кнопки и посмотрим, что находится с другой стороны платы.

Неожиданно: там оказался один дополнительный чип, а на самой плате — еще 6 нераспаянных пинов (спойлер: они нам скоро понадобятся).
Для начала рассмотрим под микроскопом обнаруженную микросхему.

Это STC 8G2K64S4 — 8-битный микроконтроллер на базе быстрого ядра 8051, предназначенный для управления электроникой. Полное описание микросхемы, а также даташит на нее можно найти по ссылке.
Пытаемся прочитать чип
Изучив даташит и внимательно осмотрев схему, находим контакты UART и подключаем к ним логический анализатор с помощью PCBite Probes.

После запуска флешки на наш контакт RX поступают данные — частично читаемые, а частично закодированные. Как ни странно, расшифровались не все символы.

Чтобы ускорить процесс, я обратился за помощью к ИИ, но результат несколько удивил.

Опустим момент, что на российской флешке — информация на китайском языке. Больше всего здесь смущает последняя фраза: «версия с расширенным паролем / добавленным режимом пароля». Обычно это означает, в том числе, наличие мастер-пароля и режим администратора. Следовательно, производитель потенциально может зашить туда бэкдор со всеми вытекающими последствиями. Проверить это мы не смогли, поэтому наверняка утверждать не станем.
К сожалению, никакой другой информации через UART не проходит даже при подключении RS232-адаптера и вводах различных команд и комбинаций.
Однако в документации на устройство сказано, что для взаимодействия с микросхемой и ее перепрошивки нужно использовать специальное ПО — STC ISP Tool (находится парой запросов в поисковике).
Увы, и этот проблеск надежды быстро угас: установка и запуск программы тоже не дали никакой информации.

STC-загрузчик не предоставляет команд вроде «прочитай флеш», «прочитай EEPROM» или «дамп памяти». Он умеет только загружать новый код в микроконтроллер, считывать UID и параметры тактирования.
Однако в документации есть еще одна зацепка: несколько дополнительных контактов RX/TX. А что, если подключиться к ним?

И снова сюрприз. После включения флешки каждое нажатие на любую кнопку клавиатуры устройства начало давать отклик, причем всегда разный. Я так и не смог подобрать нужный baud rate и дополнительные параметры UART, чтобы все корректно прочитать. Для справки: общее время всего сигнала — 36,916 миллисекунды, минимальная длина сигнала — 2,75 миллисекунды.

Я собрал все комбинации клавиш (от 1 до 0) и представил их в формате программы Saleae Logic 2, который вы можете скачать по ссылке на Google-диск.
Интересное наблюдение: при нажатии на клавиатуре «1», «9» и «0» вместо однократной подачи сигнала происходит длительное повторение до тех пор, пока не отпустишь кнопку. Что касается «1» и «0», то данные комбинации прямо задокументированы в инструкции (смена основного пароля и смена пароля очистки данных). А вот про кнопку «9» каких-либо сведений в инструкции не было. Это опять же наталкивает на мысль о возможном мастер-пароле.
Вдобавок ко всему можно оставить кейлоггер — аппаратную закладку (места, конечно, мало, но при определенной сноровке такое возможно), куда и будет писаться пин-код.
«Пациент 3»: Kingston IronKey Keypad 200
Напоследок отвлечемся от российских устройств и проверим криптофлешку от именитого американского производителя Kingston Technology.

На упаковке заявлено соответствие знакомому нам стандарту FIPS 140-3, а также указан формат шифрования AES-256-XTS.

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

Пытаемся извлечь файлы
После инициализации подключаем флешку к порту USB, монтируем и смотрим, что лежит внутри.

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

Проверяем методы шифрования
Самое время проверить, действительно ли в устройстве применяется заявленное шифрование, а не уязвимый AES-256-ECB. В который раз берем наше собраний сочинений Пушкина и записываем его 5000 раз. Что же, «привычка свыше нам дана».

Далее действуем по устоявшемуся плану: рестарт в дефолтные настройки через 10 неудачных вводов, установка нового пароля и подключение.
На этот раз, на наше удивление, повторов не оказалось от слова «совсем».


По моей щеке едва не скатилась скупая мужская слеза: неужели хотя бы одно исследуемое устройство обладает надежной (или хотя бы не дырявой) защитой?
К сожалению, стопроцентно удостовериться в том, что на флешке применяется AES-256-XTS, невозможно с одной лишь «абракадаброй» hexdump’а на руках. Шифротекст AES-XTS (как и любого современного корректно реализованного шифра) выглядит как криптографически случайный шум, не имеет повторов, не содержит сигнатур, заголовков или «магических байтов». Он статистически не отличается от случайных данных.
Можно лишь проверить алгоритм по косвенным признакам, например, энтропии.

Здесь мы видим максимально возможную энтропию в 8.0 (и это на 15 гигах): такое значение с большой вероятностью указывает на AES-XTS. В свою очередь, Optimum compression составляет 0%, то есть данные несжимаемы, что также соответствует AES-XTS.
Другие показатели тоже косвенно подтверждают применение заявленного шифрования. Но ключевое слово здесь «косвенно».
Вскрываем устройство
Вскрытие устройства оказалось той еще головоломкой. В какой-то момент я даже подумал, что корпус склеен изнутри, и безрезультатно попытался «растопить» клей.

Деликатные меры не дали результата, и я переключился в «режим Халка». Первым делом я разломал пластик около порта USB, освободив, как минимум, одну сторону. Потом с небольшим усилием потянул за кольцо, и процесс сдвинулся с мертвой точки.

Защита от «рептилоидов»
К моему удивлению, все внутренности устройства были обернуты золотистой фольгой.

Здесь напрашивается сравнение с шапочками из фольги, которые якобы мешают пришельцам читать мысли людей. Только в нашем случае информацию защищают не от рептилоидов, а, согласно стандарту FIPS, от утечек по побочным/электромагнитным каналам связи. Фольга на плате должна минимизировать такие излучения.
Раздеваем флешку
Я аккуратно удалил фольгу… и снова удивленно развел руками. Вся плата была залита компаундом (не какая-то отдельная микросхема или чип памяти, а буквально вся). Вот оно, соблюдение требований регулятора на практике.

Ничего не поделаешь, продолжаем избавляться от защитного покрытия: главное — случайно не удалить вместе с компаундом часть SMD-компонентов. У меня не было под рукой азотной кислоты, так что пришлось действовать методом «физического брутфорса» — плоской отверткой.

Часть элементов все же отошла вместе с компаундом, однако флешка все равно продолжала работать (видимо, удалили «ненужные» понижающие/повышающие резисторы).

Изучаем чип
Чип памяти BGA тоже отделился от флешки — теперь не посмотришь, в каком виде хранятся данные в покое . А вот чип управления оказался более стойким: он все равно принимал корректный код и отделял правильный пин-код от неправильного.

Это PHISON PS2251-13-Q. Поиск по гуглу показал интересный результат. Как оказалось, исследователи Сергей Скоробогатов и Ольга Ларина в 2021 году уже препарировали линейку криптофлешэк Kingston со всех сторон и даже проводили ренгтеновское исследование.
Общий вывод того исследования: в целом эта линейка сильно защищена, но уязвима перед атаками NAND mirroring, когда выполняется копирование бит в бит всей флешки для оффлайн-брутфорса.
Выводы
Всего мы протестировали 5 устройств в широком ценовом диапазоне. В статье мы намеренно сосредоточились только на трех устройствах, так как многие флешки имеют схожие сильные и слабые стороны и будто сделаны под копирку. Ни одна из протестированных криптофлешек от российских производителей не может похвастаться надежной защитой. Все они используют морально устаревшее и небезопасное шифрование AES-256-ECB, а также одинаковый чип управления i560-N200C (который, к слову, поддерживает более сильные и стойкие методы шифрования).
Отечественные флешки не залиты эпоксидной смолой и не имеют механизма антивскрытия (anti-tampering). В некоторых устройствах даже стоит обычная SDCard вместо BGA-чипа, что позволяет ее демонтировать, сдампить всю память и установить обратно без видимых внешних признаков и логирования на чипах управления.
Хотя в большинстве протестированных устройств есть все необходимые базовые компоненты: металлический корпус и чип (пусть и китайский) с поддержкой AES-256-XTS, BGA NAND-чипы и прочее. Нужно лишь перенастроить управляющий i560-N200C на соответствующее шифрование, капнуть эпоксидкой, завернуть внутренности в фольгу и приварить корпус. Это не сильно повлияло бы на себестоимость устройства, зато в разы повысило бы безопасность.
«Зарубежные аналоги» тоже не лишены слабых мест, но все же выдерживают высокие стандарты безопасности не только на бумаге. Словом, за державу обидно.
Мой обзор не претендует на истину в последней инстанции. Например, я не исследовал i560-N200C, так как у меня не оказалось нужного адаптера для программатора. Если кто-то из читателей работал с таким чипом, пожалуйста, поделитесь в комментариях.
Навскидку приобретение таких устройств кажется бесполезной тратой денег. Дорогие флешки за 15–20 тысяч рублей не отличаются по формату и содержанию от устройств стоимостью в 2 тысячи рублей. Если нет разницы, зачем переплачивать за бренд?
P.S. Для совсем хардкорных экономщиков есть еще вот такой вариант за 200 рублей:

Если эта статья наберет 100 000 лайков — сделаем обзор на Хабре ☺
Еще ненавязчиво приглашаю всех в свой Telegram-канал, где вы найдете массу интересного по теме реверс-инжиниринга: http://t.me/glinkinivan

PURP — Telegram-канал, где кибербезопасность раскрывается с обеих сторон баррикад
t.me/purp_sec — инсайды и инсайты из мира этичного хакинга и бизнес-ориентированной защиты от специалистов Бастиона
