Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #66, ИЮНЬ 2004 г.

Эксплойтный ликбез

Олег Толстых aka NSD

Xakep, номер #066, стр. 066-070-2


int format_bug(char *str)

{

int k = 9;

printf(str);

return 0;

}

Эта функция должна выводить в stdout содержимое передаваемой через параметры переменной str. Если передать функции строку «Hi, people!», на экран выведется то же самое, что и вводилось. Какая же ошибка может быть тут? Попробуем передать функции строку «%x_%x_%x_%x_%x_%x_Hi, ppl!». Что же мы видим? Вместо ожидаемого результата на экране появилась строка “9_fff6_2fc_ff92_7825_255f_Hi, ppl!”. Из-за чего могло такое произойти? Фишка в том, что printf() обрабатывает входные данные, воспринимая некоторые символы как форматные спецификаторы, и как ты уже понял, 9_fff6_2fc_ff92_7825_255f является соответствием %x_%x_%x_%x_%x_%x. Шестнадцатеричные представления чисел, которые ты видишь выше, это не что иное, как данные из стека. Число 9 – это значение переменной k, fff6 – сохраненное в стеке содержимое регистра bp, 2fc – адрес возврата функции format_bug и т.д. Таким образом можно вывести содержимое всего стека. А ведь в нем могут находиться пароли, приватные ключи для шифрования и прочая важная инфа! Используя хитрым образом форматный преобразователь «%n», хакер может даже перезаписывать нужную область стека. Главное, он может перезаписать адрес возврата функции. К чему это приводит - я писал выше. Ошибка программиста заключается в том, что он не указал printf’у тип выводимых данных, в результате чего пользователь смог сам влиять на строку форматных спецификаторов. Если бы в коде вместо строки «printf(str);» он написал «printf(“%s”,str);», все работало бы без багов. Собственно говоря, эти две уязвимости чаще всего используются хакерами при написании эксплойтов.

Компиляция *nix’овых эксплойтов

Обычно эксплойты пишут под одну из двух популярных платформ - под форточки от всеми любимых мелкомягких или под никсы. Для того чтобы откомпилить никсовый сплойт, вовсе не обязательно ставить себе unix. Обычно хакеры взламывают какой-нибудь сервак и используют его как плацдарм для хака, собирая и запуская remote-сплойты прямо на нем. Чтобы собрать *nix-exploit, следует заюзать компилятор gcc, который имеется на большинстве серверов. Компилируется эксплойт следующим образом. В командной строке оболочки оси набирается команда gcc expl.c –o expl. В нашем случае, expl.c – имя файла исходника, expl – имя конечного файла. Если процесс компиляции завершится успешно, в той же папке, в которой находятся сорцы сплойта (expl.c), появится новый файл-бинарник expl, который как раз и можно запускать. Удаленные сплойты можно компилить где угодно, а вот локальные лучше всего собирать прямо на машине-жертве. Хотя часто бывает так, что шелл на сервере есть, но доступ к компилятору ограничен. В этом случае лучшее решение – собрать сплойт на другой машине, работающей под аналогичной операционной системой, при этом нужно понимать, что если ты соберешь сплойт под OpenBSD 3.4, он не будет работать во FreeBSD 4.9.

Назад на стр. 066-070-1  Содержание  Вперед на стр. 066-070-3