Взлом с использованием данных
Контрмеры: защита от атак с использованием переполнения буфера
Практика безопасного кодирования
Лучшим методом зашиты от переполнения буфера является практика кодирования, учитывающего все требования обеспечения безопасности. Хотя на практике невозможно спроектировать и запрограммировать систему таким образом, чтобы в ней не было ни одной ошибки, существуют подходы, способные минимизировать вероятность возникновения переполнения буфера. Среди таких рекомендаций можно выделить следующие.
- При проектировании программы всегда оценивайте ее с точки зрения безопасности. К сожалению, зачастую программы создаются наспех, чтобы успеть к поставленному сроку. В таких ситуациях безопасность – это последнее, о чем думают разработчики. При этом поставщики программного обеспечения даже не беспокоятся о том, чтобы своевременно устранять изъяны по мере их обнаружения. Более подробная информация по этому вопросу приведена в разделе Secure UNIX Program по адресу http://www.whitefang.com/sup/index.html.
- Рассмотрите возможность использования безопасного компилятора, такого, например, как StackGuard, разработанного в рамках проекта Immunix. В этом компиляторе используется подход, заключающийся в "вакцинации" программ во время компиляции, что позволяет свести к минимуму риск возникновения переполнения буфера. Кроме того, к механизмам защиты относится динамическая библиотека libsafe, предназначенная для перехвата вызовов уязвимых функций на уровне операционной системы. Помните о том, что подобные механизмы нельзя рассматривать как "серебряную пулю", так что при их использовании все же не стоит забывать о необходимости обеспечения безопасности.
- Нужно проверять все аргументы, получаемые от пользователя или какой-либо программы. Такая проверка, конечно, может замедлить некоторые приложения, но это не очень высокая цена за безопасность. При проведении проверки особое внимание необходимо уделять принадлежности используемых значений корректным диапазонам, особенно для переменных окружения.
- Используйте безопасные процедуры, такие как fget(), strncpy() и strncat () и проверяйте коды возврата системных вызовов.
- Уменьшите количество кода, запускаемого с привилегиями root. Этого можно достичь за счет минимизации использования программ, которым требуются права SUID суперпользователя. Если даже злоумышленнику удастся успешно применить к такой программе атаку с переполнением стека, то ему все равно придется повышать полученные привилегии до уровня root.
- И наконец, применяйте все модули обновления, предоставляемые поставщиком программного обеспечения.
Тестирование и аудит каждой программы
Очень важно выполнять тестирование и аудит каждой программы. Очень часто случается, что программисты даже не задумываются о том, может ли в их программе возникнуть ошибка переполнения буфера. Однако всегда найдется кто-нибудь, кто не только задумается над этим, но и приложит все усилия для того, чтобы найти такие ошибки и воспользоваться ими в своих целях. Одним из лучших примеров тестирования и аудита кода UNIX является проект OpenBSD (www.openbsd.org), которым руководит Тео де Раадт (Theo de Raadt). Программисты, работающие над проектом OpenBSD, постоянно проверяют и перепроверяют исходный код друг друга и уже исправили сотни ошибок, которые могут привести к переполнению буфера, не говоря уже о более серьезных проблемах, имеющих отношение к безопасности. Именно из-за столь грамотного подхода к тщательному аудиту, применяемого разработчиками OpenBSD, эта операционная система заслужила репутацию одной из самых надежных из свободно распространяемых версий UNIX.
Отключение неиспользуемых или потенциально опасных служб
На протяжении этой главы мы будем возвращаться много раз к этому вопросу. Если какие-то неиспользуемые или потенциально опасные службы не являются жизненно необходимыми для работы системы UNIX, отключите их. Помните, что ни один злоумышленник не может проникнуть в систему через неработающую службу. Кроме того, мы настоятельно рекомендуем использовать TCP-оболочки (tcpd) и xinetd (http://www.synack.net/xinetd/) для того, чтобы можно было применить избирательные списки управления доступом на уровне служб, а также воспользоваться дополнительным возможностями регистрации событий. Конечно, не к каждой службе можно применить оболочку. Однако применение этого средства лишь к некоторым службам может значительно повысить защищенность вашей системы. Кроме того, оцените возможность использования режима фильтрации пакетов на уровне ядра, поддержка которого уже стала стандартной для большинства бесплатных операционных систем UNIX (например, ipchains или netf liter для Linux, ipf для BSD). Хорошие рекомендации по использованию ipchains для обеспечения безопасности можно найти по адресу http://www.linuxdoc.org/HOWTO/IPCHAINS-HOWTO.html. Пакет ipf Даррена Рида (Darren Reed) является одним из лучших и может быть добавлен во многие версии системы UNIX. Для получения об этом пакете более подробной информации обращайтесь по адресу http://www.obfuscation.rg/ipf/ipf-howto.html.