The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project The YapLink Project

Аппаратный взлом жёсткого диска. Часть 2

BlackPope

Местный
Регистрация
27.04.2020
Сообщения
242
Реакции
35
Разумеется, я мог превратить это в завершённый хак, но из-за необходимости подключения JTAG для записи в ОЗУ при каждом запуске жёсткого диска он становится довольно бесполезным. Мне нужно было сделать его сохраняемым, то есть хранить мои модификации в каком-то месте, откуда их можно было бы брать при каждом включении жёсткого диска.

Для этого я выбрал флэш-ПЗУ. Вероятно, я бы мог поместить его куда-нибудь в зарезервированные сектора самого жёсткого диска, но если бы я что-то перепутал, то не смог бы восстановить диск. Чип флэш-памяти — это просто стандартная деталь с восемью выводами, поэтому я могу запросто извлечь её, прошить и вставить снова. Для этого я отпаял её и подключил к монтажной плате, чтобы можно было легко переключаться между программатором и жёстким диском:



Что же нам записать во флэш-память? К счастью, хранящийся в чипе формат уже был разобран: он состоит из множества блоков данных, а в самом начале находится описывающая их таблица. Эта таблица описывает местоположение блока во флэш-памяти, способ его сжатия (если он сжат), место, в которое блок должен помещаться в ОЗУ, а для последнего адреса — точка исполнения, в которую загрузчик должен перейти для исполнения программы.

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

Разумеется, для этого мне нужно было дизассемблировать и снова собрать двоичный файл флэш-памяти. Я создал для этого инструмент и дал ему скучное название «fwtool». Этот инструмент может дампить разные блоки флэш-памяти, а также транслировать заголовок в текстовый файл для простоты редактирования. Затем можно модифицировать, удалить или добавить блок, а затем собрать всё снова в единый файл прошивки, готовый к записи во флэш-память. Я использовал его для добавления в образ собственного фрагмента кода, прошил всё обратно в чип, припаял чип к жёсткому диску, снова всё запустил и в результате получил вот это:



Это неудивительно: именно такой результат я и получал раньше. Хитрость заключается в том, что теперь для этого не требуется модификация через JTAG.

Прошиваем ПО

Хотя модификация флэш-памяти стала хорошим шагом вперёд, я по-прежнему не мог реализовать свой воображаемый хакерский сценарий: не думаю, что какая-то серверная компания принимает «пожертвования» в виде жёстких дисков с отпаянными и заново припаянными флэш-чипами. Мне нужно было найти способ перепрошивки чипа, когда он припаян к жёсткому диску, желательно с компьютера, к которому подключен диск.

Инструменты обновления прошивок Western Digital доказывают, что это возможно: по сути, это инструмент, запускаемый под DOS для записи новой прошивки во флэш-память и в сервисную область, то есть на зарезервированные сектора жёсткого диска. По информации из Интернета, для этого в инструменте используются так называемые Vendor Specific Commands. Существуют и другие инструменты, способные модифицировать прошивки: например, есть экспериментальный код, способный использовать незанятые зарезервированные сектора для сокрытия данных. Кроме того, есть набор инструментов под названием idle3-tools, которые можно использовать для модификации байта в прошивке, чтобы изменить поведение жёсткого диска в режиме ожидания. В этом коде тоже используются VSC при помощи «официального» способа с применением ioctls scsi-драйвера Linux. Я решил «позаимствовать» этот код, немного его изменить и интегрировать в fwtool. После экспериментов с кодом и подбора параметров VSC моя программа fwtool внезапно научилась считывать и записывать флэш-память жёсткого диска, подключенного к компьютеру, на котором она запущена.

На этом моя атака была завершена. Если бы blackhat-хакер каким-то образом получил бы root-доступ к серверу с этим диском, то он бы смог использовать fwtool для удалённого создания дампа флэш-памяти на диск, модифицировать его и снова прошить в память. Рано или поздно владелец компьютера выяснил бы, что я использую его машину с вредоносными целями, и, вероятно, переустановил бы систему, закрыв лазейку, через которую хакер проник изначально.

Однако после установки прошивки нападающий смог бы приказать жёсткому диску сделать что-нибудь вредоносное с новой установленной системой. Сначала бы ему нужно было запустить подобное поведение, и это можно было бы реализовать определённой магической строкой, которую бы хак прошивки искал на диске. Магическая строка может быть любым файлом; например, нападающий мог бы загрузить на сервер файл .jpeg со строкой в нём. Также он мог бы запросить файл с веб-сервера через магическую строку, присоединённую к URL. Затем бы она появилась в логах машин, что привело бы к срабатыванию эксплойта.

Затем хак прошивки жёсткого диска сделал бы нечто вредоносное. Например, он мог бы подождать, пока машина не начнёт считывать файл /etc/shadow, где в системе Unix/Linux хранятся все пароли, и модифицировать его содержимое на лету, заменив его чем-то, что хакер прописал заранее. Затем нападающий мог бы попробовать войти в систему с собственным паролем, а машина бы сравнила этот пароль с модифицированным /etc/shadow, позволив нападающему снова войти в систему.

Вот демонстрация, которую я сделал для презентации. Вы видите, как я безуспешно пытаюсь войти в аккаунт root компьютера. Затем я включаю хак и передаю ему хэш нового пароля, а именно пароля «test123». Так как Linux кэширует файл shadow (как и все файлы, к которым недавно выполнялся доступ), мне придётся генерировать сильную дисковую активность, чтобы «вытеснить» файл из кэша; благодаря этому, когда я снова попытаюсь выполнить вход, Linux будет вынужден снова получить файл shadow с диска. Наконец, благодаря очистке кэша я смогу просто выполнить вход в аккаунт root с фальшивым паролем test123.



Другие способы применения

Разумеется, восстановление доступа к серверам, у которых были закрыты тайные способы входа — не единственный полезный способ применения моей работы по реверс-инжинирингу. Её можно использовать и в целях защиты.

Например, можно создать неклонируемый жёсткий диск: жёсткий диск будет функционировать обычным образом, если паттерн доступа к секторам является случайным, аналогично тому, как к файловой системе обращается ОС. Если доступ к диску выполняется только последовательно, как это обычно делает утилита клонирования дисков, то жёсткий диск может искажать данные, делая клон отличным от оригинала.

Контроллер диска интересен и просто как плата контроллера. У него есть три довольно мощных процессорных ядра, к которым подключён достаточно большой объём ОЗУ. Также у него есть uart для последовательного порта и не менее двух интерфейсов SPI; один для флэш-ПЗУ, второй — для контроллеров двигателя шпинделя. Можно загружать код для процессора, обновляя данные во внешнем флэш-чипе или даже при помощи последовательного в загрузчике. Чтобы продемонстрировать мощь чипа, я портировал на свой жёсткий диск довольно популярное ПО. Демо является только проверкой концепции, единственное работающее периферийное устройство — это последовательный порт, а пользовательского пространства пока нет. Тем не менее, я всё равно немного горд тем, что установил на свой жёсткий диск Linux. Сверху расположена стандартная командная строка (жёсткий диск смонтирован в /mnt), снизу — вывод моей работы с последовательным портом жёсткого диска:



Расскажу немного подробнее о том, что здесь происходит: ядро и init каждый упакованы во фрагменты размером ровно в один сектор, а к их началу добавлены магическая строка и порядковый номер. При считывании файла с диска он оказывается в кэше диска. Запись магической строки «HD, lnx!» заставляет модифицированную прошивку искать в кэше все сектора, пересобрать образ ядра и загрузить его. Ядро собрано для процессора без MMU (у контроллера диска его нет) и оно имеет только драйвер для последовательного порта. К сожалению, для ядра без MMU требуется ещё и специально отформатированное пользовательское пространство. Мне не удалось его скомпилировать, поэтому ядро в конце концов выдаёт kernel panic, потому что не может найти init, который оно смогло бы исполнить.
 
Верх