Как отключить cfg в windows 10

После апдейта до 1709 (Fall Creators Update) ПК и ноутбуки на Windows 10 значительно потеряли в производительности и быстродействии. Это связано с интеграцией новой функции в систему под названием

Как в Windows 10 отключить CFG

Посмотрело: 3 979

CFG windows 10

После апдейта до 1709 (Fall Creators Update) ПК и ноутбуки на Windows 10 значительно потеряли в производительности и быстродействии.

Это связано с интеграцией новой функции в систему под названием Control Flow Guard (cfg). Она направлена на борьбу с различными уязвимостями, но создает большую нагрузку на ОС и снижают ее производительность. Даже возможны зависания и лаги при работе или в играх.

Пока Microsoft не «пофиксел» эту неприятность, стоит ее деактивировать.

1. Запускаем ‘Защитник Windows«;
2. Открываем в нем «Управление приложениями и браузеров«;
3. Находим пункт «Параметры защиты от эксплойт«;
4. Там отключаем «защиту CFG (Control Flow Guard)«

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

Категория: Полезная информация

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

Встроенная функция безопасности Windows 10 – Control Flow Guard (CFG) предназначена для борьбы с уязвимостями повреждения памяти. Control Flow Guard помогает предотвратить повреждение памяти, что очень помогает предотвратить атаки вымогателей. Возможности сервера ограничены тем, что необходимо в этот момент времени, чтобы уменьшить поверхность атаки. Защита от эксплойтов является частью функции защиты от эксплойтов в Защитнике Windows. CFG является частью этой функции.

Содержание

  1. Контроль Flow Guard в Windows 10
  2. 1] Что такое Control Flow Guard и как он работает
  3. 2] Как Control Flow Guard влияет на производительность браузера
  4. 3] Как отключить Control Flow Guard в Windows 10

Контроль Flow Guard в Windows 10

Давайте немного углубимся в функцию Control Flow Guard в Windows 10 и ответим на несколько вопросов, таких как:

  1. Что такое Control Flow Guard и как он работает?
  2. Как Control Flow Guard влияет на производительность браузера?
  3. Как отключить Control Flow Guard?

1] Что такое Control Flow Guard и как он работает

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

Чтобы избежать таких случаев, мощная комбинация поддержки компиляции и времени выполнения от Control Flow Guard реализует целостность потока управления, которая жестко ограничивает места, где могут выполняться инструкции косвенного вызова. Он также определяет набор функций в приложении, которые могут быть потенциальными целями для косвенных вызовов. Таким образом, Control Flow Guard добавляет дополнительные проверки безопасности, которые могут обнаружить попытки взлома исходного кода.

Когда проверка CFG не выполняется во время выполнения, Windows немедленно завершает работу программы, тем самым устраняя любую уязвимость, которая пытается косвенно вызвать неверный адрес.

2] Как Control Flow Guard влияет на производительность браузера

Сообщается, что эта функция вызывает проблемы с производительностью браузеров на базе Chromium. Все основные браузеры, такие как Google Chrome, Microsoft Edge browser, Vivaldi и многие другие, похоже, пострадали от этого. Эта проблема обнаружилась, когда разработчики Vivaldi запустили модульные тесты Chromium в Windows 7 и обнаружили, что они работают быстрее, чем в самой последней версии Windows 10.

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

3] Как отключить Control Flow Guard в Windows 10

Если вы хотите отключить эту функцию, следуйте этой процедуре.

Нажмите Пуск и найдите Безопасность Windows .

Выберите «Безопасность Windows» на левой панели раздела « Обновление и безопасность » в настройках Защитника Windows.

Выберите « Управление приложениями и браузером » и прокрутите вниз, чтобы найти « Настройки защиты от эксплойтов ». Выберите его и выберите Control Flow Guard ’.

Нажмите стрелку раскрывающегося списка и выберите «Выключить по умолчанию».

Надеюсь, это поможет.

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

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

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

Оказалось, что Microsoft добавила во все компьютеры на базе Windows 10 новую разработку под названием Control Flow Guard. Это своего рода специальная защита, направленная на борьбы с уязвимостями, связанными с повреждениями памяти. Защита защитой, но она в несколько раз снижает скорость работы всей операционной системы, причем отключить ее, на первый взгляд, невозможно.

К счастью, была обнаружена скрытая настройка, которая значительно повышает скорость работы всех компьютеров на Windows 10. Для этого необходимо запустить «Защитник Windows», а затем перейти в раздел «Управление приложениями и браузеров». Потребуется открыть подраздел «Параметры защиты от эксплойт», после чего отключить защиту CFG (Control Flow Guard). Чтобы все начало работать потребуется перезагрузить компьютер.

После выполнения этих действий и перезагрузки компьютера, он начнет работать в разы быстрее, поскольку фирменная система защиты Control Flow Guard перестанет использоваться. Зачем Microsoft принудительно включала эту настройку для всех – неизвестно, однако на форумах компании уже имеются десятки тысяч отзывов от пользователей, которые жалуются на медленную работу операционной системы Windows 10 из-за такого нововведения.

Как отключить Control Flow Guard

Совершенно случайно наткнулся на статью о системе защиты Control Flow Guard, которая появилась в Windows 10 и Windows 8.1 Update 3 после одного из обновлений. Оказывается это технология сильно тормозит работу компьютера, особенно это ощущается на ПК без SSD диска.

Вот как было у меня:

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

Обновился до Windows 10 в один из последних дней возможного бесплатного перехода на новую операционную систему и сразу заметил как упала скорость работы по сравнению с восьмеркой. Возможности откатить на Windows 8 уже не было. Пришлось «наслаждаться» тем что имеем.

И вот спустя почти год я вдруг узнал, что есть такая программа как Control Flow Guard и она всему виной. Как говорится — «Лучше поздно, чем никогда!».

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

В любом случае интересно провести эксперимент и сравнить скорость загрузки и работы ноутбука с CFG и без неё. Сказано — сделано!

Как отключить Control Flow Guard в Windows 10

У кого стоит Windows 8, думаю, по аналогии не составит труда разобраться ведь отключается CFG в защитнике виндоус. Для наглядности прилагаю скриншот ниже.

  1. Заходим в Защитник Windows.
  2. Переходим на вкладку «Управление приложениями и браузером».
  3. Находим там защиту потока управления и в выпадающем списке ставим значение «Выкл, по умолчанию».
  4. Перезагружаем компьютер и наслаждаемся более быстрой загрузкой.

Отключаем control flow guard

На чтение 4 мин. Опубликовано 15.12.2019

Совершенно случайно наткнулся на статью о системе защиты Control Flow Guard, которая появилась в Windows 10 и Windows 8.1 Update 3 после одного из обновлений. Оказывается это технология сильно тормозит работу компьютера, особенно это ощущается на ПК без SSD диска.

Вот как было у меня:

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

Обновился до Windows 10 в один из последних дней возможного бесплатного перехода на новую операционную систему и сразу заметил как упала скорость работы по сравнению с восьмеркой. Возможности откатить на Windows 8 уже не было. Пришлось «наслаждаться» тем что имеем.

И вот спустя почти год я вдруг узнал, что есть такая программа как Control Flow Guard и она всему виной. Как говорится — «Лучше поздно, чем никогда!».

Содержание

  1. Что такое Control Flow Guard
  2. Как отключить Control Flow Guard в Windows 10
  3. Default Settings
  4. Default Behavior
  5. Dependencies
  6. Restore Default Startup Configuration for DevicesFlow

Что такое Control Flow Guard

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

В любом случае интересно провести эксперимент и сравнить скорость загрузки и работы ноутбука с CFG и без неё. Сказано — сделано!

Как отключить Control Flow Guard в Windows 10

У кого стоит Windows 8, думаю, по аналогии не составит труда разобраться ведь отключается CFG в защитнике виндоус. Для наглядности прилагаю скриншот ниже.

  1. Заходим в Защитник Windows.
  2. Переходим на вкладку «Управление приложениями и браузером».
  3. Находим там защиту потока управления и в выпадающем списке ставим значение «Выкл, по умолчанию».
  4. Перезагружаем компьютер и наслаждаемся более быстрой загрузкой.

Allows ConnectUX and PC Settings to Connect and Pair with WiFi displays and Bluetooth devices.

Default Settings

Startup type: Manual
Display name: DevicesFlow
Service name: DevicesFlowUserSvc
Service type: user share process template
Error control: normal
Object: LocalSystem
Path: %SystemRoot%system32svchost.exe -k DevicesFlow
File: %SystemRoot%System32DevicesFlowBroker.dll
Registry key: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesDevicesFlowUserSvc

Default Behavior

In Windows 10 it is starting only if the user, an application or another service starts it. If DevicesFlow fails to start, the failure details are being recorded into Event Log. Then Windows 10 will start up and notify the user that the DevicesFlowUserSvc service has failed to start due to the error.

Dependencies

DevicesFlow cannot be started under any conditions, if the Remote Procedure Call (RPC) service is disabled.

Restore Default Startup Configuration for DevicesFlow

1. Run the Command Prompt as an administrator.

2. Copy the command below, paste it into the command window and press ENTER:

sc config DevicesFlowUserSvc start= demand

3. Close the command window and restart the computer.


Некоторые пользователи после обновления до Windows 10 Fall Creators Update (1709) могли замтетить, что окна в Проводнике открываются очень медленно, а файлы в папках подгружаются поэтапно. Все это очень похоже на то, что в системе отсутствует корректный драйвер на видеокарту, но это не так — у вас вполне могут идти новые 3D-игры и. лагать Проводник.

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

Отключить ее просто — для этого нужно зайти в Защитник Windows > Управление приложениями и браузером > Параметры защиты от эксплойтов и выключить CFG:

После этого нужно перезагрузиться, и Проводник снова должен начать работать быстро.

Компания Microsoft не оставляет попыток победить в бесконечной войне с эксплоитописателями, раз за разом реализуя новые техники по защите приложений. На сей раз разработчики операционной системы Windows подошли к решению данного вопроса более фундаментально, переведя свой взгляд на корень проблемы. Работа почти каждого эксплоита так или иначе нацелена на перехват потока исполнения приложения, следовательно, не помешало бы «научить» приложения следить за этим моментом.
Концепия Control Flow Integrity (целостность потока исполнения) была описана еще в 2005 году. И вот, 10 лет спустя, разработчики из компании Microsoft представили свою неполную реализацию данного концепта — Control Flow Guard.

Что такое Control Flow Guard

Control Flow Guard (Guard CF, CFG) — относительно новый механизм защиты Windows (exploit mitigation), нацеленный на то, чтобы усложнить процесс эксплуатации бинарных уязвимостей в пользовательских приложениях и приложениях режима ядра. Работа данного механизма заключается в валидации неявных вызовов (indirect calls), предотвращающей перехват потока исполнения злоумышленником (например, посредством перезаписи таблицы виртуальных функций). В сочетании с предыдущими механизмами защиты (SafeSEH, ASLR, DEP и т.д.) являет собой дополнительную головную боль для создателей эксплоитов.
Данная секьюрити фича доступна пользователям ОС Microsoft Windows 8.1 (Update 3, KB3000850) и Windows 10.
Компиляция программ с поддержкой CFG доступна в Microsoft Visual Studio 2015 (как включить?).

Аналогичная реализация механизма защиты на основе концепции Control Flow Integrity для ОС семейства Linux имеется в расширении PaX.

Как работает Control Flow Guard

Рассмотрим принцип работы CFG в пользовательском режиме. Данный механизм имеет два основных компонента: битовую карту адресов (управляется ядром) и процедуру проверки указателя вызываемой функции (используется пользовательскими приложениями).
Вся служебная информация CFG заносится в IMAGE_LOAD_CONFIG_DIRECTORY исполняемого файла во время компиляции:

  • GuardCFCheckFunctionPointer — указатель на процедуру проверки
  • GuardCFFunctionTable — таблица валидных адресов функций (используется ядром для инициализации битовой карты)
  • GuardCFFunctionCount — количество функций в таблице
  • GuardFlags — флаги

В заголовок IMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics заносится флаг IMAGE_DLLCHARACTERISTICS_GUARD_CF, показывающий, что данный исполняемый файл поддерживает механизм CFG.

Всю служебную информацию можно посмотреть при помощи инструмента dumpbin.exe из Microsoft Visual Studio 2015 (Microsoft Visual Studio 14.0VCbindumpbin.exe), запустив его с ключом /loadconfig.

GuardFlags

Заголовочный файл winnt.h для Windows 10 (1511) содержит следующие флаги CFG (последний является маской, а не флагом):

  • IMAGE_GUARD_CF_INSTRUMENTED (0x00000100) — Модуль производит проверки потока исполнения при поддержке системы
  • IMAGE_GUARD_CFW_INSTRUMENTED (0x00000200) — Модуль производит проверки целостности потока исполнения и записи
  • IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT (0x00000400) — Модуль содержит таблицу валидных функций
  • IMAGE_GUARD_SECURITY_COOKIE_UNUSED (0x00000800) — Модуль не использует security cookie (/GS)
  • IMAGE_GUARD_PROTECT_DELAYLOAD_IAT (0x00001000) — Модуль поддерживает Delay Load Import Table, доступную только для чтения
  • IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION (0x00002000) — Delay Load Import Table находится в своей собственной .didat секции
  • IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK (0xF0000000) — Шаг одного элемента таблицы валидных функций Guard CF кодируются в данных битах (дополнительное количество байтов для каждого элемента)

Стоит отметить, что это неполный список существующих флагов. Наиболее полный список можно получить из внутренностей файла link.exe (компоновщик):

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

Битовая карта

Во время загрузки ОС ядром (функция nt!MiInitializeCfg) создается битовая карта nt!MiCfgBitMapSection, которая является общей (shared) секцией для всех процессов. При запуске процесса, поддерживающего CFG, происходит отображение (mapping) битовой карты в адресное пространство процесса. После чего адрес и размер битовой карты заносятся в структуру ntdll!LdrSystemDllInitBlock.
Сопоставлением адресов функций с битами в битовой карте занимается загрузчик исполняемых файлов (функция nt!MiParseImageCfgBits). Каждый бит в битовой карте отвечает за 8 байт пользовательского адресного пространства процесса. Адреса начала всех валидных функций соотносятся с единичным битом по соответствующему смещению в битовой карте, а всё остальное — 0.

Процедура проверки указателя вызываемой функции

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

Оригинальный код на C++:

class CSomeClass
{
public:
    virtual void doSomething()
    {
        std::cout << "hello";
    }
};

int main()
{
    CSomeClass *someClass = new CSomeClass();
    someClass->doSomething();

    return 0;
}

ASM листинг (вырезка):

mov eax, [ecx] ; EAX = CSomeClass::vftable
call dword ptr [eax] ; [EAX] = CSomeClass::doSomething()

С ключом компиляции /guard:cf :

mov eax, [edi] ; EAX = CSomeClass::vftable
mov esi, [eax] ; ESI = CSomeClass::doSomething()
mov ecx, esi
call ds:___guard_check_icall_fptr ; checks that ECX is valid function pointer
mov ecx, edi
call esi

В первом случае код подвержен атаке с использованием техники подмены таблицы виртуальных функций. Если атакующий при эксплуатации уязвимости способен перезаписать данные объекта, то он может подменить таблицу виртуальных функций таким образом, что вызов функции someClass->doSomething() приведет к выполнению контролируемого атакующим кода, тем самым перехватив поток исполнения приложения.
В случае же использования Control Flow Guard, адрес вызываемой функции предварительно будет сверен с битовой картой. Если соответствующий бит будет равен нулю, произойдет программное исключение.

При запуске данного приложения на ОС, которые поддерживают механизм Guard CF, загрузчик исполняемых файлов построит битовую карту и перенаправит адрес проверяющей процедуры на функциюntdll!LdrpValidateUserCallTarget.
Данная функция в ОС Windows 10 (build 1511) реализована следующим образом:

Изучим алгоритм данной функции на примере входного адреса 0x0B3385B0.

B3385B016 = 10110011001110000101101100002

Проверяемый адрес данная функция получает через регистр ecx. В регистр edx заносится адрес битовой карты. В моем случае битовая карта расположилась по адресу 0x01430000.

Три байта (24 бита) старшего порядка (подчеркнуты) адреса соответствуют смещению в битовой карте. В данном случае смещение будет равно 0xB3385. Единица измерения битовой карты равна 4 байтам (32 бита), поэтому для получения нужной ячейки необходимо вычислить базовый адрес карты + смещение * 4. Для данного примера получаем 0x01430000 + 0xB3385 * 4 = 0x16FCE14. Значение ячейки битовой карты записывается в регистр edx.

Целевую ячейку получили, теперь требуется определить номер интересующего нас бита. Номером является значение следующих 5 бит адреса (выделены жирным). Но нужно учитывать, что если проверяемый адрес не выравнен по границе 16 байт (address & 0xf != 0), то использоваться будет нечетный бит (offset | 0x1). В данном случае адрес выравнен и номер бита будет равен 101102 = 2210.

Теперь остается только проверить значение бита, проведя bit test. Инструкция bt проверяет значение бита первого регистра, порядковый номер которого берется из 5 младших бит (по модулю 32) второго регистра. В случае, если бит равен 1, будет выставлен Carry Flag (CF) и программа продолжит свое выполнение в обычном режиме.

В ином случае будет вызвана функция ntdll!RtlpHandleInvalidUserCallTarget и работа программы завершится 29-ым прерыванием с параметром 0xA на стеке, что означает nt!_KiRaiseSecurityCheckFailure(FAST_FAIL_GUARD_ICALL_CHECK_FAILURE).

Проверив 22-ой бит, можно убедиться, что адрес вызываемой функции является валидным.

Реализация данного алгоритма на Python выглядит следующим образом:

def calculate_bitmap_offset(addr):
    offset = (addr >> 8) * 4
    bit = (addr >> 3) % 32
    aligned = (addr & 0xF == 0)
    if not aligned:
        bit = bit | 1
    print "addr = 0x%08x, offset = 0x%x, bit index = %u, aligned? %s" % (addr, offset, bit, "yes" if aligned else "no")

calculate_bitmap_offset(0x0B3385B0)

Результат работы скрипта:

addr = 0x0b3385b0, offset = 0x2cce14, bit index = 22, aligned? yes

Исключения

Не во всех случаях вызов невалидной функции будет заканчиваться 29-ым прерыванием. В функции ntdll!RtlpHandleInvalidUserCallTarget происходят следующие проверки:

  • Включен ли DEP для текущего процесса
  • Имеет ли целевой адрес необходимые права (PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE)
  • Разрешены ли «suppressed» вызовы — ntdll!RtlGuardAllowSuppressedCalls
  • Является ли целевой адрес «suppressed» — ntdll!RtlpGuardIsSuppressedAddress

Псевдокод данной функции выглядит следующим образом:

Официальная информация про «suppressed» вызовы отсутствует. Можно лишь сказать, что данные вызовы требуют поддержку компилятора — должна быть установлена маска IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK во флагах GuardFlags и компилятор должен сгенерировать расширенную таблицу. В байтах, соответствующих данной маске, хранится значение дополнительного размера для элементов таблицы GuardCFFunctionTable. Если адрес функции является «suppressed», то байт, следующий за адресом, должен быть равен единице.
Разрешить «suppressed» вызовы можно, например, с помощью ветки реестра HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options, установив параметр CFGOptions для требуемого приложения в значение 1.

Слабые места Control Flow Guard

Как и любой другой защитный механизм, CFG имеет некоторые слабые места:

  • Выключенный DEP процесса влечет за собой потерю смысла проверок CFG, поскольку функция ntdll!RtlpHandleInvalidUserCallTarget в таком случае будет всегда разрешать исполнение невалидного адреса.

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

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

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

  • За каждые 8 байт адресного пространства отвечает 1 бит, но, на самом деле, 1 выравненный адрес соотносится с одним четным битом, при этом следующий нечетный бит соотносится сразу с 15 байтами адресного пространства. Убедиться в этом можно, запустив приведенный выше Python скрипт в цикле и проанализировав результат:

    addr = 0x08f38480, offset = 0x23ce10, bit index = 16, aligned? yes
    addr = 0x08f38481, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38482, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38483, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38484, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38485, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38486, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38487, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38488, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38489, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f3848a, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f3848b, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f3848c, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f3848d, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f3848e, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f3848f, offset = 0x23ce10, bit index = 17, aligned? no
    addr = 0x08f38490, offset = 0x23ce10, bit index = 18, aligned? yes
    addr = 0x08f38491, offset = 0x23ce10, bit index = 19, aligned? no
    addr = 0x08f38492, offset = 0x23ce10, bit index = 19, aligned? no
    addr = 0x08f38493, offset = 0x23ce10, bit index = 19, aligned? no
    addr = 0x08f38494, offset = 0x23ce10, bit index = 19, aligned? no
    ...

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

  • Динамически генерируемые функции (например, JIT-функции) требуют особого внимания от разработчиков, поскольку необходимо обеспечить проверки неявных вызовов на стадии генерирования функций. В добавок к этому, необходимо учитывать, что стандартное поведение функций ntdll!NtAllocVirtualMemory и ntdll!NtProtectVirtualMemory заключается в проставлении единичного бита для всего региона памяти в битовой карте Control Flow Guard, если память становится исполняемой (PAGE_EXECUTE_*).

  • CFG не способен предотвратить перехват потока исполнения при модификации атакующим адреса возврата функции.

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

Реализация обхода Control Flow Guard на примере Adobe Flash Player

Начиная с Windows 8 плагин Adobe Flash Player интегрирован в Internet Explorer, а с Windows 8.1 (Update 3) он поставляется с поддержкой CFG. Существует несколько реализаций обхода Control Flow Guard в эксплоитах под Adobe Flash Player, некоторые из которых актуальны и по сей день.

Обход при помощи динамического кода

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

Отсутствие проверок неявных вызовов в динамическом коде

Данный метод был предложен и реализован исследователем Francisco Falcón из Core Security в своем анализе эксплоита для уязвимости CVE-2015-0311. Оригинальная статья довольно хорошо и подробно описывает процесс реализации обхода. Суть метода заключается в модификации внутренней таблицы виртуальных функций определенного ActionScript класса. После чего один из методов данного класса должен быть вызван из тела динамически сгенерированной функции. Для данной цели хорошо подходит класс ByteArray.
Структура объекта ByteArray:

По смещению $+8 находится указатель на объект класса VTable:

Класс VTable является внутренним представлением виртуальной таблицы функций (то есть не той, которую генерирует C++) для классов ActionScript.
Объект данного класса содержит в себе указатели на объекты класса MethodEnv:

Данный класс представляет собой описание метода ActionScript и содержит указатель на тело функции в памяти по смещению $+4.

В объекте VTable по смещению $+D4 находится описание метода ByteArray::toString(). Имея возможность произвольно читать и писать в память, атакующий способен изменить указатель функции на тело функции (MethodEnv + 4) и благополучно перехватить поток исполнения приложения, выполнив ByteArray::toString().

Такое становится возможным по причине того, что метод данного класса будет вызываться из JIT-кода:

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

Данный метод обхода CFG был исправлен с выходом Adobe Flash Player версии 18.0.0.160 (KB3065820, Июнь 2015). Исправление заключается в следующем: если JIT-функция содержит неявный вызов, то JIT-компилятор вставит вызов процедуры проверки непосредственно перед неявным вызовом.

Любой адрес в пределах тела динамической функции является валидным

Предыдущий метод обхода был возможен из-за недочета в функции, которая производит неявный вызов. А данный метод возможен из-за недочета в функции, которую неявно вызывют.
Исследователи Юрий Дроздов и Людмила Дроздова из Center of Vulnerability Research представили данный метод обхода CFG на конференции Defcon Russia (Санкт-Петербург, 2015) (презентация, статья). Их метод основан на том факте, что при выделении исполняемой памяти ядро выставляет единичный бит в битовой карте CFG для всей выделенной памяти. Посмотрим, к чему может привести такое поведение.

Предположим, что существует некая JIT-функция по адресу 0x69BC9080, в теле которой находится следующий код:

Что именно делает эта функция, нас не интересует, нужно лишь обратить внимание на 2 байта FF D0 инструкции по адресу 0x69BC90F0. Что будет, если начало функции вдруг сдвинется в середину данной инструкции? Вот что:

FF D0 — не что иное, как call eax! Вот так безобидная на первый взгляд функция превратилась в прекрасную цель для атакующего — неявный вызов без проверки Control Flow Guard. Нужно лишь разобраться с двумя вопросами: как добиться нужной последовательности байтов и как записать в регистр необходимый адрес.

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

public static function useless_func():uint
{
    return 0xD5EC;
}

Результат:

Совсем не то, что мы ожидали. Опытным путем можно прийти, например, к такому варианту кода:

public static function useless_func():void
{
    useless_func2(0x11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26);
}

public static function useless_func2(arg1:uint, arg2:uint, arg3:uint, a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u, v, w, x, y, z):void
{
}

Тело первой функции будет содержать следующие инструкции:

Интересующие нас байты FF 11 являются инструкцией call [ecx]:

Неявный вызов получили, теперь нужно занести в регистр ecx контролируемый адрес. Выясним, что хранится в данном регистре в момент вызова функции useless_func().

В момент вызова функции, в регистре ecx находится объект класса MethodEnv. Первый DWORD данного класса является указателем на виртуальную таблицу функций (ту, которую генерирует компилятор C++). Эта таблица в момент вызова метода useless_func() не используется, поэтому ничего не мешает атакующему непосредственно перед вызовом метода заменить указатель на свой.
Реализация данного алгоритма будет следующей:

var class_addr:uint = read_addr(UselessClass);
var vtable:uint = read_dword(class_addr + 8);
var methodenv:uint = read_dword(vtable + 0x54); // $+54 = useless_func
var func_ptr:uint = read_dword(methodenv + 4);

write_dword(methodenv + 4, func_ptr + offset_to_call_ecx);
write_dword(methodenv, rop_gadget); // ecx <- pointer to rop gadgets

UselessClass.useless_func(); // call [ecx]

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

Этот метод обхода CFG был исправлен в версии 18.0.0.194 (KB3074219, Июнь 2015). Исправление заключается в использовании нового флага
PAGE_TARGETS_INVALID/PAGE_TARGETS_NO_UPDATE (0x40000000) для функций VirtualAlloc и VirtualProtect в связке с новой функцией WinAPI — SetProcessValidCallTargets.
Флаг PAGE_TARGETS_INVALID при выделении исполняемой памяти выставляет нулевой бит для всего участка памяти, а флаг PAGE_TARGETS_NO_UPDATE при изменении типа памяти на исполняемую предотвращает изменение битовой карты для целевого участка памяти.
Данное исправление можно наблюдать в функции AVMPI_makeCodeMemoryExecutable в исходном коде ядра AVM (AVMPI/MMgcPortWin.cpp):

Вызов функции SetProcessValidCallTargets реализован в AVMPI_makeTargetValid (AVMPI/MMgcPortWin.cpp):

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

  • VirtualAlloc(PAGE_READWRITE)
  • Запись кода в выделенный участок
  • VirtualProtect(PAGE_EXECUTE_READ | PAGE_TARGETS_NO_UPDATE)
  • SetProcessValidCallTargets()

И, конечно же, не стоит забывать про неявные вызовы внутри динамического кода.

Обход при помощи функций WinAPI

Проверка Control Flow Guard заключается в валидации вызываемого адреса, но валидными адресами являются не только начала пользовательских функций. Все функции WinAPI, как и любые другие функции из таблицы импорта, являются валидными адресатами для неявного вызова. Атакующему ничего не мешает перевести поток исполнения напрямую в библиотечную функцию, минуя тем самым выполнение шеллкода (shellcode) или ROP-гаджетов. Хорошим кандидатом для такой цели является WinAPI функция kernel32!WinExec.

Данная идея впервые была озвучена исследователем Yuki Chen из Qihoo 360 Vulcan Team на конференции SyScan (Сингапур, 2015) в презентации, посвященной эксплуатации уязвимости в Internet Explorer 11 с обходом новых механизмов защиты. Также на конференции BlackHat (США, 2015) исследователь Francisco Falcón описал реализацию данного метода применительно к Adobe Flash Player.
В своей реализации Francisco Falcón оперировал методом toString() объекта класса Vector, но мы попробуем реализовать данный метод, пользуясь наработками из предыдущего.
Основная сложность данного метода заключается в том, чтобы передать параметры WinExec через стек. Данная функция, согласно справке, принимает 2 параметра: LPCSTR lpCmdLine и UINT uCmdShow.

  • lpCmdLine — указатель на строку, которую нужно выполнить (должна заканчиваться нулевым байтом).
  • uCmdShow — режим отображения запускаемого приложения.

Обратимся к скриншоту из предыдущего метода:

В момент вызова нашей функции на стеке оказывается 3 параметра. Третий параметр нас не интересует. Со вторым все отлично, поскольку 0 = SW_HIDE (приложение запустится скрыто). Первым параметром является указатель на объект MethodEnv.

Как мы уже выяснили ранее, первые 4 байта данного объекта являются указателем на виртуальную таблицу функций, и в момент вызова ActionScript-метода она никак не задействуется. Следующие 4 байта указывают на тело функции, и именно их нужно изменить на указатель функции WinExec.
Поскольку порча указателя на тело функции не приведет ни к чему хорошему, в нашем распоряжении имеется лишь первые 4 байта. В данный размер можно, например, уместить строку cmd (командная строка Windows). Данной командой, конечно, не добиться полной компрометации системы, но для демонстрации подойдет.

Модифицируем алгоритм из предыдущего метода и получим следующий код:

var class_addr:uint = read_addr(UselessClass);
var vtable:uint = read_dword(class_addr + 8);
var methodenv:uint = read_dword(vtable + 0x50); // $+50 = useless_func

var winexec:uint = get_proc_addr("kernel32.dll", "WinExec");

write_dword(methodenv + 4, winexec); // useless_func() --> WinExec()
write_dword(methodenv, 0x00646d63); // '', 'd', 'm', 'c'

UselessClass.useless_func();

Поиск WinAPI функции в условиях современных Flash-эксплоитов является тривиальной задачей. Данную реализацию мы опустим, но с ней можно всегда ознакомиться, изучив пакет Flash Exploiter из фреймворка Metasploit.
Выполнив приведенный выше алгоритм при эксплуатации уязвимости, можно убедиться в работоспособности данного метода:

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

Образец для подражания

Все современные Flash-эксплоиты так или иначе используют метод запуска полезной нагрузки (payload) из утекших исходников эксплоитов компании HackingTeam. Автором данного метода является Виталий Торопов. Его метод основан на вызове WinAPI функции kernel32!VirtualProtect, благодаря чему достигается обход всех механизмов защиты и, в том числе, Control Flow Guard.
Целью данного метода является метод apply() класса Function (core/FunctionClass.cpp)

В исходном коде данного метода происходит нативный вызов core->exec->apply(get_callEnv(), thisArg, (ArrayObject*)AvmCore::atomToScriptObject(argArray));, который можно перехватить, оперируя объектами ActionScript.

Подробное описание данного метода требует отдельной статьи, но с реализацией можно ознакомиться на GitHub. Также есть хороший материал с разбором данного метода в условиях 64-битного Flash в блоге Metasploit.

Другие работы по обходу Control Flow Guard

В данной статье были рассмотрены методы обхода CFG при эксплуатации уязвимостей Adobe Flash Player. Но мир не крутится вокруг Flash, поэтому рекомендуем ознакомиться со следующими исследованиями, в которых затрагивается вопрос обхода Control Flow Guard в Internet Explorer 11.

  • Zhang Yunhai @ Black Hat 2015
    Перезапись read-only указателя ___guard_check_icall_fptr используя CustomHeap::Heap библиотеки Jscript9.
  • Yuki Chen @ SyScan 2015
    Вызов WinAPI функции kernel32!LoadLibraryA
  • Rafal Wojtczuk & Jared DeMott @ DerbyCon 2015 (video), заметка в блоге Bromium Labs
    Интересное исследование, в котором представлена новая техника — «десинхронизация стека» (stack desync). Данная техника основана на том, что Control Flow Guard не способен контролировать валидность адреса возврата функции. Модификация адреса возврата достигается за счет вызова функции с несоответствующим соглашением о вызове (calling convention).

Заключение

Несмотря на свои недостатки, Control Flow Guard при должном внимании со стороны разработчиков является хорошим дополнением в арсенале борцов с эксплоитами в среде ОС Windows. Компании Microsoft удалось, пусть и не полностью, реализовать концепцию Control Flow Integrity, минимально повлияв на производительность приложений, и сохранив обратную совместимость. Данный механизм еще не достиг предела своих возможностей, и разработчики из Microsoft наверняка в ближайшем будущем смогут усилить защиту приложений.
Хочется надеяться, что все разработчики приложений задумаются над современной защитой от эксплуатации уязвимостей и добавят в свои продукты поддержку CFG.

Подобные механизмы защиты появляются и на уровне железа. Компания Intel, например, выпустила спецификацию их новой технологии, нацеленную на противодействие ROP-атакам — CET (Control-flow Enforcement Technology) (статья на хабре). В добавок к лучшей производительности, CET избавлен от многих недостатков Control Flow Guard.

Источники

Jack Tang, Trend Micro Threat Solution Team. Exploring Control Flow Guard in Windows 10.
mj0011, Qihoo 360 Vulcan Team. Windows 10 Control Flow Guard Internals.
Source code for the Actionscript virtual machine, GitHub.
Francisco Falcon, Core Security. Exploiting Adobe Flash Player in the era of Control Flow Guard.

Microsoft добавила во все компьютеры на базе Windows 10 новую разработку
под названием Control Flow Guard. Это своего рода специальная защита,
направленная на борьбу с уязвимостями, связанными с повреждениями
памяти. Защита защитой, но она в несколько раз снижает скорость работы
всей операционной системы.

Для отключения необходимо запустить «Защитник Windows», а затем перейти в
раздел «Управление приложениями и браузеров». Потребуется открыть
подраздел «Параметры защиты от эксплойтов», после чего отключить защиту
CFG (Control Flow Guard). Чтобы все начало работать потребуется
перезагрузить компьютер.

После выполнения этих действий и перезагрузки компьютера, он начнет
работать в разы быстрее. Зачем Microsoft принудительно включала
эту настройку для всех — неизвестно, однако на форумах компании уже
имеются десятки тысяч отзывов от пользователей, которые жалуются на
медленную работу операционной системы Windows 10 из-за такого
нововведения.

ПыСы: Данный финт не сильно помог, но теперь хотя бы программы запускаются быстро. Во время работы в Проводнике всё еще проскакивают фризы. Также при закрытии программ наблюдается тупняк.

Понравилась статья? Поделить с друзьями:
  • Как отключить action center windows 10
  • Как отключить ceip в windows 10
  • Как отключить acpi в windows 10
  • Как отключить cd rom windows 10
  • Как отключить 445 порт в windows 10