Gets – еще одна проблематичная функция языка C. Компилятор GNU языка C выдает предупреждающее сообщение при компиляции программ с функцией gets, потому что эта функция никак не контролирует размер получаемых данных. Посмотрите на следующий пример:
>/* getsbufo.c */
>/* Hal Flynn */
>/* December 31, 2001 */
>/* This program demonstrates how NOT */
>/* to use the gets() function. gets() */
>/* does not sufficient check input */
>/* length, and can result in serious */
>/* problems such as buffer overflows. */
>#include
>int main()
>{
>get_input();
>return (0);
>}
>void get_input(void)
>{
>char c[8];
>printf(“Enter a string greater than seven bytes: ”);
>gets(c);
>return;
>}
В исходном тексте программы можно найти функцию gets. В результате выполнения функции gets данные входного потока пересылаются в восьмибайтовый массив символов c. Но поскольку эта функция не выполняет никаких проверок на размер обрабатываемых данных, то в результате легко получить ошибку переполнения буфера.
Подробнее с проблемой переполнения буфера можно познакомиться в главе 8.
Ошибки проверки входных данных
Причина других типичных ошибок программирования кроется в недостаточной проверке входных данных программы. В результате уязвимость программы может проявиться при передаче ей различных типов данных, как, например, это происходит с программами Web CGI.
Ошибки проверки входных данных программы могут привести к уязвимостям форматирующей строки. Уязвимость форматирующей строки проявляется при использовании в программе таких спецификаций преобразования, как, например, %i%i%i%i или %n%n%n%, что может привести к неожиданному результату. Подробно форматирующие строки рассмотрены в главе 9.
Но перед этим приведем пример программы с уязвимой форматирующей строкой. Проанализируйте следующую программу:
>/* fmtstr.c */
>/* Hal Flynn */
>/* December 31, 2001 */
>/* fmtstr.c demonstrates a format */
>/* string vulnerability. By supplying */
>/* format specifiers as arguments, */
>/* attackers may read or write to */
>/* memory. */
>#include
>int main(int argc, char *argv[])
>{
>printf(*++argv);
>return (0);
>}
В результате запуска программы и передачи ей на вход форматирующей строки со спецификацией преобразования %n пользователь сможет распечатать содержимое произвольных областей памяти. При распечатке соответствующей области памяти можно запустить программу с привилегиями привилегированного пользователя root.