11.10.2016

Практический реверс-инжиниринг. Часть 3 – Исследование информационных потоков

image

Главный бонус, который мы получаем при работе с аппаратной частью, - полный доступ к системе bare metal и всем электрическим сигналам, на основе которых функционирует система.

Автор: Juan Carlos Jiménez

В первой части мы обнаружили дверь внутрь прошивки в виде отладочного UART-порта. Во второй части было проведено базовое исследование прошивки и получены некоторые данные.

Главный бонус, который мы получаем при работе с аппаратной частью, - полный доступ к системе bare metal и всем электрическим сигналам, на основе которых функционирует система. При наличии некоторых навыков и правильного оборудования можно получить любую интересующую нас информацию. Начиная от анализа трафика при помощи дешевого логического анализатора и заканчивая получением секретных ключей, используя дорогостоящее оборудование и измеряя мощность, потребляемую устройством, с нужной точностью (атака по сторонним каналам, связанная с анализом мощности; power analysis side channel attack). Если речь заходит о физических параметрах, важно работать в правильных условиях.

В этой статье мы поговорим об анализе трафика и способах получения информации при помощи этого метода.

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

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

Схема передачи данных в печатной плате

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


Рисунок 1: Информационные потоки на печатной плате

Мы не будем искать скрытых лазеек, а просто проанализируем данные, протекающие по шине SPI (Serial Peripheral Interface; последовательный периферийный интерфейс) между микросхемой Ralink и внешней флеш-памятью.
В большинстве случаев каждая микросхема имеет документацию, где описаны технические характеристики, начина от мощностей на выходных пинах и заканчивая коммуникационными протоколами. В поисковых системах можно найти огромное количество даташитов, включая те, которые имеют к нашему случаю непосредственное отношение:

Теперь, когда мы познакомились со схемой выходных пинов, электрическими характеристиками и протоколами, настала очередь извлечь нужную нам информацию.

Логика работы флеш-памяти

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


Рисунок 2: Назначение выходных пинов флеш-памяти
Обычно коммуникация по шине SPI затрагивает 4 пина:

  1. MISO (Master In Slave Out): Информационный канал Ralink<-Flash
  2. MOSI (Master Out Slave In): Информационный канал Ralink->Flash
  3. SCK (Clock Signal): Координирует процесс чтения из информационных каналов
  4. CS# (Chip Select): При логическом нуле подключает флеш-память. Соответственно, несколько микросхем могут разделять каналы MISO/MOSI/SCK.

После ознакомления с назначением пинов попробуем подключить логический анализатор и считать случайные данные:

Рисунок 3: Схема подключения логического анализатора
Для настройки логического анализатора необходимо выяснить некоторые настройки SPI:

  • Порядок байтов при передаче [По умолчанию: MSB First]
  • Количество битов за один акт передачи [По умолчанию: 8]. Выяснится при перехвате трафика
  • CPOL: Стандартный уровень сигнала синхронизирующей шины в неактивном состоянии [0 или 1]. Выяснится при перехвате трафика
  • CPHA: Фронт сихроимпульсов, инициирующий чтение данных в информационных каналах [0=ведущий, 1=ведомый]. Выяснится в процессе

В документации сказано, что микросхема флеш-памяти понимает только две комбинации CPOL и CPHA: (CPOL=0, CPHA=0) или (CPOL=1, CPHA=1):

Рисунок 4: Режимы работы SPI
Попробуем проанализировать первую порцию перехваченных данных:

Рисунок 5: Первая порция информации, перехваченная с шины SPI

Чтобы вникнуть в суть происходящего, необходимо ознакомиться с набором команд из даташита на микросхему FL064PIF:


Рисунок 6: Команды, используемые микросхемой FL064PIF

Теперь можно окончательно понять смысл перехваченной информации:


Рисунок 7: Разбивка по командам

В даташите указано, что микросхема FL064PIF обладает возможностями для высокопроизводительного чтения/записи, например, может разделять данные на несколько линий в целях увеличения скорости передачи. После ознакомления с порцией перехваченной информации, кажется, что роутер не использует эти функции в полной степени (если вообще использует). Однако о данной возможности не следует забывать в случае, если мы обнаружим нечто странное.
Режимы передачи, затрагивающие дополнительные пины, могут оказаться проблемой в случае, если ваш логический анализатор недостаточно мощный.

Почему важна частота дискретизации (теория)

С технической точки зрения логический анализатор устроен довольно просто. Устройство считывает сигнальные линии как цифровые входы каждые X микросекунд в течение Y секунд, и когда операция завершена, отсылает информацию на компьютер для анализа.

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

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

Я записывал данные с шины SPI между микросхемой Ralink и флеш-памятью при помощи бюджетного анализатора от компании Saleae. Максимальная частота дискретизации для данного набора линий передач - 24 MS/s (24 миллиона выборок в секунду):


Рисунок 8: Неравномерная длительность синхроимпульсов

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

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

Попробуем считать данные с той же самой шины, но при помощи более высокопроизводительного логического анализатора на скорости 100 MS/s:


Рисунок 9: Длительность синхроимпульсов при более высокой частоте дискретизации

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

Если вы видите искажения при перехвате трафика, придется либо смириться с потерей данных, либо вложиться в более дорогостоящее оборудование. 

Обзор информационных потоков

Мы уже познакомились логикой работы всей системы после того, как проанализировали прошивку во второй части. Теперь можно углубиться в детали передачи интересующей нас информации по шине SPI. Подключение осциллографа к пинам MISO и MOSI поможет нам выяснить, как инициируется передача нужной нам информации.


Рисунок 10: Схема подключения осциллографа

Ниже показано видео (без аудио), где показан последовательный интерфейс и сигналы с пинов MISO/MOSI во время манипуляций с роутером.

https://www.youtube.com/watch?v=OJOCm0IIbPE

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

Анализ данных на шине SPI

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

  • Дожидаемся окончания загрузки и перехода роутера в режим бездействия. То есть по шине SPI не будет передаваться никаких данных.
  • Запускаем оболочку ATP Cli, как описано в первой части.
  • Подсоединяем осциллограф к пинам MISO/MOSI и запускаем команду save, чтобы примерно понимать, в течение какого времени необходимо перехватывать информацию.
  • Устанавливаем в триггер (пин CS#) значение 0, чтобы запись информации началась в момент включения флеш-памяти.
  • Запускаем команду save.
  • Анализируем перехваченные данные.

Пункты 3 и 4 можно скомбинировать для того, чтобы увидеть на осциллографе, как перемещаются данные в режиме реального времени, и одновременно наблюдать за индикацией логического анализатора. Таким образом, ситуация будет под контролем, и информация будет записана в полном объеме. Чтобы одновременно подключить осциллограф и логический анализатор к одним и тем же пинам, подойдет следующий пружинный зажим:


Рисунок 11: Одновременное подключение осциллографа и логического анализатора

Теперь попробуем проанализировать, что передается по шине:


Рисунок 12: Информация, которая передается при запуске команды save

Давайте посмотрим, что полезного можно извлечь из перехваченной информации.

Мы работаем модулем памяти и видим, как читаются/записываются данные и по каким адресам. Я думаю, что полученную информацию можно наглядно разложить двумя способами:

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

Вначале я выгрузил всю полученную информацию в CSV файл. Кончено, в идеале можно было бы доработать анализатор протокола и добавить нужную функциональность, но эта задача довольно сложна и выходит за рамки данной статьи. Одно из главных преимуществ низкоуровневых протоколов, наподобие того, который используется при передаче по шине SPI, - простота и открытость. Я решил написать два скрипта (binmaker.py и traffic_mapper.py) для анализа CSV файла и извлечения интересующей нас информации.

Алгоритм анализа примерно следующий:

  • Экспортируем перехваченный трафик в CSV файл.
  • Запускаем скрипт:
    • Проходим весь CSV файл.
    • Идентифицируем команды на основе индекса.
    • Опознаем команды на основе первого байта.
    • Обрабатываем аргументы (адреса и т. д).
    • Идентифицируем полезную нагрузку, предназначенную для чтения/записи.
    • Конвертируем каждый байт полезной нагрузки из ASCII в бинарный формат.
    • Пишем бинарные блоки в различные бинарные файлы (MISO – чтение, MOSI - запись)
  • Считываем карту перехваченного трафика (обычный текст) и бинарные файлы (hexdump -C output.bin | less).

Скрипты генерируют следующие результаты:

Карта перехваченного трафика намного более полезна в сочетании с картой флеш-памяти, найденной во второй части:


Рисунок 13: Полная карта внешней флеш-памяти

Из карты перехваченного трафика видно, что информация, относящаяся к команде save, довольно проста:

  • Чтение около 64 Кб данных из защищенной области.
  • Перезапись информации, которую мы только что считали.

В бинарном файле MISO (save_miso.bin) видно, что большая часть считываемой информации довольно однородна и состоит из множества единиц:


Рисунок 14: Содержимое файла save_miso.bin

Большинство данных из бинарного файла MOSI представляют собой обычный XML и выглядят в точности так же, как в файле /var/curcfg.xml, который мы обнаружили во второй части. Тогда было сказано, этот файл представляет собой «текущий конфигурационный файл», содержащий массу полезной информации, включая учетную запись для WiFi.

Зачастую во флеш-памяти есть зарезервированные области, где хранится различная информация, которая нужна во время перезагрузки и может конфигурироваться пользователем, прошивкой или разработчиком устройства. Сей факт имеет значение, когда речь заходит о команде save, предназначенной для записи в данную область, и объясняет, почему эта информация представлена в удобочитаемом виде в отличие от сжатой файловой системы и почему мы нашли XML файл в папке /var/. В папке /var/ находятся файлы, используемые во время работы системы. Информация в защищенной области должна загружаться в память отдельно от файловой системы.

Золотой самородок в конце прошивки (теория)

Во время исследования важно не выпускать из вида конечную цель.

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

Подобная проблема безопасности неоднократно возникала в прошлом, когда пароли генерировались на основе MAC-адреса точки доступа или SSID.

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

Начиная от стандартных WiFi-паролей и заканчивая учетными записями к IoT-устройствам.

Проблема, связанная с наклейками

В настоящее время случаи подключения к роутеру через ethernet, когда нет необходимости в WiFi-пароле, не особо распространены, а отображение случайно сгенерированных паролей на экране было бы слишком дорогой затеей. В случае с роутерами наиболее распространенное решение – создание WiFi-сети и использование стандартных учетных записей, которые наклеиваются заводом изготовителем на задней стенке устройства. 


Рисунок 15: Наклейка с паролем на задней стенке устройства

Именно WiFi-пароль является той самой «уникальной информацией», а заводской компьютер, печатающий наклейки – «внешним объектом». И прошивке и компьютеру необходимо знать о стандартных WiFi-паролях, а инженер должен решить вопрос, связанный с синхронизацией. Обычно тут возможно 2 варианта:

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

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

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

Сбор информации во время сброса настроек роутера

Теперь, когда мы определились с целью, настало время сбора данных. Первое, что мы хотим выяснить, - какие действия способствуют появлению актуальной информации на плате. В нашем случае подобным действием будет удержание кнопки «Factory Reset» (восстановление заводских настроек) в течение 10 секунд. Сие действие должно заменить текущую учетную запись к WiFi-сети на стандартную. Если во время сброса будет извлекаться стандартная учетная запись или алгоритм генерации из внешней флеш-памяти, мы сможем увидеть данную информацию во время перехвата трафика.

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


Рисунок 16: Лог на выходе UART-порта

Перехваченный трафик:


Рисунок 17: Информация, передаваемая по шине SPI во время сброса

На выходе получаем три файла, сгенерированные при помощи скриптов (см. выше):

Карта трафика говорит нам о том, что вначале устройство считывает и перезаписывает 2 больших массива данных из защищенной области, а затем считывает еще один небольшой массив из файловой системы (возможно, следующая часть процесса для выполнения):
___________________
|Transmission  Map|
|  MOSI  |  MISO  |
|        |0x7e0000| Size: 12    //Part of the Protected area
|        |0x7e0000| Size: 1782
|        |0x7e073d| Size: 63683
| ERASE 0x7e073d  | Size: 64kB
|0x7e073d|        | Size: 195
|0x7e0800|        | Size: 256
|0x7e0900|        | Size: 256
---------//--------
[...]
---------//--------
|0x7e0600|        | Size: 256
|0x7e0700|        | Size: 61
|        |0x7d0008| Size: 65529 //Part of the Protected area
| ERASE 0x7d0008  | Size: 64kB
|0x7d0008|        | Size: 248
|0x7d0100|        | Size: 256
---------//--------
[...]
---------//--------
|0x7dff00|        | Size: 256
|0x7d0000|        | Size: 8
|        |0x1c3800| Size: 512   //Part of the Filesystem
|        |0x1c3a00| Size: 512
---------//--------
[...]
---------//--------
|        |0x1c5a00| Size: 512
|        |0x1c5c00| Size: 512
-------------------

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

  • Из флеш-памяти считывается ATP_LOG, содержащий информацию относительно удаленного доступа роутера или сброса настроек.  ATP_LOG оканчивается большим количеством единиц (0xff).
  • Тот сегмент памяти перезаписывается единицами.
  • Записывается «новый» ATP_LOG, в конце которого идет «текущая конфигурация» из файла curcfg.xml.
  • Считывается сжатый (недоступный для анализа) кусок памяти из файловой системы.

Кусок из файловой системы считывается ПОСЛЕ того, как новый пароль записывается на флеш-память, что не предполагает использования алгоритма генерации. С другой стороны, алгоритм может быть уже загружен в память и не передаваться по шине SPI.

Исследуя информацию канала MOSI, мы видим, что новый WiFi-пароль записан во флеш-память внутри XML-строки:


Рисунок 18: Новый Wifi-пароль

А как насчет чтения стандартного пароля? В бинарном файле канала MISO стандартный пароль отсутствует. Либо микросхема Ralink считывает стандартный пароль в другом режиме (secure/dual/quad/?), либо учетные записи (или алгоритм) уже загружены в память, и нет необходимости в повторном считывании из флеш-памяти, поскольку данная информация не меняется. Последнее – наиболее вероятно, и я не буду добавлять в свои скрипты поддержку других режимов чтения. На этом шаге мы остановимся и вернемся к стандартным учетным записям в следующей части.

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


Рисунок 19: Учетные записи, загружаемые из флеш-памяти

Как видно из рисунка выше, учетные записи хранятся в виде обычного текста и находятся обособленно. Сей факт может свидетельствовать о том, что алгоритм генерации пароля на данном устройстве не используется (но данный вывод не является окончательным). Возможно, разработчики решили сгенерировать учетные записи единожды (во время первой загрузки) и сохранить во флеш-памяти для того, чтобы ограничить использование алгоритма генерации и сокрыть бинарный файл, где находится данный алгоритм. Иначе мы можем просто проанализировать запущенные процессы на роутере во время нажатия на кнопку «Factory Reset» и увидеть, какие процессы зарождаются и потребляют наибольшее количество ресурсов.

Что дальше

На данный момент у нас есть код для создания снимков памяти и карт перехваченного трафика и информационных потоков. Я создавал карты во время других событий, в частности первых нескольких секунд во время загрузки (карта, miso), но не нашел ничего особо полезного. Однако даже просто возможность создания подобных файлов является весьма полезной и позволяет продвигаться вперед.

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

Спасибо за внимание.

comments powered by Disqus