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

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

не в том, что малейшая небрежность и забытая или некорректно

дело ла*5Си1,аЯ проверка аргументов, приводит к потенциальной уязвимости

pt3-111301 ы Корректную проверку аргументов невозможно осуществить

проРаМ , рассмотрпм функцию, определяющую длину переданной ей стро-

„ "Р111"1 воЛЬно читающую эту строку до встречи с завершающим ее нулем.

кн н нос ющего ноля на конце не окажется? Тогда функция вылетит за \ ,»г?н1 заьс

.. утвержденного блока памяти и пойдет чесать испаханную целину по-1>C/U ней оперативной памяти! В лучшем случае это закончится выбро-10исключения. В худшем — доступом к конфиденциальным данным. Мож-М u,.uno передать максимальную длину строкового буфера с отдельным

МО, KOHt4" I

огументом, но кто поручится, что она верна.- Ведь этот аргумент приходится (нормировать вручную, и, следовательно, он не застрахован от ошибок. Короче говоря, вызываемой функции ничего не остается, как закладываться на корректность переданных ей аргументов, а раз так — о каких проверках мы вообще говорим?!

Далее, выделение буфера возможно лишь после вычисления длины принимаемой структуры данных, то есть должно осуществляться динамически. Это препятствует размещению буферов в стеке, поскольку стековые буферы имеют фиксированный размер, задаваемый еще па стадии компиляции. Зато стековые буферы автоматически освобождаются при выходе из функции, снимая это бремя с плеч программиста и предотвращая потенциальные проблемы с утечками памяти. Динамические буферы, выделяемые из кучи, намного менее популярны, поскольку их использование уродует структуру программы. Если раньше обработка текущих ошибок сводилась к немедленному returny, то теперь перед выходом из функции приходится выполнять специальный код, освобождающий все, что программист успел к этому времени «нонавыделять». Без критикуемого goto (которое само по себе нехилый «глюкодром») эта задача решается только глу-°ко вложенными if ами, обработчиками структурных исключений, макросами или внешними функциями, что захламляет листинг и служит источником многочисленных п трудноуловимых ошибок.

0Гие библиотечные функции (например, gets, sprintf) не имеют никаких кц п В огРа,шче,тя Длины возвращаемых данных и легко вызывают ошиб-ческ лнення- Руководства но безопасности буквально кишат категори-эиалоги 3аП)°ТаМИ "а ис,10ЛЬ30вание последних, рекомендуя их «безопасные» "Мину б 4ti9etS " snprint явно специфицирующие предельно допустимую ного"3. Р3, Предаваемую в специальном аргументе. Помимо неоправдан-,,РоблИ)МОЖлсния листинга посторонними аргументами и естественных 1с°гДа о С ИХ СИ11хР°нн,ачией (при работе со сложными структурами данных, •1лиць, н"елн,1ственный буфер хранит много всякой всячины, вычисление 4ecKoft "СТавшег°ся «хвоста» становится не такой уж очевидной арифмети-СТалкива;ЙЧе" и здесь °чень легко допустить грубые ошибки), программист "Ьх- КакСТСЯ С неоходимостью контроля целостности обрабатываемых дан-РеэаЧЬ1И/МИНИмум не°бходимо убедиться, что данные не были варварски об-,,СаацИе1уИли УСечены, а как максимум - корректно обработать ситуацию с об-А что мы, собственно, здесь можем сделать? Увеличить буфер


ОКУТАННЫЕ ЖЕЛТЫМ ТУМАНОМ МИФОВ И ЛЕГЕНД

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

Все это так (ведь и на улицу лишний раз лучше не выходить — случается, что и балконы падают), но за всю историю существования компьютерной индуст" рин не насчитывается и десятка случаев широкомасштабного использования переполняющихся буферов для распространения вирусов или атак. Отчасти потому, что атаки настоящих профессионалов происходят бесшумно. Отчасти потому, что настоящих профессионалов среди современных хакеров практически совсем не осталось...

Наличие одного или нескольких переполняющихся буферов еще ни о чем не-говорит, и большинство ошибок переполнения не позволяет атакующему пр0

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

В Си++ ситуация с переполнением обстоит намного лучше, хотя проблем все равно хватает. Поддержка динамических массивов и «прозрачных» текстовых строк наконец-то появилась (и это очень хорошо), но подавляющее больший, ство реализаций динамических массивов работают крайне медленно, а строки тормозят еще сильнее, поэтому в критических участках кода от них лучше сразу же отказаться. Иначе и быть не может, поскольку существует только одни способ построения динамических массивов переменной длины — представление их содержимого в виде ссылочной структуры (например, двунаправленного списка). Для быстрого доступа к произвольному элементу список нужно индексировать, а саму таблицу индексов где-то хранить. Таким образом, чтение/запись одного единственного символа выливается в десятки машинных команд и множество обращений к памяти (а память была, есть и продолжает оставаться самым узким местом, существенно снижающим общую производительность системы).

Даже если компилятор вдруг решит заняться контролем границ массива (одно дополнительное обращение к памяти и три-четыре машинные команды), это не решит проблемы, поскольку при обнаружении переполнения откомпилированная программа не сможет сделать ничего умнее, чем аварийно завершить свое выполнение. Вызов исключения не предлагать, поскольку если программист забудет его обработать (а он наверняка забудет это сделать), мы получим атаку типа «отказ в обслуживании». Конечно, это не захват системы, но все равно нехорошо.

Так что ошибки переполнения были, есть и будут! От этого никуда не уйти, и коль скоро мы обречены на длительное сосуществование с последними, будет нелишним познакомиться с ними поближе...


уться дальше банального DoSa. Вот неполный перечень ограничений, с ко-

1рыми приходится сталкиваться червям и хакерам:

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

2Размер переполняющихся буферов обычно оказывается катастрофически мал для вмещения в них даже простейшего загрузчика или затирания сколько нибудь значимых структур данных.

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

4Адреса системных и библиотечных функций меняются от одной операционной системы к другой — это раз; ни на какие адреса уязвимой программы также нельзя закладываться, поскольку они непостоянны (особенно это актуально для UNIX-приложений, компилируемых каждым пользователем самостоятельно), — а это два.

5. Наконец, от атакующего требуется глубокое знание команд процессора, архитектуры операционной системы, особенностей различных компиляторов языка, свободное от академических предрассудков мышление, плюс уйма свободного времени для анализа, проектирования и отладки shell-кода.

А теперь для контраста перечислим мифы противоположной стороны — стороны защитников информации, с какой-то детской наивностью свято верящих, что от хакеров можно защититься хотя бы в принципе:

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

2-Все разработанные методики борьбы с переполняющимися буферами снижают производительность (подчас очень значительно), но не исключают возможности переполнения полностью, хотя и портят атакующему жизнь;

3-Межсетевые экраны отсекают лишь самых примитивнейших из червей, занижающих свой хвост через отдельное ТСР/1Р-соединение, отследить же ПеРедачу данных в контексте уже установленных TCP/IP-соединений никакой межсетевой экран не в силах.

Кп- ест„вУют с°тни тысяч публикаций, посвященных проблеме переполнения, есть 1 СПИСОК котоРьХ был приведен в конце предыдущей главы. Среди них Cog к Уникальные работы, так и откровенный поросячий визг, подогреваемый 6oD Веннои крутизной (мол, смотрите, я тоже стек сорвал! Ну и что, что в ла-Н0 °Рных условиях?!). Статьи теоретиков от программировании элементарно . ПОзНаются замалчиванием проблем, с которыми сразу же сталкиваешься свое"НаЛИЗс ПОлновссных приложений и проектировании shell-кодов (по сути являющихся высокоавтономными роботами).



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