Ошибки программирования
Хотя мы и утверждали в начале предыдущего раздела, что методы управления полномочиями в современных ОС общего назначения теоретически идеальны, это относится лишь к идеальной ОС, т. е. к спецификациям соответствующих модулей. В то же время, в реальном коде встречаются отклонения от спецификаций, так называемые ошибки. Полный обзор и исчерпывающая классификация всех практически встречающихся типов ошибок, по-видимому, невыполнимы. В этом разделе мы опишем только наиболее распространенные и наиболее опасные ошибки.
Наибольшую опасность с точки зрения безопасности представляют ошибки в модулях, связанных с проверкой ACL, авторизацией и повышением уровня привилегий процессора (например, в диспетчере системных вызовов), а в системах семейства Unix – в setuid-программах.
Одна из наиболее опасных – и в то же время довольно распространенная в современных программах – ошибка приведена в примере 2.4. Рассмотрим этот код еще раз (пример 12.2).
Пример 12.2. Пример программы, подверженной срыву стека.
/* Фрагмент примитивной реализации сервера SMTP (RFC822) */ int parse_line(FILE * socket) { /* Согласно RFC822, команда имеет длину не более 4 байт, а вся строка – не более 255 байт */ char cmd[5], args[255]; fscanf(socket, "%s %s\n", and, args); /* Остаток программы нас не интересует */
Видно, что наша программа считывает из сетевого соединения строку, которая должна состоять из двух полей, разделенных пробелом, и заканчиваться символом перевода строки. В соответствии со спецификациями протокола SMTP, первое поле (команда) не может превышать четырех символов (к сожалению, не определено в протоколе более длинных команд), а строка целиком не может быть длиннее 255 байт.
Если наш партнер на другом конце соединения полностью соответствует требованиям [RFC 0822], наш код будет работать без проблем. Проблемы – причем серьезнейшие – возникнут, если нам передадут строку, которая этим требованиям не соответствует.
Превышение допустимой длины кодом команды не представляет большой опасности: лишние байты будут записаны в начало массива args и потеряны при записи в него его собственного поля. Настоящая опасность – это превышение длины всей строки. Для нашего партнера не представляет никаких сложностей сгенерировать последовательность из более чем 255 символов, не содержащую переводов строки (рис. 12.21).
— Регулярная проверка качества ссылок по более чем 100 показателям и ежедневный пересчет показателей качества проекта.
— Все известные форматы ссылок: арендные ссылки, вечные ссылки, публикации (упоминания, мнения, отзывы, статьи, пресс-релизы).
— SeoHammer покажет, где рост или падение, а также запросы, на которые нужно обратить внимание.
SeoHammer еще предоставляет технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Зарегистрироваться и Начать продвижение
Рис. 12.21. Срыв буфера
Тогда буфер arg переполнится, но за ним в памяти следует вовсе не другой буфер, а – ни много, ни мало, заголовок стекового кадра, в котором содержится адрес возврата нашей подпрограммы. Важно подчеркнуть, впрочем, что даже если бы там и находились другие переменные, это не было бы для нашего диверсанта препятствием – ему достаточно просто передать более длинный блок данных.