Раздел: Документация
0 ... 38 39 40 41 42 43 44 ... 102 есах). чР11 этом старшие байты индекса содержат символы FFh, которые гтепьно более миролюбивы, чем символы нуля. " . если обнаружить факт искажения указателей практически невозмож-0Дна1;111рОвать их значения в резервных переменных не предлагать), то оце-"° коРРсКТНОСТЬ инлексов ПСРСД их использованием не составляет никакого "1ТЬ \ многие программисты именно так и поступают (правда, «многие» еще даначает «все»). Другой слабой стороной индексов является их ограничен-ИС «дальнобойность», составляющая ±128/256 байт (для индексов типа signed/ "rTigned спаг)11 2 4 байт для индексов тина signed int (листинг 4.7). г 4.7. фрагмент программы, подверженной последовательному переполнению "йпри записи, с затиранием индекса .ndexjJfO char *р: char buff[MAX BUF SIZE]: int т: P= nalloc(MAX BUF SIZE): i = MAX BUF SIZE: or.ntfCpassws:"): gets(buff): // i ((i < 1) (i > MAXBUFSIZE)) оиибка while(i-) p[i] = buff[MAX BUF S1ZE - 1]; СКАЛЯРНЫЕ ПЕРЕМЕННЫЕ Скалярные переменные, не являющиеся ни индексами, пи указателями, менее интересны для атакующих, поскольку в подавляющем большинстве случаев их возможности очень ограничены, однако на безрыбье сгодятся и они (совместное использование скалярных переменных вместе с указателями/индексами мы только что рассмотрели, сейчас же нас интересуют скалярные переменные сами чо себе). Рассмотрим случай, когда вслед за переполняющимся буфером расположена временная buks, инициализируемая до переполнения, а после переполнения "гпользуемая для расчетов количества денег, снимаемых со счета (не обязательно счета злоумышленника). Допустим, программа тщательно проверяет водные данные и не допускает использования ввода отрицательных значений, °-1Нако не контролирует целостность самой переменной buks. Тогда, варьируя то с°Держимое по своему усмотрению, злоумышленник без труда обойдет все Роверкц и ограничения (листинг 4.8). ПИСТИИг4-8. Фрагмент программы, подверженной переполнению, с затиранием скалярной переменной *Лето(Пс loat *money account har ff[MAx 3UF SIZE]: float buks = CURRENT 3UKS RATE: lriPut money:"): gets (buff): Продолжение > Листинг 4.8 (продолжение) .f (atof(buff)<0) ошибка! введите положительное значение *money account -= (atof (buff) * CURRENTBUKSRATE): } При всей своей искусственности приведенный пример чрезвычайно наглцд Модификация скалярных переменных только в исключительных случаях щ водит к захвату управления системой, но лег ко позволяет делать из чисел виц, грет, а на этом уже можно сыграть! Но что же это за исключительные случаГ-Во-первых, многие программы содержат отладочные переменные, оставлен,, разработчиками и позволяющие, например, отключить систему аутентнфп. ции. Во-вторых, существует множество переменных, хранящих начальные uv предельно допустимые значения других переменных, например счетчиков щк. ла — for (а = b: а < с: а++) *р++ = *х++; очевидно, что модификация переменных b и с приведет к переполнению буфера р со всеми вытекающими отсиь последствиями. В-третьих... да мало ли что можно придумать — всего и не перечислишь! Затирание скалярных переменных при переполнении обычно и приводит к немедленному обрушению программы, поэтому такие ошибки могут долго оставаться необнаруженными. Будьте внимательными! МАССИВЫ И БУФЕРЫ Что интересного можно обнаружить в буферых? Прежде всего это строки, хранящиеся в PASCAL-формате, то есть с полем длины вначале, затирание которого порождает каскад вторичных переполнений. Про уязвимость буфер» с конфиденциальной информацией мы уже говорили, а теперь, пожалуйста-конкретный, хотя и несколько наигранный пример! Еще интересны буферы, содержащие имена открываемых файлов (можно ласт* вить приложение записать конфиденциальные данные в общедоступный фаГи И-1!-напротив, навязать общедоступный файл взамен конфиденциального), тем*1" что несколько подряд идущих буферов, вообще говоря, не редкость (листинг4* Листинг 4.9. Фрагмент программы, подверженной последовательному переполнению при записи, с затиранием постороннего буфера b;jff demo() char buff[MAX BUF SIZE]: char DswdLMAX BUr SIZE]: fgetstpswd. MAX BUF SI7E. f): pr intf("passwd:"): getstbuff): if (strncmp(buff. pwsd. MAXBUFSIZE)) // неправильный пароль else // правильный пароль } В-—----— пЕЦИфИЧЕСКИЕ ОСОБЕННОСТИ РАЗЛИЧНЫХ ТИПОВ ПЕРЕПОЛНЕНИЯ Рчссматрнвая ра.чличные механизмы переполнения и обсужлая их возможные последствия, ранее мы не касались таких «организационных» вопросов, как, ]ПИример, порядок размещения переполняющихся буферов, затираемых переменных и служебных структур данных в оперативной памяти. Теперь пришло время восполнить этот пробел. В СТЕКЕ... Переполнения автоматических буферов наиболее часты и наиболее коварны. Часты — потому что размер таких буферов жестко (hardcoded) определяется еще на этапе компиляции, а процедура проверки корректности обрабатываемых данных зачастую отсутствует или реализована с грубыми ошибками. Коварны — потому что в непосредственной близости от автоматических буферов присутствует адрес возврата из функции, модификация которого позволяет злоумышленнику осуществить передачу управления на произвольный код (рис. ЛЛ). свободно автоматические переменные дочерней функции [сохраненные регистры] [кадр стека материнской функции] адрес возврата в материнскую функцию аргументы дочерней функции автоматические переменные материнской функции [сохраненные регистры] [кадр стека праматеринской функции] адрес возврата в праматеринскую функцию Г аргументы материнской функции дно стека рис. 4.1. Карта распределения стековой памяти Еще в стеке содержится указатель на фрейм (он же кадр) материнской функции, охраняемый компилятором перед открытием фрейма дочерней функции. Вооо-"te-то оптимизирующие компиляторы, поддерживающие технологию «плавающих, фреймов, обходятся и без этого, используя регистр-указатель вершины Калра как обычный регистр общего назначения, однако даже поверхностный ана-л»з обнаруживает большое количество уязвимых приложений с кадром внутри, так что этот прием атаки все еще остается актуальным. Модификация кад-JJ8 "ека срывает адресацию локальных переменных и аргументов материнской "чии и дает возможность управлять ими по своему усмотрению. Устано-каДр Материнской функции на «свой» буфер, злоумышленник может «за-1ь* в Материнские переменные (аргументы) любые значения (в том чис-авед°мо некорректные, поскольку проверка допустимости аргументов 0 ... 38 39 40 41 42 43 44 ... 102
|