Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
Крис Касперски
Мы живем в суровом мире. Программное обеспечение, окружающее нас, содержит дыры, многие из которых размерами со слона. В дыры лезут хакеры, вирусы и черви, совершающие набеги изо всех концов Сети. Червям противостоят антивирусы, заплатки, брандмауэры и другие умные слова, существующие лишь на бумаге и бессильные сдержать размножение червей в реальной жизни. Сеть небезопасна – это факт. Можно до потери пульса закидывать Била Гейтса тухлыми яйцами и кремовыми тортами, но ситуация от этого вряд ли изменится. Анализ показывает, что подавляющее большинство червей и хакерских атак основано на ошибках переполнения буфера, которые носят фундаментальный характер и которых не избежало практически ни одно полновесное приложение. Попытка разобраться в этой, на первый взгляд довольно скучной и незатейливой проблеме безопасности погружает вас в удивительный мир, полный приключений и интриг. Захват управления системой путем переполнения буфера – сложная инженерная задача, требующая нетривиального мышления и превосходной экипировки. Диверсионный код, заброшенный на выполнение, находится в весьма жестких и агрессивных условиях, не обеспечивающих и минимального уровня жизнедеятельности. Если вам нужен путеводитель по стране переполняющихся буферов, снабженный исчерпывающим руководством по выживанию, – эта статья для вас!
Чудовищная сложность современных компьютерных систем неизбежно приводит к ошибкам проектирования и реализации, многие из которых позволяют злоумышленнику захватывать контроль над удаленным узлом или делать с ним что-то нехорошее. Такие ошибки называются дырами или уязвимостями (holes и vulnerability соответственно).
Мир дыр чрезвычайно многолик и разнообразен: это и отладочные люки, и слабые механизмы аутентификации, и функционально-избыточная интерпретация пользовательского ввода, и некорректная проверка аргументов и т. д. Классификация дыр чрезвычайно размыта, взаимно противоречива и затруднена (во всяком случае, своего Карла Линнея дыры еще ждут), а методики их поиска и «эксплуатации» не поддаются обобщению и требуют творческого подхода к каждому отдельному случаю. Было бы наивно надеяться, что одна-единственная публикация сможет описать весь этот зоопарк! Давайте лучше сосредоточимся на ошибках переполнения буферов как на наиболее важном, популярном, перспективном и приоритетном направлении.
Большую часть статьи мы будем витать в бумажных абстракциях теоретических построений и лишь к концу спустимся на ассемблерную землю, обсуждая наиболее актуальные проблемы практических реализаций. Нет, не подумайте! Никто не собирается в сотый раз объяснять, что такое стек, адреса памяти и откуда они растут! Эта публикация рассчитана на хорошо подготовленную читательскую аудиторию, знающую ассемблер и бегло изъясняющуюся на Си/Си++ без словаря. Как происходит переполнение буфера, вы уже представляете и теперь хотели бы ознакомиться с полным списком возможностей, предоставляемых переполняющимися буферами. Какие цели может преследовать атакующий? По какому принципу происходит отбор наиболее предпочтительных объектов атаки?
Другими словами, сначала мы будем долго говорить о том, что можно сделать с помощью переполнения, и лишь потом перейдем к вопросу «как именно это сделать». В любом случае эта тема заслуживает отдельной статьи.
Описанные здесь приемы работоспособны на большинстве процессорных архитектур и операционных систем (например, UNIX/SPARC). Пусть вас не смущает, что приводимые примеры в основном относятся к Windows NT и производным от нее системам. Просто в момент написания статьи другой операционной системы не оказалось под рукой.
Мясной рулет ошибок переполнения, или попытка классификации
Согласно «Новому словарю хакера» Эрика Раймонда ошибки переполнения буфера – это «то, что с неизбежностью происходит при попытке засунуть в буфер больше, чем тот может переварить». На самом деле, это всего лишь частный случай последовательного переполнения при записи. Помимо него существует индексное переполнение, заключающееся в доступе к произвольной ячейке памяти за концом буфера, где под «доступом» понимаются как операции чтения, так и операции записи.