В этой главе приведены начальные сведения об ошибках форматирующей строки, причины их возникновения и способы их использования в злонамеренных целях. Будет рассмотрена реальная уязвимость форматирующей строки и показано, как злоумышленник может ей воспользоваться.
Уязвимость форматирующей строки
Для понимания сути уязвимости форматирующей строки необходимо иметь четкие представления о работе функции printf.
Часто программистам требуется сформировать строку из нескольких переменных разного типа во время работы программы. Зачастую при разработке программы точное количество переменных, необходимых для формирования строки, и порядок их следования неизвестны. В основном для этих целей используется семейство функций printf,
предоставляющее гибкие возможности создания и форматирования строк во время выполнения программы. Функции семейства printf входят в стандартную библиотеку языка C. Возможности функций семейства printf реализованы и в других языках, например Perl.Параметрами этих функций являются форматирующая строка и переменное число параметров, которые позволяют сформировать строку. Форматирующая строка может рассматриваться как некий шаблон, описывающий структуру будущей строки и содержащий спецификации преобразования, которые сообщают функции семейства printf,
где и какие данные должны располагаться и как они должны быть отформатированы. Часто спецификации преобразования называются спецификациями формата. В главе будут использоваться два этих понятия независимо друг от друга....
Инструментарий и ловушки
Функции семейства printf
Ниже приведен список функций семейства printf,
входящих в стандартную библиотеку языка C. При неправильном использовании каждая из них может привести к ошибкам форматирующей строки.• Функция printf
позволяет сформировать и записать отформатированную строку в стандартный поток вывода.• Функция fprintf
позволяет сформировать и записать отформатированную строку в определяемый библиотекой libc файловый поток вывода, имя которого задается программистом.• Функция sprintf
позволяет сформировать и записать отформатированную строку в область памяти. Неправильное использование этой функции часто приводит к переполнению буфера.• Функция snprintf
позволяет сформировать и записать отформатированную строку заданной длины в область памяти. Является безопасной заменой функции sprintf при защите от переполнения буфера.В стандартную библиотеку языка C также включены функции vprintf, vfprintf, vsprintf
и vsnprintf. Они выполняют те же функции, что и ранее перечисленные, но их входным параметром может быть структура varargs, описывающая переменное число аргументов.Работа функции printf демонстрируется следующим примером:
int main
{
int integer = 10;
printf(“this is the skeleton of the string, %i”,integer);
}В этом примере вызывается функция printf
с двумя параметрами: форматирующей строкой и переменной, которая включается в формируемую строку вывода во время выполнения программы. Первый параметр функции – форматирующая строка, которая состоит из строки символов (статического текста) и спецификации вывода целого числа со знаком %i, соответствующей переменной integer. При вызове функции printf значение переменной целого типа, преобразованное в символьный вид десятичного числа, будет вставлено в строку после запятой.«this is the skeleton of the string, %i»
Ниже приведена строка, которая выводится во время выполнения программы (значение переменной равно 10).
[dma@victim server]$ ./format_example
this is the skeleton of the string, 10