Существует
множество сценариев, позволяющих осуществить поиск уязвимости и
создание эксплоита. Например: переполнение буфера, переполнение кучи,
повреждение стека, повреждение памяти…
В данной статье
будет рассказано о Переполнении буфера, как наиболее простом и понятном
пути атаки на программу. В частности, популярные эксплоиты, основанные
на файлах сохранения игры (GripShift, Lumines, GTA LCS), являются
примерами использования Переполнения буфера.
Нижеследующий пример применим к архитектуре x86, но общие принципы и методы для создание эксплоита одинаковы.
В чем особенность эксплоита, работающего на уровне ядра?
Главная
особенность такого эксплоита заключаются в том, что он позволяет
работать с памятью ядра. В основном, уязвимости обнаруживаются в
SceIoOpen, для этого нужно дизассемблировать PRX файлы прошивки PSP.
Поиск уязвимости требует много времени и терпения. Это одна из причин,
почему такие уязвимости трудно найти.
Что есть Переполнение буфера?
Переполнение
буфера (Buffer Overflow или Buffer Overrun) — явление, возникающее,
когда компьютерная программа записывает данные за пределами выделенного
в памяти буфера.
Переполнение буфера обычно возникает из-за
неправильной работы с данными, полученными извне, и памятью, при
отсутствии жесткой защиты со стороны подсистемы программирования
(компилятор или интерпретатор) и операционной системы. В результате
переполнения могут быть испорчены данные, расположенные следом за
буфером (или перед ним). Для примера рассмотрим следующий код,
написанный на С++:
#include #include
int copy(char *string){ char buffer[5]; strcpy(buffer, string); return 1; }
Пока ничего необычного. Сначала мы объявили подпрограмму, вызвали
main(), инициализировали Строку (string) и Буфер (buffer). После этого
компьютер выводит «Hello World» на экран консоли. А вот после этого
начинается самое интересное – программа вызывает функцию copy(),
которая копирует в буфер данные введенные пользователем с консоли. В
программе используется стандартная функция библиотеки С – strcpy(),
весьма ненадежная функция, которую следует избегать при
программировании. Функция strcpy() копирует данные из string в buffer.
Однако размер buffer составляет всего 5 байт. Но что произойдет, если
передать больше 5 байт? Например, передадим 30 байт, чтобы быть
уверенными, что мы перезаписали все важное в памяти. Смотрим:
scrnshot1.png (41.29 Kb)
Замечательно. Как вы видите, EIP – адрес возврата был перезаписан
следующими данными - 0x41414141, что в переводе из 16-ричного вида в
ANSI означает «AAAA». Если подобное происходит на платформе архитектуры
MIPS (к коей относится и PSP) , то вы увидите: $ra: 0x41414141. $ra – это адрес возврата для MIPS.
Отлично,
а теперь вместо краха программы сделаем что-нибудь более полезное,
например, заменим адрес возврата так, чтобы он указывал на функцию
main(). Ищем адрес функции main() в памяти:
scrnshot2.png (30.92 Kb)
Дебаггер Nemiver указывает, что функция main() расположена в
0x080488AF. Итак, перезапишем EIP таким образом, чтобы он принял
значение 0x080488AF. Если все сделано правильно, то на экран «Hello
World» выведется дважды.
В эксплоите MaTiAz для игры GripShift
возвратный адрес указывал на ячейку сохранения игры, которая содержала
неподписанный код (а отсюда и ограничение в размере).
Как
видите, данные действия требуют терпеливости и усидчивости, некоторое
количество мозгов и знаний, а также времени для того, чтобы превратить
найденную уязвимость в эксплоит. Далеко не все уязвимости так хороши
для атаки, как та, что приведена в примере. Уязвимость приобретает
ценность, если она способна нести полезную нагрузку – исполняемый код.
Потому всякого рода вопли вокруг файлов сохранений различных игр
вызывают смех. Зависание PSP не означает наличие эксплоита.
Также
в следующей статье будет рассказано более подробно о конкретном примере
для PSP, на основе статьи Wololo. Если вам не терпится попробовать свои
силы самостоятельно, то скачайте и установите следующие плагины и
программы:
Теперь
вы можете сделать незашифрованное сохранение к игре, найти в нем
строки, содержащие имя персонажа (то, что вы вводите сами в игре),
попробовать его перезаписать длинной строкой. Если игра обращается к
данной строке, и не имеет защиты, то она или зависнет, или вылетит.
Если это произойдет, переходите к следующему шагу – анализ краха игры с
помощью PSPLink. Помните, что далеко не каждая уязвимость имеет
ценность, но, возможно, вы найдете что-нибудь полезное. Продолжение
следует...