ПИШЕМ БАЖНУЮ CGI`ШКУ НА C

Спецвыпуск Xakep, номер #022, стр. 022-026-2


1a. Переполнение буфера при использовании стандартных функций

Одна из самых распространенных и опасных ошибок, т.к. под данную ошибку очень легко написать exploit.

Пример грубой ошибки:

char name[300];

scanf("%s", name);

Число 300 взято от балды, вместо него могло быть и 30, и 300000, от ошибки это не спасает, т.к. все равно можно ввести (или написать прогу, которая будет вводить) строку большей длины.

Пример тонкой ошибки:

char s[6];

itoa (value, s, 10);

Если переменная value вводилась пользователем, то он мог ввести число, в котором цифр больше, чем 5, т.к. самое длинное целое число (-2147483648) содержит 13 символов, разницы в 7 символов часто хватает с лихвой, чтобы написать под эту ошибку exploit.

Ошибке "переполнение буфера" подвержены следующие стандартные функции (в скобочках указан безопасный аналог, если он есть) - gets (fgets), strcpy (strncpy), strcat(strncat), при неосторожном обращении опасны также функции - sprintf (snprintf), vsprintf (vsnprintf), scanf, fscanf, sscanf, itoa.

1б. Переполнение буфера в своем коде

Переполнение буфера поджидает не только при использовании стандартных функций, но и при написании своего кода.

Пример грубой ошибки:

int index, value, array[100];

std::cout >> index >> value; //вводим номер элемента массива, вводим число

array[index] = value; //записываем введенное число в массив

В данной задаче надо было проверять переменную index на правильное значение - оно должно было быть больше нуля и меньше 100.

Пример тонкой ошибки:

char buf[200], *p = buffer;

int i = 0;

for (i = 0; (buf[i] = getchar()) != ' ' && i < 200; ++i){}

buf[i] = 0;

Максимально введенная строка будет занимать 201 байт, а не 200, как рассчитывалось. Exploit на данный конкретный случай будет сложно написать, но уронить программу можно будет запросто, а при небольшом везении может все-таки получиться и exploit.

Рекомендации по избежанию данной ошибки просты:

a. Проверяй все входные параметры на корректность.

b. Будь внимателен при написании кода, работающего с массивами.

2. Ошибка форматной строки

При выводе строк с помощью функций семейства printf многие ленивые программисты или "крутые оптимизаторы" (которые стараются экономить даже на спичках) пишут вместо printf ("%s", str) просто printf (str).

Во втором случае, если строка str вводилась пользователем, в нее можно вставить форматные спецификаторы (%s, %d и т.д.), которые могут не только завалить программу, но и поспособствовать выполнению exploit`а.

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