Здравствуйте, меня зовут Александр. Немного о себе. Мне 16 лет, заканчиваю 11 класс, живу в городе, который очень далёк от столицы. Уже 2,5 года занимаюсь программированием по части игровых консолей Sony. Автор многих плагинов и программ, а также, с недавнего времени, прошивок.

Я думаю, многие помнят старушку PSP, которая радовала наш глаз с 2005 года.
Многие, будучи детьми, очень завидовали сверстникам с состоятельными родителями, которые могли порадовать своё чадо таким подарком.
Но время проходит, технологии совершенствуются, и PSP уже не та.
Примерно год назад Sony запустила новый проект под названием PSVita, также известная как NGP (Next Generation Portable) и PSP2.
Последним термином не брезгует и сама компания, применяя его в качестве кодового названия.
Консоль получила хорошие технические характеристики и уникальные возможности. Многие из хакеров поприща PSP кинули свои силы на взлом защиты PSVita.

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

Шаг 1 — Usermode доступ в эмуляторе PSP

Первые и текущие usermode эксплоиты эмулятора PSP на PSVita, позволяющие запустить неподписанный код были построены на уязвимостях переполнения буфера. Начальный код и «вода», которая переливалась за буфер находились в теле сохранения игры, купленной за кровные деньги в PS Store. Де/криптовка сохранений и поиск уязвимостей на этом поприще стал возможен благодаря совместимости данных сохранений с PSP.

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

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

Допустим в игре есть код.

// структура данных сохранения
struct {
    char username[64];
    int other_data[256];
}SaveData;

ReadSavedata(&SaveData); // чтение данных сохранения

// целевой буфер
char username_backup[64];

// уязвимый участок
sprintf(username_backup, "%s", username);



Я не зря оставил участок other_data. Я хотел показать, что в сохранении есть ещё место кроме 64 байт для имени игрока. Если мы удлиним имя игрока до 128 символов, то уязвимая функция, не обращая на размер буфера, запишет данные по его указателю. 128-64=64. То есть буфер будет переполнен на 64 символа. А, так как буфер выделен из стека, то произвольные данные из строки заполнят служебные записи кода.
Существуют 3 разновидности эксплуатации инструкций.

1. Регистр $ra (инструкция jr)

Если в последующем данные из стека будут восстановлены в регистр $ra (регистр возвращения адреса в MIPS), то мы сможем выполнить код с произвольного адреса. Нам сослужит службу инструкция «jr $ra», которая предназначена для возвращения кода на исходный участок из подфункции. Конечно же, мы положим свой код в свободное место в сохранении, осталось ещё 64 байта, которых предостаточно.

2. Аргумент инструкции jalr

Если данные будут восстановлены в регистр, который является аргументом инструкции jalr, то мы также сможем перенаправить код аналогично первому случаю. Отличие лишь в том, что в этом случае вам придётся повозиться с исследованием кода, когда же в первом переполнение буфера вы заметите сразу («Exception — Bus error (instr)» в дебаггере).

3. Аргументы sw

Если мы возымеем контроль над аргументами инструкции sw (store word), то мы сможем подставить себе «под ножку» любую инструкцию, в том числе и перенаправление.

Все эти манипуляции проводятся на PSP с помощью дебаггера (psplink), далее сохранение криптуется и подаётся на завтрак PSVita с заведомо купленной уязвимой игрой.

В доказательство предоставлю скриншот Hello World, запущенного с помощью эксплоита в данных сохранения.


При наличии только usermode эксплоита возможно портирование загрузчика usermode софта (Vita Half-Byte Loader). У него куча ограничений и багов, но, тем не менее, это не мешает пользователям наслаждаться лишь эмуляторами первых консолей (Dendy, Atari, Sega, GameBoy Advance).

Шаг 2 — Kernel доступ в эмуляторе PSP

Следующий шаг — kernel доступ. При получении возможности вносить правки в kernel память, мы можем сделать с системой всё что угодно. Это и сделал известный хакер и разработчик Total_Noob, написав и выпустив CEF (Custom Emulator Firmware) на основе утекшего kernel эксплоита от человека, который пожелал остаться неизвестным. После прошивки 1.81 был длительный кризис в плане взлома. Новый эксплоит никто не торопился выпускать, тогда я решил выпустить свой. И вот вы можете использовать CEF на прошивках выше 1.81 вплоть до 2.02. Сейчас я постараюсь объяснить его концепцию. Я думаю, она многим знакома.

1. Read-only kernel эксплоит

Насколько вам известно, имея только user права, записать или даже прочитать kernel память нельзя. Попытки этого ограничиваются эксепшном «ломящегося» модуля и последующим крешем всей системы. Создаётся впечатление, будто и нет её, этой kernel памяти. Но мы то знаем, что она есть и даже знаем её адрес — 0x88000000.

Но с чего же нам начать? У нас нет модулей прошивки, а прочитать kernel память чтобы получить их мы не можем!
Для этого нам нужно найти read-only kernel эксплоит. Его принцип прост. Мы должны использовать функцию в kernel модуле, которая может записать в указатель или вернуть из функции значение участка кода, адрес которого можно задать аргументом самой функции. Для исследований можно использовать модули прошивки PSP (рекомендую 6.60). Ведь прошивка эмулятора PSP во многих местах просто идентична прошивке PSP, как я уже говорил выше. Соответственно, дыры остались.

Пример «дырявой» функции (пример без мусора и служебных инструкций).

sceKernelReadOnlyKxploit:
    move   $s0, $a0
    lw     $v0, 0($s0)



Регистр $a0 является первым аргументом функции, значение которого потом перемещается в регистр $s0. Регистр $s0 в свою очередь есть второй аргумент для инструкции lw, он задаёт адрес. Первым аргументом lw является регистр $v0, который возвращает значение операции return (в Си). Инструкция lw это load word — загрузка четырёхбайтного слова (его адрес это значение второго аргумента) в регистр (первый аргумент).
Осмыслив абзац выше, мы можем сделать заключение, что данная функция вернёт значение четырёхбайтного слова по адресу, заданному в первом аргументе.

Эксплоит для данной функции будет выглядеть так.

u32 *target = (void *)0x08A00000;
u32 i;
for(i = 0; i <= 0x00400000; i += 4)
{
    *(target + i) = sceKernelReadOnlyKxploit(0x88000000 + i);
}



В результате по адресу 0x08A00000 в памяти будет записано содержимое kernel памяти размером в 0x00400000 байт. Сохранить его в виде файла не составит трудностей, также как и поиск идентичных уязвимостей.

Вытащив необходимые модули, их можно исследовать. Дизассемблирование производится программой prxtool.

2. Kernel эксплоит с правами записи

С поиском этих зверьков придётся поднатужиться, они очень редки и ценны. Я объясню только основную концепцию.
Посмотрите на функцию sceKernelLibcTime (модуль sysmem.prx, лучше смотреть на код прошивки 6.60 и экспериментировать пока на PSP). Видите jalr на регистр $a1? А теперь подумайте, что будет если затереть «lw $a1, 2244($v1)» несколькими инструкциями выше? Правильно, мы получим контроль над аргументом jalr и сможем перенаправить выполнение кода на любой существующий адрес. А как мы можем это сделать? Только используя kernel функции.

Итак, найти подходящую функцию можно только исследуя kernel функции на наличие контроля второго аргумента store инструкций (sw, sh, sb) с помощью входных аргументов самой функции ($a0-$a3, $t0-$t7) и наличие ошибок в структурах. Будьте внимательны, особенно к структурам.

Ввиду того, что о последнем написано абстрактно, подробнее об этом вы можете почитать здесь, в моей же давней статье.
Хороший справочник по архитектуре MIPS есть на википедии.
Просто отличный учебник по ассемблеру с нуля на примере MIPS (за который отдельная благодарность Bradley Kjell) вы можете найти здесь.
Описание kernel эксплоита на консоли PSP в прошивках 6.20 и 6.60.

Хочу выразить благодарность: SilverSpring, Malloxis, Dark Alex и some1.

В заключение хочу сказать, что я не поддерживаю пиратство и статья написана только в ознакомительных целях. Если у вас возникли вопросы всегда буду рад ответить в твиттере (frostegater). Спасибо за внимание.

источник: http://habrahabr.ru/post/167985/

каммент отражающий всю суть


Давайте вспомним первые годы жизни PSP. Сколько на ней было приличных игр? Очень мало, как и сейчас на PS Vita. Плюс сейчас у PSP официально есть возможность запускать игры PSOne, и существует куча игр серии Minis. PS Vita получила это всё изначально. Возможность выхода в интернет отовсюду с помощью 3G — это тоже отличная возможность. PSP на старте продаж стоила около 12000 рублей, как и PS Vita сейчас.

Согласен, для многих покупателей PSP главным мотивом была возможность взлома и последующего запуска любых игрушек и хоумбрюшек; а как раз этого сейчас лишена PS Vita. Зачем ломать PS Vita именно сейчас, когда под неё ещё нет огромного количества качественных игр? Да затем же, зачем и PSP начали ломать сразу после выхода. Чтобы был наработан опыт; чтобы при выходе новых прошивок можно было быстро найти эксплойт; чтобы не произошло ситуации «Ой, а на PS Vita уже куча хороших игр, давайте её сломаем!» и последующего долгого ожидания.



Во времена PSP ей не было никакой альтернативы. В 2005-м году никаких планшетов и смартфонов на Android не существовало. Поэтому устройство, подобное PSP, вызывало настоящий вау-эффект: портативная читалка, видео- и mp3-плеер, пачка эмуляторов, словари, да ещё и в сеть выходить умеет! Круто же, особенно за такую цену (устройства реально были крайне дешёвые, хороший смартфон сейчас стоит дороже, чем PSP тогда).
Реально, ни одно портативное устройство не могло тягаться с PSP по соотношению цена-доступность-возможности.
Я знаю уйму людей, которые никогда не скачивали никаких iso, а 99% времени проводили в букридере или в видеоплеере. Т.е. устройство реально заменяло планшет.

Сейчас же, когда на рынке прямо-таки засилье планшетов, смартфонов, плееров, читалок, возможности PSP (да и PSV тоже) особо никому и не нужны. Чем ждать хака, воевать с идиотскими проприетарными форматами от Sony, куда проще купить смарт/планшет на Android. Тем более, есть даже китайские поделки в PSV-корпусе со стиками и кнопками как в вите(!). И там сразу будет всё, весь софт. А не будет разве что тех 6 игрушек, которые выпущены эксклюзивом для Виты. Но кому они интересны? Разве что хардкорным геймерам и немногочисленным фанатам серии.