Новая техника атак на основе Meltdown. Использование спекулятивных инструкций для детектирования виртуализации

    Атака Meltdown открыла новый класс атак на процессоры, использующий архитектурные состояния для передачи информации. Но спекулятивное исполнение, которое было впервые применено для атаки в Meltdown, позволяет не только выполнить код со снятием ограничений, но и узнать определенные детали работы процессора. Мы нашли новый способ реализации атаки с использованием архитектурных состояний. Он позволяет детектировать виртуализацию, опираясь на то, как процессор выбирает, отправлять инструкции на спекулятивное исполнение или нет. Мы сообщили о данном способе в Intel, и 21 мая 2018 года было выпущено оповещение об уязвимостях «Q2 2018 Speculative Execution Side Channel Update», в котором присутствует наша уязвимость CVE-2018-3640 или Spectre Variant 3a.

    1. Введение


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

    2. Виртуализация


    Технология VT-x в процессорах Intel позволяет гипервизору выбрать, произойдет ли VMEXIT (переключение контекста на гипервизор) при выполнении определенных инструкций, например rdtsc. Большинство сред виртуализации в стандартной конфигурации настраивают перехват rdtsc по умолчанию. Так делают, например Virtualbox, VMware, Hyper-V, Parallels на гипервизоре от Apple и от Parallels. Поскольку VMEXIT фактически означает переключение контекста, то инструкции, которые генерируют VMEXIT, исполняются дольше, чем если бы они исполнялись в невиртуализованной среде.

    3. Атака


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

    _declspec(naked) void herring() {         //Эта функция используется для
     __asm {                                  //срабатывания спекулятивного
             xorps xmm0, xmm0                 //исполнения в функции speculate 
             sqrtpd xmm0, xmm0
             sqrtpd xmm0, xmm0
             sqrtpd xmm0, xmm0
             sqrtpd xmm0, xmm0
             sqrtpd xmm0, xmm0 
             sqrtpd xmm0, xmm0 
             sqrtpd xmm0, xmm0 
             sqrtpd xmm0, xmm0
             movd eax, xmm0
             lea esp, [esp+eax+4]
             ret
        }
    }
    _declspec(naked) void __fastcall speculate(const char* detector) {
          __asm {                   //Эта функция спекулятивно исполняет rdtsc и
               mfence.              //обращается к странице, соответствующей 
               mov esi, ecx.        //возвращенному rdtsc значению                                
               call herring           
               rdtsc.               //Эти инструкции
               and eax, 7.          //исполняются спекулятивно
               or eax, 32.                      //*
               shl eax, 12.                     //*
               movzx eax, byte ptr [esi+eax]    //*
         }
    }

    Для успешной реализации атаки эти действия нужно повторять, чтобы найти распределение кешируемых страниц. Необходимо выполнить столько повторов, сколько требуется, чтобы набрать достаточно статистических данных: во время описываемого теста использовалось 10 000 итераций. Затем рассчитывается количество промахов мимо выбранного региона памяти. В виртуализованных средах, где включен перехват rdtsc, доля таких промахов составляет от 50 до 99 процентов. На невиртуализованных системах она меньше одного процента. Эта информация представлена на рисунке ниже (чем темнее регион памяти, тем больше попаданий в него зафиксировано). При тестировании в качестве невиртуализованных систем использовались macOS, Ubuntu, Debian и Windows, а в качестве гостевых систем — Ubuntu, Debian и Windows.



    Распределение кешированных страниц в различных средах

    4. Описание атаки


    Атака использует спекулятивное исполнение инструкций, чтобы заставить процессор раскрыть информацию об исполнении rdtsc. В невиртуализованной среде rdtsc исполняется на самом процессоре, который просто возвращает счетчик. В виртуализованной среде, где для бита «RDTSC exiting» выставлено значение MSR IA32_VMX_PINBASED_CTLS, исполнение rdtsc по сути является переключением контекста, которое выполняется слишком долго.

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

    5. Выводы и направления будущих исследований


    Описываемая атака использует новую технику кеширования на основе Meltdown для создания побочного канала, которая вместо обращения к привилегированным регионам памяти раскрывает информацию о режиме работы процессора. Все известные методы детектирования виртуализации сильно зависят от использования инструкции rdtsc в качестве таймера, что позволяет «умному» гипервизору обмануть эти методы, подменив возвращаемые значения. Такую атаку также можно ограничить, но если внести небольшие изменения в код, то подмена времени со стороны гипервизора не сможет повлиять на результат. Возможно, мы опубликуем PoC такой версии позже.
    Можно сделать вывод, что в виртуализованных средах с перехватываемым rdtsc вариация описанной атаки позволяет определить наличие виртуализации, а при отсутствии перехвата возможно использование ранее известных методов, например, метода измерения скоростей работы с TLB-кешами.

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

    Код PoC можно найти по ссылке
    BI.ZONE 59,90
    Компания
    Поделиться публикацией
    Похожие публикации
    Комментарии 12
      –1
      Мне кажется, что speculate надо перевести более точно.
      www.multitran.ru/c/m.exe?CL=1&s=speculate&l1=1
        +2
        В каком предложении и что вам кажется более подходящим?
          0
          забавно, что наказав меня минусом, у меня кончилась карма голосовать и я не смог поставить вам плюс :)

            0
            Не я вам минус ставил
        0
        Может, кто-то знает, на что рассчитывают механизмы коррекции rdtsc виртуалок.

        Время ведь на виртуалке выдаётся настоящее (API GetSystemTime, time_t time()). Часы не запаздывают оттого, что время потрачено в VMM.

        То есть, таймер rdtsc корректируется, а обычный time() выдаётся без коррекции (если на виртуалке есть интернет, можно и с NTP-сервера запросить).

        На расхождениях этих таймеров можно детектировать VM, не залезая в такие дебри, как спекулятивное выполнение?
          0
          Есть механизм Blue Chicken. Описан у Рутковской. Если слишком много вызовов rdtsc, то его перестают перехватывать. Как один из вариантов. И циклы на разной аппаратуре занимают разное время. Так что не всё так просто
            0
            Если слишком много вызовов rdtsc, то его перестают перехватывать
            Ну отлично. Вызываем 100500 раз RDTSC, его перестают перехватывать и корректировать, а на 100501-й раз RDTSC меряет что-то полезное, например, время выполнения гарантированно перехватываемой инструкции, типа CPUID.

            И циклы на разной аппаратуре занимают разное время
            Да, но не в тысячи раз разница.
              0
              Ну там и не будет такая большая разница, а после cpuid можно включать. Не очень получается так обнаружить, иначе бы все малварщики его использовали, чтобы уйти от песочниц. Ещё особенность, что из 3 уровня привилегий нельзя точно узнать, какая должна быть разница у rdtsc. Возможно система дает вашему процессу очень мало вычислительной мощности, почти не переключает на него исоплнение. В итоге обнаружение превращается в гонку гипервизора против детектора.
                0
                CPUID тут просто для примера. Можно взять любую другую инструкцию, либо просто доступ к памяти, требующий нетривиальной трансляции, чтобы точно вылететь в гипервизор.

                Если RDTSC включают после CPUID, возвращаемся обратно к вопросу, почему накапливается существенное расхождение часов и RDTSC.

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

                Система без виртуализации переключает процессы по прерываниям таймера. То есть, она не может дать квант времени меньше 20мс (но может давать эти кванты реже). Значит, если выполнить RDTSC+CPUID подряд 10 раз, только один замер может увеличить время из-за переключения контекста.
                обнаружение превращается в гонку гипервизора против детектора
                Да вроде, никто и не скрывает VM? Не знаю, есть ли специализирующиеся на скрытности VMM, но обычные Hyper-V, VMWare палятся на совсем простых вещах, типа наличия в диспетчере устройств «виртуализированных», наличия в Program Files «support drivers», зарардкоженных серийных номерах и моделях HDD, ставят свой копирайты в производителя BIOS и материнсткой платы (доступно через WMI)
                  0
                  Да, стандартные пользовательские гипервизоры себя не скрывают. Но их переделывают специально, чтобы избежать детекта. И в них надо детектировать свойства ОС, оборудования, иногда специальные MSR. А метод в статье почти не привязан к ПО
          0
          Это теперь любой «средненький» вирус сможет детектить песочницу или виртуалку?
            0
            Если не поставлен патч от Intel, то да

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

          Самое читаемое