Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #58, СЕНТЯБРЬ 2005 г.

Сокрушительная атака

Андрей Семенюченко

Спецвыпуск: Хакер, номер #058, стр. 058-010-3


Существует также динамическое выделение памяти. Выделение памяти под данные производится самой программой, когда это необходимо. Время жизни таких данных зависит от программы. Раньше считалось, что переполнения при динамическом выделении памяти произойти не может или, минимум, это маловероятно. Считалось, что при таком раскладе максимум, что светит хакеру, – DoS-атака. В этом виновата хаотичность распределения динамических блоков в памяти. Но как показала практика, буфера, расположенные в динамической памяти, также подвержены переполнению. Многие программисты сначала выделяют буфер фиксированного размера, а затем определяют, сколько памяти им реально необходимо, забывая обработать ситуацию недостатка памяти. Таким образом, злоумышленник может осуществить переполнение кучи!

Практическое применение

Для приобретения навыков в переполнении буфера напишем простенькую программу на языке С и попробуем осуществить переполнение стека с помощью функции strcpy(). Это классический случай, который нужен чтобы понять суть процесса, а любые дальнейшие модернизации программы ты сможешь без труда осуществить и сам. Пример будем демонстрировать на старом добром Linux Red hat 9, но выбор системы в данном случае не принципиален и, как всегда, остается за тобой.

Итак, рассмотрим следующий код.

#include <stdio.h>

#include <string.h>

int main(int argc, char *argv[])

{

char fuffer[500];

strcpy(buffer, argv[1]);

printf(“You have entered: %s\n”,

buffer);

return 0;

}

Перед нами до боли знакомая функция main, содержащая два встроенных аргумента argc и argv. Аргумент argv типа char - указатель на массив строк. Каждый элемент массива указывает на аргументы командной строки. Один параметр отделяется от другого пробелами. Соответственно, argv[0] - полное имя запущенной программы; argv[1] - первая строка, записанная после имени программы.

С помощью функции strcpy(строка_назначения, строка_отправления) мы заполняем переменную buffer значением первого аргумента. Результат выведем на экран с помощью функции printf().

С виду простая программа, которую, казалось бы, трудно заставить вести себя некорректно. Поместим данный код в файл с названием simple_code.c.

Скомпилируем программу:

gcc simple_prog.c –o simple

Запустим программу, передав в качестве аргумента "Life is perfect".

На стандартный вывод получим строку

You have entered: Life is perfect

Теперь воспользуемся услугами Perl и передадим в качестве аргумента значение большее, чем было отведено для переменной buffer, например 524:

./simple `perl –e ‘print “X”x524’`

Результатом программы будет вывод заданного числа символа "X" и сообщения "Segmentation fault". Это значит, что программа завершилась с ошибкой, так как мы ввели число, заведомо превышающее размер переменной buffer. На самом деле число 524 я взял не случайно: это число, при котором стек затирается полностью, а если взять любое меньшее число, например 523, программа завершится корректно.

На сайте http://bstring.sourceforge.net лежит описание использования так называемых безопасных библиотек в С\С++.

Назад на стр. 058-010-2  Содержание  Вперед на стр. 058-010-4