Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #45, АВГУСТ 2004 г.

Защитись и замети!

Коваленко Дмитрий aka Ingrem

Спецвыпуск Xakep, номер #045, стр. 045-068-1


(ingrem@list.ru)

О защите от эксплоитов и закрытии уязвимостей после атаки

Часть 1. Защити себя сам

Сопротивление бесполезно?

Прочитав предыдущие статьи, ты мог решить, что защититься от атак на переполнение буфера невозможно. Кругом злые хакеры, которые все равно что-то найдут и переполнят. И при этом если не получат полный контроль, то уж DoS точно устроят! Действительно, если ты простой пользователь, то тебе только и остается, что читать бюллетени безопасности и ждать заплатки, которая закроет очередную дыру в твоем софте.

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

Настроить компиляторы!

А знаешь ли ты, что многие современные HLL-компиляторы поддерживают автоматический контроль переполнения стека? Нужно только правильно их настроить. Для примера возьмем компилятор MS VC++ 7.0 из пакета MS Visual Studio.NET. Откроем окно свойств проекта и выберем Configuration Properties =< C/C++ =< Code Generation, установим Buffer Security Check в "Yes". Теперь при попытке переполнения массива работа программы будет прерываться, и хакер, вызвавший переполнение, сможет любоваться красивым окошком:

Правда, от переполнения динамических буферов эта настройка не спасает. К тому же, при включенном контроле переполнения массивов генерируется более громоздкий и медленный код. Увы! Ради безопасности приходится чем-то жертвовать :-(. Нужные настройки компилятора обычно описаны в документации к нему.

Кстати, разработчики компиляторов давно хотят сделать автоматическую проверку не только для массивов, но и для указателей вообще. Но пока что не очень успешно. Например, существует заплатка для gcc, которая позволяет полностью реализовать проверку указателей. Результат – падение скорости и увеличение генерируемого кода примерно в 20-30 раз! Согласись, это не самое оптимальное решение.

Осторожно! В буфере длинная строка

Многие дыры в софте – результат неправильной обработки длинных строк. Программисты или не понимают, что может случиться из-за переполнения стека строкой, или так спешат сляпать и продать очередную версию своего продукта, что забывают о безопасности. В итоге, имеем вагон и маленькую тележку супер-пупер крутых приложений, которые загибаются от одной строчки. А между тем защитить буфер (любой, не только тот, что находится в стеке) от слишком длинной строки очень просто! Как? Читай дальше. Для начала напишем небольшое приложение. Откроем MS VC++ 7.0, создадим консольное приложение с именем overflow и в overflow.cpp набьем вот что:

Листинг

#include >windows.h<

#include >stdio.h<

int overflow_proc(char* big) {

char buff[10];

strcpy(buff, big);

Содержание  Вперед на стр. 045-068-2