Дэвид Лебланк - 19 смертных грехов, угрожающих безопасности программ
- Название:19 смертных грехов, угрожающих безопасности программ
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дэвид Лебланк - 19 смертных грехов, угрожающих безопасности программ краткое содержание
Эта книга необходима всем разработчикам программного обеспечения, независимо от платформы, языка или вида приложений. В ней рассмотрены 19 грехов, угрожающих безопасности программ, и показано, как от них избавиться. Рассмотрены уязвимости на языках C/C++, C#, Java, Visual Basic, Visual Basic.NET, Perl, Python в операционных системах Windows, Unix, Linux, Mac OS, Novell Netware. Авторы издания, Майкл Ховард и Дэвид Лебланк, обучают программистов, как писать безопасный код в компании Microsoft. На различных примерах продемонстрированы как сами ошибки, так и способы их исправления и защиты от них. Если вы программист, то вам просто необходимо прочесть эту книгу.
Перевод: А. Слинкин
19 смертных грехов, угрожающих безопасности программ - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Греховность C/C++
В отличие от многих других рассматриваемых нами ошибок, эту обнаружить довольно легко. Такой код неправилен:
printf(user_input);
а вот такой – правилен:
printf(«%s», user_input);
Многие программисты легкомысленно полагают, что ошибку достаточно исправить только в таких местах. Однако нередко встречаются ситуации, когда форматную строку с помощью sprintf помещают в буфер, а потом забывают об этом и пишут примерно такой код:
fprintf(STDOUT, err_msg);
Противнику нужно лишь подготовить входные данные так, чтобы спецификаторы формата экранировались, и обычно написать эксплойт для такой ошибки даже проще, потому что буфер err_msg часто выделяется в стеке. Получив возможность пройти вверх по стеку, противник сможет управлять тем, в какое место будет записана информация, определяемая поданными им на вход данными.
Родственные грехи
Хотя самая очевидная атака связана с дефектом в коде программы, нередко форматные строки помещают во внешние файлы, чтобы упростить локализацию. Если такой файл недостаточно защищен, то противник сможет просто подставить собственные форматные строки.
Еще один близкий грех – это недостаточный контроль входных данных. В некоторых системах информация о местных привязках (locale) хранится в переменных окружения и определяет, в частности, каталог, где находятся файлы на нужном языке. Иногда противник может даже заставить приложение искать файлы в произвольных каталогах.
Где искать ошибку
Любое приложение, которое принимает данные от пользователя и передает их функции форматирования, потенциально уязвимо. Очень часто этому греху подвержены приложения, записывающие полученные от пользователя данные в протокол. Кроме того, некоторые функции могут реализовывать форматирование самостоятельно.
Выявление ошибки на этапе анализа кода
В программе на C/C++ обращайте внимание на функции семейства printf, особенно на такие конструкции:
printf(user_input);
fprintf(STDOUT, user_input);
Если встретится что–то похожее на
fprintf(STDOUT, msg_format, arg1, arg2);
проверьте, где хранится строка, на которую указывает msg_format, и насколько хорошо она защищена.
Есть много других уязвимых системных вызовов и API, в частности функция syslog. Определение любой функции, в списке аргументов которой встречается многоточие (…), должно вас насторожить.
Многие сканеры исходных текстов, даже лексические типа RATS и flawfinder, способны обнаружить такие ошибки. Есть даже программа PScan (www.striker. ottawa.on.ca/~aland/pscan/), специально спроектированная для этой цели. Существуют и инструменты, которые можно встроить в процесс компиляции, например программа FormatGuard Криспина Коуэна (http://lists.nas.nasa.gov/archives/ ext/linux–security–audit/2001/05/msg00030.html).
Тестирование
Передайте приложению входную строку со спецификаторами формата и посмотрите, выводятся ли шестнадцатеричные значения. Например, если программа ожидает ввода имени файла и в случае, когда файл не найден, возвращает сообщение об ошибке, в которое входит введенное имя, попробуйте задать такое имя файла: NotLikely%x%x. txt. Если в ответ будет напечатано что–то типа «NotLikelyl2fd234104587.txt cannot be found», значит, вы нашли уязвимость, связанную с форматной строкой.
Ясно, что такая методика тестирования зависит от языка, – передавать имеет смысл только спецификаторы формата, поддерживаемые языком, на котором написана программа. Однако поскольку среды исполнения многих языков часто реализуются на C/C++, вы поступите мудро, если протестируете также и форматные строки для C/C++ – вдруг обнаружится опасная уязвимость библиотеки, использованной при реализации.
Отметим, что если речь идет о Web–приложении, которое отправляет назад данные, введенные пользователем, то существует также опасность атаки с кросс–сайтовым сценарием.
Примеры из реальной жизни
Следующие примеры взяты из базы данных CVE (http://cve.mitre.org). Это лишь небольшая выборка из 188 сообщений об ошибках при работе с форматной строкой.
CVE–2000–0573
Цитата из бюллетеня CVE: «Функция lreply в FTP–сервере wu–ftpd версии 2.6.0 и более ранних плохо контролирует форматную строку из не заслуживающего доверия источника, что позволяет противнику выполнить произвольный код с помощью команды SITE ЕХЕС». Это первый опубликованный эксплойт, направленный против ошибки в форматной строке. Заголовок сообщения в BugTraq подчеркивает серьезность проблемы: «Удаленное получение полномочий root по крайней мере с 1994 года».
CVE–2000–0844
Цитата из бюллетеня CVE: «Некоторые функции, используемые в подсистеме локализации UNIX, недостаточно контролируют внедренные пользователем форматные строки, что позволяет противнику выполнить произвольный код с помощью таких функций, как gettext и catopen».
Полный текст оригинального бюллетеня можно найти по адресу www.securityfocus.eom/archive/l/80154. Эта ошибка интересна тем, что затрагивает базовые API, применяемые в большинстве вариантов UNIX (в том числе и Linux), за исключением систем на базе BSD, в которых привилегированная suid–программа игнорирует значение переменной окружения NLSPATH. Как и многие бюллетени в разделе CORE SDI, этот прекрасно написан, информативен и содержит очень подробное объяснение проблемы в общем, но это предложение не только опасно, но еще и потребляет много процессорного времени.
Искупление греха
Прежде всего никогда не передавайте поступающие от пользователя данные функциям форматирования без проверки. За этим нужно следить на всех уровнях форматирования вывода. Отметим попутно, что функциям форматирования присущи заметные накладные расходы; загляните в исходный текст функции _output, если вам любопытно. Как бы ни удобно было писать просто:
fprintf(STDOUT, buf);
Во вторую очередь позаботьтесь о том, чтобы все используемые в программе форматные строки читались только из доверенного источника и чтобы противник не мог контролировать путь к этому источнику. Если вы пишете код для UNIX или Linux, имеет смысл последовать примеру BSD в плане игнорирования переменной NLSPATH, которая задает путь к файлу локализованных сообщений. Это повысит степень защиты.
Искупление греха в C/C++
Достаточно просто пользоваться функциями форматирования вот так:
printf(«%s», user_input);
Дополнительные защитные меры
Проверяйте локаль и разрешайте только корректные значения. Подробнее см. статью David Wheeler «Write It Secure: Format Strings and Locale Filtering», упомянутую в разделе «Другие ресурсы». Не пользуйтесь функциями семейства printf, если есть другие пути. Например, в С++ имеются операторы вывода в поток:
Читать дальшеИнтервал:
Закладка: