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

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

Life-Hack [Жизнь-Взлом]/Хакинг

#Обучение

Разумеется, я мог превратить это в завершённый хак, но из-за необходимости подключения 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, который оно смогло бы исполнить.

Источник

Report Page