Типы уязвимостей в операционной системе windows

Обновлено: 05.07.2024

Pentest_deep_23.3-5020-c58bfc.jpg

Третий модуль курса «Пентест. Практика тестирования на проникновение» посвящён структуре ОС Windows и тому, какие существуют механизмы ограничения доступа в этой популярной операционной системе. Но не менее важно знать, какие именно уязвимости используются злоумышленниками, чтобы обойти существующие механизмы ограничения доступа. О них и поговорим.

На момент написания материала из наиболее распространённых уязвимостей Windows можно выделить четыре:

1-20219-e64b0c.jpg

Давайте вкратце рассмотрим каждую из них.

Stack Corruption

Stack Corruption — это повреждение стека или массива данных, которые сохраняются на стеке.

2-20219-1ce07b.jpg

Как известно, все программы, которые запускаются на любых языках программирования, попадают в оперативную память. Хранятся они там в виде своеобразных «табличек», и эти таблички разделены на части: в одной части лежат команды, в другой части лежат данные и т. п. Так вот, там, где находятся данные, возможны ситуации, связанные со Stack Corruption.

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

Heap overflow

Речь идёт о переполнении, которое происходит на куче. «На куче» — это если программист написал приложение, которое очень много делает при обработке файлов, соответственно, вместо стека переполнение происходит на куче. Здесь как раз и происходит выполнение команд, то есть отсюда уже забирается информация, которая в дальнейшем будет открывать порт, дампить какие-нибудь значения или переконфигурировать операционную систему.

3-20219-f82690.jpg

Heap overflow — сложно диагностируемая ошибка, так как реализация кучи может быть собственной у каждого ПО.

Type Confusion and Use-After-Free

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

Use-After-Free (UAF) — уязвимость, при которой процесс может войти в неопределённое состояние. Сам этот класс уязвимости не приводит к проблемам, но при определённых условиях может быть произведено выполнение команд. Например, эти уязвимости могут позволить подменить значения в памяти, что, в свою очередь, может привести к выполнению вредоносного кода либо к остановке и выходу из строя самого приложения.


Количество обнаруженных уязвимостей

По данным mi2g, ущерб от различных видов атак достиг в 2004 г. $150 млрд., что примерно в два раза больше, чем в годом ранее. По мнению экспертов, ежегодно хакерами взламывается до 90% сетей предприятий

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

Основополагающие посылы защиты информации

Вероятность защищенности системы

1 в год

2 в год

5 в год

10 в год

1 нед.

2 нед.

1 мес.

2 мес.

3 мес.

4 мес.

Рассмотрим, например, значение “0,98” (лучшее значение надежности системы защиты в таблице). Оно достигается в том случае, если в среднем обнаруживается одна уязвимость в год при среднем времени ее восстановления разработчиком, составляющим одну неделю. При этом вероятность того, что в любой момент времени система защищена, равна 0,98, т.е. в любой момент времени с вероятностью 0,02 систему защиты можно считать отказавшей. Для современных систем это практически идеальная ситуация. Сегодня во многих современных системных средствах за год находится отнюдь не одна уязвимость, а продолжительность устранения уязвимости разработчиком может составлять несколько месяцев.

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

Статистика уязвимостей ОС семейства Windows

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

- получение имени и пароля ОС или БД. В эту группу входят уязвимости позволяющие узнать из файлов и реестра имена и пароли пользователей системы, включая имя и пароль администратора;

- получение имени и пароля других служб и приложений. Такие уязвимости позволяют сделать тоже, что и в первой группе, но с учетом того, что несистемные имена и пароли могут совпадать с системными;

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

- использование некорректных настроек файловой системы. Для ОС Windows применяются файловые системы FAT и NTFS. Есть различные версии этих файловых систем. Одни абсолютно не защищены (FAT), другие развиваются и включают все большее количество возможностей по защите (NTFS). Разрешения на чтение и запись в файловой системе позволяет узнавать конфиденциальную информацию и менять конфигурации ОС и приложений;

- подмена адреса программы, становится возможной, если получен доступ к реестру или файловой системе (см. предыдущие пункты). Замена стандартных программ с известными именами на вредоносные, возможно скрытые программы, позволяет незаметно внедряться в систему, расширяя права до прав системы или администратора;

- получение доступа к временным файлам (доступ к общим папкам неразделяемым ОС), Позволяет получить имена и пароли пользователей из временных файлов;

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

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

- перехват информации пользователя. Позволяет получить имена и пароли, вводимые пользователем с клавиатуры или прочитать конфиденциальную информацию так же вводимую пользователем;

- определение имени пользователя ( information leak). Часто удаленные атаки, совершаемые злоумышленниками, имеют своей целью сбор первичной информации об атакуемой системе, а ряд уязвимостей позволяет удаленно получать список пользователей системы или имя текущего пользователя. Это позволяет более осмысленно искать недостающие пароли;

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

- удаление и перезапись. Уязвимости этой группы позволяют удалять следы пребывания в системе злоумышленника, позволяя некорректно стирать и перезаписывать системные журналы событий;

Процентное соотношение количества уязвимостей в каждой из определенных групп для ОС Windows

Источник: CNews Analytics, 2005

Динамика изменения процентного соотношения уязвимостей

Динамика изменения процентного отношения доли уязвимостей, связанных с возможностью расширения привилегий пользователей

Источник: CNews Analytics, 2005

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

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

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

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

Уязвимости ПО на различных ОС

Почему существуют уязвимости и атаки

Атака — это процесс, нарушающий установленный в системе порядок. В контексте программного обеспечения такое воздействие может быть эквивалентно созданию состояния неопределенности: в этом случае состояние структур, используемых для работы программного обеспечения, может стать нестабильным. Атаки могут иметь серьезные последствия: от сбоя до потери пользовательских данных, поэтому изучение корней проблемы актуально сегодня. Чтобы понять, почему в приложении обнаруживаются уязвимости ПО, обратимся к основному «родителю» любого программного обеспечения — языку программирования. Объектом нашего исследования будет язык программирования C: многие части популярных операционных систем до сих пор пишутся с его использованием или из его эволюционной версии C ++.

Язык программирования C — это, по сути, набор команд, которые позволяют операционной системе взаимодействовать с устройствами и, таким образом, раскрывать их функциональность в полной мере. Для использования языка программирования в большом количестве систем необходимо, чтобы все его команды и результаты их выполнения всегда имели предсказуемые значения. Единственный способ добиться этого — создать стандарт, описывающий каждую конструкцию и команду языка программирования. За время существования языка программирования C было создано 6 версий стандарта (C89, C90, C95, C99, C11, C18).

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

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

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

Противодействие атакам

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

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

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

Портирование атаки

Представим себе сценарий — мы хотим изучить подход к эксплуатации уязвимостей Stack Buffer Overflow и UAF. С чего можно начать изучение? План изучения:

Найти описание особенности уязвимости;

Найти или создать уязвимое приложение;

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

В качестве тестовых будем использовать Windows 7 x86 и Kali Linux.

Особенности уязвимости: UAF

Описание уязвимости можно найти на ресурсе. Если вкратце, то данный тип уязвимостей связан с использованием объекта после его освобождения. Следовательно, атака должна создать на месте освобождаемого объекта тот, который позволит выполнить произвольный код. Графическое представление уязвимости ниже.

Уязвимости ПО на различных ОС

В качестве упражнения попробуйте найти пример уязвимого приложения для ОС Windows (любой версии), которое будет содержать UAF. Также подобных приложений много для ОС Linux. Попробуем адаптировать одно из таких приложений: чтобы оно было скомпилировано и для Windows, и для Linux, а также уязвимость воспроизводилась на обоих системах.

Уязвимое приложение: UAF

В качестве подопытного будем использовать следующее приложение:

Скомпилируем код под Windows и Linux:

Уязвимости ПО на различных ОС

Запуск на Linux:

Уязвимости ПО на различных ОС

апуск на Windows:


Поведение ОС: UAF

Уязвимость UAF в операционной системе очень сложно отследить, и для каждого отдельного случая следует писать специальные меры противодействия. Сам класс уязвимостей работает на основе доступа к данным, поэтому реализация защиты обычно представляет собой проверку целостности структур, важных для процесса. В нашем случае приложение не имеет доступа к этим структурам, поэтому никакой механизм защиты Windows и Linux не приведет к аварийному завершению работы приложения: процесс продолжит работу, что является проблемой безопасности и может быть использовано. Исходный пример самодостаточен и показывает, что эти уязвимости чаще всего используются из-за функциональности приложения. Что касается различий в реализации операционных систем, как указано выше, операционная система больше не важна, если ошибка заключается в неосторожных действиях самого приложения с памятью.

Особенности уязвимости: Stack Buffer Overflow

Уязвимость, которая имеет наибольшую популярность на сегодняшний день. Механизм работы Stack Buffer Overflow заключается в следующем. Данные, помещенные на стек, перетираются другими данными, заполняемыми в объекте, в котором не верно проверяется их размер. Картинка взята отсюда.


Уязвимое приложение: Stack Buffer Overflow

В качестве тестового будем использовать следующее приложение:

Скомпилируем приложение для Linux и для Windows:



В полученные файлы для защиты от атак добавляются специальные данные о механизмах защиты.Они помогают операционной системе противодействовать атакам. В ОС Linux посмотреть эти данные можно через специальную утилиту checksec .


Полный список технологий защит, которые были получены через вывод инструмента checksec , можно найти тут.

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


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

Эксплойт для уязвимого приложения: Stack Buffer Overflow

Самый простой тип уязвимости с точки зрения написания эксплойта. Проанализировав все механизмы защиты, которые задействованы в Linux, становится ясно, что единственный механизм — “NX Bit”. По всем описаниям в сети обойти данный механизма можно с помощью ROP. Для написания эксплойта будем использовать автоматизацию — pwntools для Python. Тогда скрипт для атаки на операционной системе Linux может иметь такой вид:

Эксплойт под Windows c применением ROP не дал результатов. Вывод его работы можно увидеть ниже.


Необходимо проводить дальнейший ресерч обходов защит системы. Против эксплойта сработали следующие механизмы защиты: SimExecFlow, DEP, SEHOP.

Вывод

Как видите, подходы к обеспечению безопасной работы приложений в операционных системах Linux и Windows различны. В случае Linux можно было использовать присущую приложению уязвимость. А Windows вовремя остановила приложение. Исследователи системной безопасности должны помнить об этом. Так что новичку следует использовать Linux в качестве отправной точки для тестирования уязвимых приложений. И искать в Windows лучшие методы обхода защиты операционной системы.

В данном цикле статей мы рассмотрим написание эксплоитов уровня ядра в ОС Windows.

image

Автор: Mohamed Shahat

Эта серия статей появилась по двум причинам. Во-первых, мне нравится работать с проектом HackSysExtremeVulnerableDriver. Во-вторых, я получил массу пожеланий, чтобы осветить эту тему.

Весь код, используемый при написании этой серии, находится в моем репозитории.

В данном цикле статей мы рассмотрим написание эксплоитов уровня ядра в ОС Windows. Важно отметить, что мы будем иметь дело с известными уязвимостями, и в реверс-инжиниринге нет необходимости (по крайней мере, для драйвера).

Предполагается, что после ознакомления со всеми статьями вы будете знать все наиболее распространенные классы брешей и методы эксплуатации, а также сможете портировать эксплоиты с архитектуры x86 на архитектуру x64 (если возможно) и ознакомитесь с новыми методами защиты в Windows 10.

Схема отладки ядра

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

Дополнительный материал для изучения:

Эксплуатация уязвимостей ядра

Этот процесс проходит намного веселее, чем эксплуатация на уровне пользователя J.

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

Темы статей этого цикла

  • Часть 1: Настройка рабочей среды
    • Конфигурирование трех виртуальных машин и системы, которая будет выступать в роли отладчика.
    • Конфигурирование отладчика WinDBG.
    • Изучение наиболее распространенных полезных нагрузок. В последующих частях будут рассматриваться конкретные уязвимости и, при необходимости, указываться ссылки на эту статью.
    • Рассмотрение уязвимостей.

    Жизненный цикл разработки эксплоита уровня ядра

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

    Типы целевых систем

    Мы будем работать с уязвимостями в следующих системах (конкретная версия не принципиальна):

    • Win7 x86 VM
    • Win7 x64 VM
    • Win10 x64 VM

    Начнем с архитектуры x86, и далее будем портировать эксплоит для системы Win7 x64. Некоторые эксплоиты не будут запускать на машинах с Win10 из-за присутствия новых защит. В этом случае мы либо будем изменять логику работы эксплоита, либо будем использовать полностью другой подход.

    Используемое программное обеспечение:

    • Гипервизор (масса вариантов).
    • Windows 7 x86 VM
    • Windows 7 x64 VM
    • Windows 10 x64 VM

    Настройка систем для отладки

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

    На каждой машине, которая будет отлаживаться, нужно сделать следующее:

    • Внутри директории VirtualKD запустите файл target\vminstall.exe. Добавится новая загрузочная запись и будут доступны функции отладки и автоматическое подключение к серверу VirtualKD, установленному в системе, которая выступает в роли отладчика.

    В случае с Windows 10 VM необходимо включить режим test signing, который позволяет загружать неподписанные драйвера в ядро.

    После выполнения команды bcdedit /set testsinging on и перезагрузки на рабочем столе появится надпись «Test Mode».

    • Запустите OSR Driver Loader. Зарегистрируйте и запустите службу. Возможно, потребуется перезагрузка.
    • Установите дополнения на гостевой виртуальной машине (необязательное условие).
    • Добавьте учетную запись с низкими привилегиями, которая понадобится во время эксплуатации.

    C:\Windows\system32>net user low low /add
    The command completed successfully.

    Настройка отладчика

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

    Хост VirtualKD будет выполнять коммуникацию автоматически через именованный канал, вместо установки соединения вручную. Если вы отлаживаете через сеть в Win10 VM, потребуется протестировать соединение вручную.

        • Установите Windows SDK. Вы можете выбрать только «Debugging Tools for Windows».
        • Проверьте, что установлен отладчик WinDBG. По умолчанию используется папка C:\Program Files (x86)\Windows Kits\10\Debuggers.

        Добавьте этот путь в качестве системного и установите путь к отладчику в VirtualKD

        Перезапустите гостевые виртуальные машины. Система с VirtualKD, используемая в качестве отладчика, должна быть запущена. После перезагрузки вы сможете начать сессию в WinDBG.

        Настройка WinDBG


        Если все настроено корректно, WinDBG поставит выполнение на паузу и отобразит некоторую информацию, касающуюся целевой системы.

        Рисунок 1: Остановка выполнения кода ядра

        Символы содержат отладочную информацию для множества бинарных файлов в ОС Window. Загрузить символы можно при помощи следующей команды:

        Включаем режим подробного информирования процесса отладки.

        ed nt!Kd_Default_Mask 0xf

        Должен загрузиться модуль HEVD:

        kd> lm m HEVD
        Browse full module list
        start end module name
        fffff80b`92b50000 fffff80b`92b59000 HEVD (deferred)

        Сохраняем настройки профиля и любые изменения рабочей среды:

        File -> Save Workspace to File

        Введите команду g или нажмите клавишу F5 для продолжения выполнения (перечень других команд, которые вам могут пригодиться, хорошо описан в этом документе).

        Краткое описание модуля HEVD

        Процедура DriverEntry является стартовой для каждого драйвера:

        NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) UINT32 i = 0;
        PDEVICE_OBJECT DeviceObject = NULL;
        NTSTATUS Status = STATUS_UNSUCCESSFUL;
        UNICODE_STRING DeviceName, DosDeviceName = ;

        RtlInitUnicodeString(&DeviceName, L"\\Device\\HackSysExtremeVulnerableDriver");
        RtlInitUnicodeString(&DosDeviceName, L"\\DosDevices\\HackSysExtremeVulnerableDriver");

        // Create the device
        Status = IoCreateDevice(DriverObject,
        0,
        &DeviceName,
        FILE_DEVICE_UNKNOWN,
        FILE_DEVICE_SECURE_OPEN,
        FALSE,
        &DeviceObject);

        • Эта процедура содержит вызов функции IoCreateDevice, содержащей имя драйвера, которое мы будем использовать во время коммуникации.
        • В объект DriverObject будут добавлены нужные структуры и указатели на функции.
        • Для нас важен указатель функции, связанный с процедурой DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL], отвечающей за обработку IOCTL (I/O Control; управление вводом/выводом);
        • В HEVD эта функция называется IrpDeviceIoCtlHandler, которая представляет собой большое условное выражение со множеством ответвлений для каждого IOCTL. Каждая уязвимость имеет уникальный IOCTL.

        Пример: HACKSYS_EVD_IOCTL_STACK_OVERFLOW представляет собой IOCTL, используемый для активации бреши, связанной с переполнением стека.

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

        Читайте также: