ПИШЕМ БАЖНУЮ 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
|