Пятница, 19.04.2024, 03:55
Приветствую Вас Гость | RSS
//vkontakte.ru/id66890680
Главная
Регистрация
Вход
Меню сайта

Категории раздела
Новости и релизы [29]
Прошивки [2]
Инструкции [16]
Soft раздел [3]
Hard раздел [5]
PSP Кодинг [5]
Игры на PSP [10]

Мини-чат
500

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Форма входа

Главная » Файлы » Инструкции [ Добавить материал ]

Углубляемся в PSP – Часть 6: Принцип атаки на IPL и PreIPL
28.01.2010, 13:21

Автор оригинального текста: SilverSpring и Dark-Alex
Перевод: sk8-maN

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

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




Эксплоит Пандоры

Защита IPL была взломана методом подбора (bruteforce, далее брутфорс), Однако взломать удалось не весь загрузчик, а лишь первый его блок. Это удалось сделать только благодаря его очень маленькому размеру. Собственно, нельзя подделать подпись для каждого блока установочного файла EBOOT ввиду его слишком большого размера. При этом алгоритм шифрования до сих пор неизвестен, а секретный ключ не взломан.

Принцип установки IPL

IPL поставляется в зашифрованном виде с цифровой подписью Sony. Когда IPL передается в криптографический модуль (KIRK), сначала проверяется подпись, и если она верна, то модуль дешифрует сами данные IPL. При этом алгоритмы шифрования и подписи, опять же, неизвестны.

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

Примерный принцип работы PreIPL эксплоита

Структура дешифрованного IPL блока:
0x00: загрузочный адрес
0x04: размер данных
0x08: адреса входа
0x0C: контроль сумма предыдущего блока
0x10: данные

Пример:
0x040F1EA0
0x00000F50
0x00000000
0xB71C6EBA
…data…

Что означает: загрузить 0xF50 байт данных по адресу 0x040F1EA0, контрольная сумма предыдущего блока - 0xB71C6EBA. Адрес входа равен 0, так как это непоследний блок. Как только последний блок будет загружен, в нем будет указан адрес входа – то, куда был загружен IPL (обычно 0x040F0000). После чего будет совершен переход по этому адресу.

Псевдокод PreIPL для загрузки и дешифрования IPL:
int iplBlockNumber = 0;
u32 checksum = 0;

// загрузка/дешифрование всех блоков IPL
while(1)
{
// копирования зашифрованных блоков IPL в 0xBFD00000-0xBFD01000 (4Кб встроенной ОЗУ ЦПУ)
if (LoadIplBlock(iplBlockNumber, block) <0)
while(1);

// дешифрование блоков IPL «на месте» (ой-ой)
if (DecryptIplBlock(block, block))
while(1);

// Первый блок будет содержать в себе нули в качестве контрольной суммы,
// так как нет предыдущего блока (еще один ой-ой)

if (block->checksum != checksum)
while(1);

// загрузка секции с данными блока IPL по определенному адресу (0x040Fxxxx диапазон)
if (block->loadaddr)
checksum = memcpy(block->loadaddr, block->data, block->blocksize);

// при достижении конца IPL – переход по адресу входа (0x040F0000)
if (block->entry)
{
// очистка кеша
Dcache();
Icache();

// переход к ipl – больше не возвращается
block->entry();
}
iplBlockNumber++;
}

Когда PreIPL загружает первый блок IPL (подложный), то происходит дешифрование «на месте», то есть дешифрованный блок записывается прямо поверх этого же зашифрованного блока. Поскольку подложный блок хитро сформирован, то будут стерты нулями только первые четыре байта подложного блока, сохранив полезную нагрузку.

Подложный подписанный блок IPL:
00000000: 00 00 00 00 00 00 00 00 00 01 D0 BF 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00000020: 52 A1 05 CD 3A 52 59 28 0A D1 31 F1 BD 87 2E CC
00000030: 14 DA 02 2F 77 88 C7 66 F3 32 07 BD 1A 08 9E 4C

00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000060: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00000070: 04 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

000000A0: 00 00 00 00 00 00 00 00 00 00 00 01 C6 5F 74 12

Важные моменты:
0x20-0x3F – подобранная хеш-подпись
0xA0-0xAF – подобранная зашифрованная информация
0x70-0x73 – размер данных для дешифрования (только 4 байта)

Эта ошибка в криптографическом модуле позволила упростить брутфорс во много-много раз.

После дешифрования PreIPL считает, что данный блок IPL уже дешифрован.

Обратите внимание на первые 0x10 байт:
0x00000000 (загрузочный адрес подложен на нули после дешифрования)
0x00000000 (размер блока для загрузки - нет)
0xBFD00100 (адрес входа, где и расположен неподписанный код)
0x00000000 (контрольная сумма)

Проверка контрольной суммы проходится благодаря 0x00000000, затем никакая информация уже не загружается, так как адрес загрузки подменен на 0x00000000, затем обнаруживается адрес входа 0xBFD00100, так что PreIPL считает, что IPL закончился, после чего происходит переход по адресу (где и расположен неподписанный код).

Вроде все просто, но это нисколько не умаляет объем работы, вложенной для создания неподписанного IPL.

Так что же Sony изменила в новых PreIPL?

При загрузке PSP PreIPL загружает IPL из NAND Flash или карты памяти. IPL разбит на блоки по 0x1000 байт. Первые 0xA0 байт каждого блока - это заголовки для KIRK-аппаратных комманд. Содержит ключи, размер зашифрованной информации и два хеша: один хеш заголовка, второй - для тела блока. Остальные 0xF60 байт - зашифрованное тело, которые расшифровываются в 0xF60 обычных байт... если хэши, которые проверяются kirk-аппаратом, пройдут проверку. (Зашифрованное тело может быть меньше, чем 0xF60, в этом случае, оставшиеся байты игнорировались в старых платах до выхода ТА88v3).

Защита старой PreIPL была нарушена временной атакой, описанной выше.

Что же сделали в Sony для защиты?

Ответ лежит в 4.00+ «слимовских» IPL. Они уменьшили размер шифрованного тела до 0xF40 для того, чтобы оставить 0x20 байт в конце каждого блока (начиная с 0xFE0).
Раньше эти байты игнорировались, их значение могло быть случайными, но IPL успешно загружала прошивку PSP. Но для новых PreIPL эти байты имеют значение.

Первые 0x10 байт - это неизвестный хеш, вычисляемый по некоторому алгоритму из расшифрованного блока. Выяснено, что хеш высчитывается из расшифрованного блока, а не зашифрованного, так как прошивки 4.01 и 4.05 имеют много общего в IPL блоках, когда они расшифрованны, но совершенно различны зашифрованными. В этих двух IPL, этот хеш одинаков, как показано на рисунке:

image001.png (3. Kb)

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

Эта защита также исключает любую возможность даунгрейда ниже 4.00, так как новые CPU не запустят старые IPL.

Итого: защита новых PSP основана на тайне вычисления этих 0x20 байт. Основная проблема – неизвестно как сделать дамп PreIPL, скорее всего это можно сделать только аппаратным путем.

image003.png (45.86 Kb)

Главная
  По поводу материала обращайтесь FAQ (вопрос/ответ)
Категория: Инструкции | Добавил: sk8-man
Просмотров: 1065 | Загрузок: 0 | Комментарии: 1 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск


Copyright MyCorp © 2024