8(495)909-90-01
8(964)644-46-00
pro@sio.su
Главная
Системы видеонаблюдения
Охранная сигнализация
Пожарная сигнализация
Система пожаротушения
Система контроля удаленного доступа
Оповещение и эвакуация
Контроль периметра
Система домофонии
Парковочные системы
Проектирование слаботочных сетей
Аварийный
контроль
Раздел: Документация

0 ... 33 34 35 36 37 38 39 ... 102

находится в весьма жестких и агрессивных условиях, не обеспечивающИ)( нимального уровня жизнедеятельности.иЧи-

И если вам нужен путеводитель по стране переполняющихся буферу женный исчерпывающим руководством по выживанию, — эта глава для

ФИЛОСОФСКОЕ НАЧАЛО

Чудовищная сложность современных компьютерных систем неизбежно при водит к ошибкам проектирования и реализации, многие из которых позволяют злоумышленнику захватывать контроль над удаленным узлом или делать с ним что-то нехорошее. Такие ошибки называются дырами, или уязвимостями (holes и vulnerability соответственно).

Мир дыр чрезвычайно многолик и разнообразен: это и отладочные люки, н слабые механизмы аутентификации, и функционально-избыточная интерпретация пользовательского ввода, и некорректная проверка аргументов, нт.д. Классификация дыр чрезвычайно размыта, взаимно противоречива и затруднена (во всяком случае, своего Карла Линнея дыры еще ждут), а методики их поиска и «эксплуатации» не поддаются обобщению и требуют творческого подхода к каждому отдельно взятому случаю. Было бы наивно надеяться,что одна единственная публикация сможет описать весь этот зоопарк! Давайте лучше сосредоточимся па ошибках переполнения буферов (bufferoverflow/ overrun) как на наиболее важном, популярном, перспективном и приоритетном направлении.

Большую часть главы мы будем витать в бумажных абстракциях теоретических построений и лишь к концу спустимся на ассемблерную землю, обсуждая наиболее актуальные проблемы практических реализаций. Нет, не подумайте. Никто не собирается в сотый раз объяснять, что такое стек, адреса памяти и от куда они растут! Эта глава рассчитана на хорошо подготовленную читатель скую аудиторию, знающую ассемблер и бегло изъясняющуюся на Си/Си++ словаря. Как происходит переполнение буфера вы, вероятно, уже представляе те, и теперь хотели бы ознакомится с полным списком возможностей, иред0 ставляемых переполняющимися буферами. Какие цели может преследовать кующий? По какому принципу происходит отбор наиболее предпочтите объектов атаки? Ну и т. д....

Другими словами, сначала мы будем долго и нудно говорить о том, что м°н. сделать с помощью переполнения и лишь затем перейдем к вопросу, «как но это сделать».

Описанные приемы работоспособны на большинстве процессорных аР*аеТ, тур и операционных систем (например, UNIX/SPARC). Пусть вас не ему что приводимые примеры в основном относятся к Windows NT и прои*в (С от нее системам. Просто в момент написания другой операционной систе оказалось под рукой.


oSS---- i z

„ЯСНОЙ РУЛЕТ ОШИБОК ПЕРЕПОЛНЕНИЯ, или ПОПЫТКА КЛАССИФИКАЦИИ (СКУКА СМЕРТНАЯ)

Согласно «Новому Словарю Хакера» Эрика Раймонда, ошибки переполнения буфера - это

...то, что с неизбежностью происходит при попытке засунуть в буфер больше, чем тот может переварить.

На самом деле это всего лишь частный случай последовательного переполнения при записи (листинг 4.1). Помимо него, существует индексное переполнение, заключающееся в доступе к произвольной ячейке памяти за концом буфера, где под «доступом» понимаются как операции чтения, так и операции записи (листинг 4.2).

Переполнение при записи приводит к затиранию, а следовательно, искажению одной или нескольких переменных (включая служебные переменные, внедряемые компилятором, такие, например, как адреса возврата или указатели this), нарушая тем самым нормальный ход выполнения программы и вызывая одно пз следующих последствий:

•нет никаких последствий;

•программа выдает неверные данные или, попросту говоря, делает из чисел винегрет;

•программа «вылетает», зависает или аварийно завершается с сообщением об ошибке;

•программа изменяет логику своего поведения, выполняя незапланированные действия.

Переполнение при чтении менее опасно, так как «всего лишь» приводит к потенциальной возможности доступа к конфиденциальным данным (например, паролям или идентификаторам TCP/IP соединения).

Листинг 4.1. Пример последовательного переполнения буфера при записи

seq Write(char *Р)

rhar buff[8]; strcpytbuff. р):

Листинг 4.2. Пример индексного переполнения буфера при чтении

i(Wite(int i)

ct»r buffr>"0l23456789":

return buff[i]:


118Глава 4. Ошибки переполнения буфера извнр

-----—!иэну.

За концом буфера могут находиться данные следующих типов:

•другие буферы;

•скалярные переменные;

•указатели.

Или же вовсе может не находиться ничего (например, невыделенная стран памяти). Теоретически за концом буфера может располагаться исполняем * код, но на практике такая ситуация почти никогда не встречается.Ь1"

Наибольшую угрозу для безопасности системы представляют именно указав ли, поскольку они позволяют атакующему осуществлять запись в производь ные ячейки памяти или передавать управление по произвольным адресам, например, на начало самого переполняющегося буфера, в котором расположен машинный код, специально подготовленный злоумышленником и обычно на-зываемы й shel 1 -кодом.

Буферы, располагающиеся за концом переполняющегося буфера, могут хранить некоторую конфиденциальную информацию (например, пароли). Раскрытие чужих паролей, равно как и навязывание атакуемой программе своего пароля -вполне типичное поведение для атакующего.

Скалярные переменные могут хранить индексы (и тогда они фактически приравниваются к указателям), флаги, определяющие логику поведения программы (в том числе и отладочные люки, оставленные разработчиком), и прочую информацию.

В зависимости от своего местоположения буферы делятся на три независимые категории:

1.Локальные буферы, расположенные в стеке и часто называемые автоматическими переменными.

2.Статичные буферы, расположенные в секции (сегменте) данных.

3.Динамические буферы, расположенные в куче.

Все они имеют свои специфичные особенности переполнения, которые мы обя зательно рассмотрим во всех подробностях, но сначала немного нофнлософ ствуем.

НЕИЗБЕЖНОСТЬ ОШИБОК ПЕРЕПОЛНЕНИЯ В ИСТОРИЧЕСКОЙ ПЕРСПЕКТИВЕ

Ошибки переполнения — это фундаментальные программистские ошибку торые чрезвычайно трудно отслеживать и фундаментальность коТОРЫХграм-печивается самой природой языка Си — наиболее популярного языка п" мирования всех времен и народов — а точнее, его низкоуровневым хаРа.тиЧно. взаимодействия с памятью. Поддержка массивов реализована лишь час и работа с ними требует чрезвычайной аккуратности и внимания со с . программиста. Средства автоматического контроля выхода за граничь ствуют, возможность определения количества элементов массива по У лю и не ночевала, строки, завершающиеся нулем, — вообще песня.-



0 ... 33 34 35 36 37 38 39 ... 102
Яндекс.Метрика