Один из самых интересных типов программного кода полезной нагрузки известен под названием вложенного программного кода полезной нагрузки (eggshellpayload). Под вложенностью понимается использование одного кода полезной нагрузки внутри другого. Цель подобных манипуляций заключается в использовании программы с незначительными правами и внедренным кодом полезной нагрузки для атаки на привилегированную программу.

Этот способ позволяет с помощью простой программы переполнения буфера сначала переступить одной ногой через порог, а затем с бандой вломиться в дом. Благодаря нему результат достигается с меньшими усилиями и за меньшее время, поскольку нападение комплексное: удаленная атака на непривилегированный процесс объединяется с локальным нападением на привилегированный процесс, образуя разрушительную комбинацию.

Вложенный программный код полезной нагрузки использован в программе IISHACK1.5, которая компрометирует Windows NT Server с установленным информационным сервером Интернет IIS 4. Подробный анализ программы и ее код можно найти в документе www.eeye.com/html/Research/Advisories/AD20001003.html. Для внедрения программой asp-файла на сервер был использован непривилегированный код, реализующий атаку «Unicode». Атака «Unicode» выполняется в пространстве процесса IUSR MACHINE, который обычно является непривилегированным процессом.

Атака «Unicode» была объединена с атакой переполнения буфера на неназванный синтаксический анализатор. ASP, который выполнялся в контексте LOCAL SYSTEM. Их комбинация позволила добиться полной компрометации системы.

Резюме

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

Обязательным условием понимания приведенных в главе способов переполнения буфера является знание принципов работы стека. Стек используется почти каждой функцией для передачи входных и выходных параметров. Регистр ESP указывает на вершину локального стека, а регистр EBP - на базовый регистр стека. При вызове функции содержимое регистров ЕГР и EBP сохраняется в стеке для того, чтобы в конце работы функции обеспечить дальнейшую работу программы.

Атаки переполнения буфера обыгрывают идею подмены сохраненного в стеке содержимого регистра EIP и передачи управления на нужный программный код. Успешная реализация идеи позволит выполнить на машине любую программу. Для успешного использования уязвимости необходимо иметь загрузчик, точку перехода, программный код полезной нагрузки и программу переполнения буфера. Загрузчик размещает в нужное место программный код полезной нагрузки, точка перехода позволяет передать управления на нужную программу - программный код полезной нагрузки, а программа переполнения буфера управляет их работой.

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

Конспект

Стек

• Область стека предназначена для хранения локальных переменных функции. Обычно она настраивается для работы в прологе функции - части программного кода, расположенного в начале функции, и очищается в эпилоге - части программного кода, расположенного в ее конце.

• Нередко отдельные части области стека используются как буферы данных функции. Из-за особенностей принципов работы стека размер буфера данных не изменяется на протяжении всей жизни функции.

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

Стековый фрейм функции

• Стековый фрейм функции - область памяти, выделяемая всякий раз, когда вызывается функция. Она предназначается для временного хранения параметров, локальных переменных функции, оставшегося от предыдущего вызова функции содержимого регистра EBP и содержимого регистра EIP, указывающего на точку возврата.

• Содержимое регистра ESP указывает на вершину стека, содержимое регистра EBP -на дно. Значение регистра ESP метается по мере выталкивания и проталкивания данных в стек. Регистр EBP обычно является базовым регистром для ссылки на локальные стековые переменные.

• Команды процессора Intel call и rel позволяют вызывать и завершать функцию. По команде call в стеке сохраняется содержимое регистра EIP, которое указывает на точку возврата. По команде ret из стека восстанавливается значение регистра EIP и управление передается в точку возврата из функции.

Основы переполнения буфера

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

• Поскольку по команде ret в регистр EIP будут загружены данные из стека, то при перезаписи области хранения в стеке содержимого регистра EIP данными пользователя команда ret загрузит в регистр адрес перехода, указанный пользователем.

Пример программы, уязвимой к переполнению буфера

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

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

• Адрес перехода - адрес, который подменяет сохраненное в стеке содержимое регистра EIP. Имеется много возможностей для подмены содержимого регистра EIP с целью непосредственной или косвенной передачи управления нужной программе. Ряд способов позволяет повысить надежность передачи управления, например к ним относятся способ последовательности операций NOP (NOP sleds) или способ распыления динамически распределяемой памяти (heap spray).

• Программный код полезной нагрузки - это код, который стремится выполнить нападающий и который может делать все, что угодно. Анализируя результаты дизассемблирования прототипа программного кода полезной нагрузки на языке С, получают его окончательный вариант в виде последовательности машинных команд. Обычно код полезной нагрузки состоит из самых необходимых команд процессора, чтобы максимально сжать программный код, сэкономить место и время его доставки.

Современные способы переполнения буфера

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

• Иногда вместо подмены сохраненного в стеке содержимого регистра EIP возможны только частичное переполнение буфера или подмена значений в отдельных областях стека. Этого оказывается достаточным для передачи управления нужной программе. Требуется лишь подпортить данные в нужном месте стека, чтобы в дальнейшем произошло переполнение буфера и была вызвана нужная программа. Или в стеке подменить указатель функции, чтобы при ее вызове опять же вызвать нужную программу.

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

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

• В программном коде полезной нагрузки может использоваться уже загруженный обычным способом программный код. Это позволит уменьшить размер программного кода полезной нагрузки и предоставит возможность воспользоваться готовыми заготовками программ в своих целях. Не следует забывать, что зачастую в память загружено больше программного кода, чем это нужно. Поэтому исследование памяти процесса поможет найти полезный, предварительно загруженный код.

• Если для программы переполнения буфера чего-то не хватает, не бойтесь самостоятельно догрузить необходимое. Загружая динамические библиотеки, можно загрузить любой код, уже существующий на машине. Это даст практически неограниченные возможности для написания программного кода полезной нагрузки.

• Вложенный программный код полезной нагрузки позволяет скомпрометировать систему. Основная идея вложенного программного кода полезной нагрузки заключается в использовании одним кодом полезной нагрузки с незначительными правами другой уязвимости для загрузки нового кода полезной нагрузки в память привилегированного процесса.

Часто задаваемые вопросы

Наиболее часто авторы книги отвечали на приведенные ниже вопросы. Вопросы интересны тем, что они позволяют читателю лучше усвоить изложенный в главе материал и реализовать его на практике для обеспечения безопасности вычислительных систем. Если у читателя возникли вопросы по главе, зайдите на сайт www.syngress.com/solutions и щелкните мышкой на кнопке «Ask the Author».

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

Вопрос: Где можно глубже познакомиться с вопросами переполнения буфера? Ответ: Чтение списков рассылки типа Bugtraq (www.securityfocus.com) и сопутствующие статьи об атаках переполнения буфера в журналах типа «Phrack» помогут значительно углубить знания в этой области.

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

Вопрос: Переполняются только буферы? Ответ: Фактически любое неправильное использование стековых переменных может привести к переполнению буфера. Этот тип уязвимости присущ программам, написанным на языке программирования с недостаточным контролем типов используемых данных, например на языке С. В последнее время возросли последствия от переполнения буфера, о чем свидетельствуют, например, локальная компрометация Sendmail (www.securityfocus.com/bid/3163) и найденная удаленная уязвимость в SSH1 (www.securityfocus.com/bid/2347). Подобные уязвимости трудны для обнаружения автоматическим инструментарием и могут доставить серьезные проблемы в будущем.

Вопрос: Каким образом можно обнаружить переполнение буфера? Ответ: Существует ряд способов для локализации в программе ошибок переполнения буфера. При наличии исходного текста атакованного приложения можно воспользоваться рядом разнообразных инструментальных средств, предназначенных для определения проблемных участков кода. Например, ITS4 (www.cigital.com/services/its4) или FlawFinder

(www.dwheeler.com/flawfinder). Но и без исходных текстов доступен ряд способов. Один из них - проверка входных данных. Многочисленные инструментальные средства пригодны для контроля полей ввода информации в программах общего применения. К ним относится компонента контроля общесетевых протоколов СНАМ (common hacker attack methods -общие методы хакерских атак) программы eEyeVs Retina (www.eEye.com), написанная автором. Дэйв Айтел (Dave Aitel) из @Stake написал для API программу SPIKE (www.atstake.com/research/tools/spike-vl.8.tar.gz), которая проверяет входные данные Web-приложений. Один из недавно появившихся способов обнаружения уязвимости переполнения буфера основан на ревизии выполнимого кода. Ревизия выполнимого кода основана на пользовательских средствах поиска характерных комбинаций машинных команд. Пока подобных общедоступных средств мало, но в скором времени ожидается рост их числа. При желании можно изучить даже некоторые инструментальные средства атак.

Загрузка новых динамически подключаемых библиотек | Защита от хакеров корпоративных сетей | Ошибки форматирующей строки


Защита от хакеров корпоративных сетей



Новости за месяц

  • Июль
    2019
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс