19 смертных грехов, угрожающих безопасности программ. Майкл Ховард
Чтение книги онлайн.

Читать онлайн книгу 19 смертных грехов, угрожающих безопасности программ - Майкл Ховард страница 13

СКАЧАТЬ возникает вопрос: «Как противник может воспользоваться ошибкой при работе с форматной строкой для записи в память□» Существует довольно редко используемый спецификатор %п, который позволяет записать число выведенных к настоящему моменту байтов в переменную, адрес которой передан в качестве соответствующего ему аргумента. Вот предполагаемый способ его применения:

      unsigned int bytes;

      printf("%s%n\n", argv[1], &bytes);

      printf("Длина входных составляла %d символов\n, bytes");

      В результате было бы напечатано:

      E:\projects\19_sins\format_bug>format_bug2.exe «Some random input»

      Some random input

      Длина входных составляла 17 символов

      На платформе, где длина целого составляет четыре байта, спецификатор %п выводит четыре байта, а спецификатор %hn – два байта. Противнику осталось только вычислить, какой адрес должен быть помещен в нужную позицию стека, а потом, манипулируя спецификаторами ширины, добиться, чтобы число выведенных байтов равнялось числовому значению нужного адреса.

      Примечание. Более подробная демонстрация шагов, которые нужно предпринять для реализации такого эксплойта, приведена в главе 5 книги Michael Howard и David С. LeBlanc «Writing Secure Code, Second Edition» (Microsoft Press, 2002) или в книге Holesby Jack Koziol, David Litchfield, Dave Artel, Chris Anley, Sinan «noir» Eren, Neel Mehta and Riley Hassell «The Shellcoder's Handbook» (Справочник no shell–кодам) (Wiley, 2004).

      Пока достаточно принять за аксиому, что если вы позволите противнику контролировать форматную строку в программе на C/C++, то рано или поздно он придумает, как заставить эту программу выполнить нужный ему код. Особенно неприятно, что перед запуском такой атаки противник может изучить содержимое стека и изменить направление атаки на лету. На самом деле в первый раз, когда автор демонстрировал эту атаку публично, ему попался не тот интерпретатор команд, на котором эксплойт разрабатывался, поэтому атака не сработала. Но вследствие удивительной гибкости этой атаки удалось исправить ошибку и взломать уязвимое приложение на глазах аудитории.

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

      Без слов понятно, что если противник может задать форматную строку, передаваемую функции scanf и ей подобным, то беда неминуема.

      Греховность C/C++

      В отличие от многих других рассматриваемых нами ошибок, эту обнаружить довольно легко. Такой код неправилен:

      printf(user_input);

СКАЧАТЬ