Различия

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

Ссылка на это сравнение

articles:exploit-review-0x19 [2017/09/05 02:55] (текущий)
Строка 1: Строка 1:
 +====== exploit-review-0x19 ======
 +<​sub>​{{exploit-review-0x19.odt|Original file}}</​sub>​
 +
 +====== exploits review\\ 19h выпуск ======
 +
 +крис касперски ака мыщъх, a.k.a. nezumi, a.k.a elraton, a.k.a. souriz, no-email
 +
 +**этот обзор еще более необычен,​ чем предыдущий и посвящен он… ошибкам процессоров,​ обнаруженных за последнюю пару месяцев и существенно облегчающих нашу хакерскую жизнь — даже если операционная система не содержит дыр (например,​ ****OpenBSD)****,​ удаленная атака все равно остается возможной благодаря дефектом проектирования процессора!**
 +
 +===== Intel Pentium – зависон на не выровненных циклах =====
 +
 +**brief**:​в июне 2008 года сотрудники тестовой лаборатории корпорации Intel обнаружили ошибку в процессоре **Core 2 Extreme Processor QX9775**, связанную с некорректной обработкой не выровненных условных переходов пересекающих 16-байтовые границы,​ и высаживающие ЦП на измену результаты которой варьируются от генерации исключения "​machine check exception"​ до полного зависания системы. Баг возникает только на определенных временных диаграммах,​ а потому чаще всего он проявляется именно в компактных вложенных циклах (short nested loops), для выполнения которых достаточно… запустить на машине жертвы специальный JavaScipt и тогда (при активном Java-компиляторе,​ компилирующем код в память),​ мы получим тотальный отказ в обслуживании,​ т. е.DoS. Назвать эту ошибку новой нельзя,​ т. к. впервые она была обнаружена еще в феврале этого же года в процессоре **Core 2 Extreme Processor QX9000**, а спустя неделю — еще в куче других и пока Intel рассылала разработчикам BIOS'​ов рекомендации по устранению обозначенного дефекта,​ в руки тестеров попал новый (едва ли не новейший,​ а потому жутко дорогой) Core 2 Extreme Processor QX9775, содержащий туже самую ошибку,​ полученную по "​наследству"​.
 +
 +**target**:​данный дефект выявлен в следующих процессорах:​ Dual-Core Xeon E3110, Quad-Core Xeon 3300, Dual-Core Xeon 5200, Quad-Core Xeon 5400, Core Extreme QX9775, Core 2 Extreme Quad-Core QX6000, Core 2 Quad Q6000, Core 2 Extreme QX9000, Core 2 Quad Q9000, однако,​ ошибка может присутствовать и в более младших процессорах,​ уже снятых с производства,​ а потому и не тестируемых,​ но все еще широко используемых на рабочих станциях и серверах.
 +
 +**exploit**:​исходный текст exploit'​а,​ написанный мыщъхем на ассемблерных вставках на MS Visual, C++ приведен ниже. При выполнении на указанных процессорах с дряхлой версией BIOS'​а наступает крах (зависон). Для переноса exploit'​а на Java/​JavaScript необходимо знать особенности Java-транслятора конкретного браузера,​ а потому готовые решения здесь не приводится.
 +
 +int bar;
 +
 +__declspec(naked) foo()
 +
 +{
 +
 +__asm{
 +
 +MOV EDI, EDI
 +
 +MOV bar, ESP
 +
 +MOV ESP, offset bar+666h
 +
 +POPAD
 +
 +MOV ESP, bar
 +
 +
 +
 +LX:
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +inc eax
 +
 +jz LX
 +
 +
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +NOP
 +
 +inc ebx
 +
 +jz LX
 +
 +
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +NOP
 +
 +inc ecx
 +
 +jz LX
 +
 +
 +
 +mov esi, eax
 +
 +mov edi, ebx
 +
 +mov ebp, ecx
 +
 +
 +
 +L1:
 +
 +NOP
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +dec esi
 +
 +jnz L1
 +
 +
 +
 +L2:
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +NOP
 +
 +dec edi
 +
 +jnz L2
 +
 +
 +
 +L3:
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +NOP
 +
 +dec ebp
 +
 +jnz L3
 +
 +
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +MOV EDI, EDI
 +
 +NOP
 +
 +dec edx
 +
 +jnz LX
 +
 +retn
 +
 +}
 +
 +}
 +
 +Листинг 1 исходный ассемблерный код exploit'​а,​ завешивающего многие процессоры
 +
 +**solution**:​обновить прошивку BIOS, если производитель материнской платы исправил этот дефект процессора (что вовсе не факт!).
 +
 +{{exploit-review-0x19_Image_0.png?​553}}
 +
 +Рисунок 1 в мыщъхином exploit'​е условные переходы вложенных циклов нарочно выровнены так, чтобы они преднамеренно рассекали 16-байтовые границы
 +
 +===== Intel Pentium – убийство виртуальных машин =====
 +
 +**brief**:​в июне 2008 года в процессорах **Core 2 Extreme Quad-Core QX6000** и **Core 2 Quad ****Q6000**была обнаружена ошибка в менеджере виртуальных машин (Virtual Machine Manager или, сокращенно,​ VMM), позволяющая зловредному коду, исполняющемся на нулевом кольце,​ "​убивать"​ текущую виртуальную машину. Линейку NT-подобных систем этим не удивишь,​ т. к. с нулевого кольца легко устроить BSOD даже безо всяких ошибок в ЦП, но вот Linux/BSD некорректным модулем ядра завалить труднее,​ к тому же, если виртуальная машина предусматривает автоматический рестарт гостевой оси при возникновении каких-то "​терок"​ (что часто встречается на виртуальных серверах,​ работающих на "​автопилоте"​),​ то убийство виртуальной машины превращается в реальную угрозу. Как его реализовать?​ Оказывается,​ достаточно задействовать опцию **IA32_DEBUGCTL.FREEZE_WHILE_SMM_EN**,​ которую можно активировать посредством записи установки бита FREEZE_WHILE_SMM_EN в MSR-регистре IA32_DEBUGCTL. И все! Виртуальная гостевая машина аварийно завершится к кодом 80000021h. Хана короче! Подробнее об этой хане можно прочитать в разделе "​**VM-Entry Failures During or After Loading Guest State**"​руководства "​**Intel 64 and IA-32 Architectures Software Developer'​s Manual Volume 3B: System Programming Guide, Part 2**";
 +
 +**target**:​в настоящее время дефект обнаружен и подтвержден в кристаллах Core 2 Extreme Quad-Core QX6000 и Core 2 Quad Q6000, за остальные процессоры пока ничего не известно,​ но вполне возможно,​ что они так же содержат эту ошибку;​
 +
 +**exploit**:​исходный текст exploit'​а,​ написанный мыщъхем на ассемблере,​ приведен ниже (чтобы его использовать необходимо подставить фактический номер MSR регистра в его имя, воспользовавшись соответственным заголовочным файлом от Intel или сделать это своими руками — номера MSR и всех их атрибутов содержатся в документации);​
 +
 +MOV ECX, IA32_DEBUGCTL
 +
 +RDMSR; читаем содержимое IA32_DEBUGCTL в EDX:EAX
 +
 +OR EAX, 4000h; взводим бит FREEZE_WHILE_SMM_EN
 +
 +WRMSR; обновляем MSR-регистр
 +
 +Листинг 2 убийство гостевой виртуальной машины четырьмя ассемблерными командами
 +
 +**solution**:​Intel предает как решение на уровне BIOS'​а,​ так и программные "​костыли",​ требующие модификации кода существующих виртуальной машины. Однако,​ ни разработчики виртуальных машин, ни Microsoft (со своим Server'​ом 2008 в состав которого входит виртуализатор) никак не отреагировали на ситуацию. Самое смешное,​ что даже сама Intel, выпустившая виртуализатор VirtualBox (бесплатный,​ кстати) не стала править код. Так что… защита нам только сниться ;) а истина,​ как водится,​ в траве.
 +
 +{{exploit-review-0x19_Image_1.jpg?​533}}
 +
 +Рисунок 2 зеленый цвет процессоров семейства Intel Core (мобильная версия) наводит на мысли о траве
 +
 +===== Intel Pentium – крах основной машины =====
 +
 +brief:в конце марта 2008 года в процессоре **Dual-Core Xeon ****7000**был обнаружен мелкий,​ но весьма противный дефект варварского типа, "​поджидающий"​ кристалл в узких переходах между 64-битным режимом основной (host) операционной системы и 32-битным режимом гостевой виртуальной машины. При задействованном режиме Hyper-Threading,​ процессор (при стечении определенных обстоятельств) с некоторой (впрочем,​ довольно незначительной) вероятностью либо выбрасывает IERR#, либо уходит в глухой зависон,​ отправляя в небытие не только виртуальные машины,​ но и основную операционную систему. А вот это уже нехорошо! Подробности этого увлекательного круиза смерти можно найти в официальном обновлении спецификаций "​**Specification Update**"​ http://​download.intel.com/​design/​xeon/​specupdt/​309627.pdf (//​**внимание!**////​Intel ////​любит менять номера ////​pdf-////​файлов,​ поэтому,​ данная ссылка через некоторое время может перестать действовать,​ тогда — заходим на сайт ////​Intel////,​ и находим нужный нам документ по имени процессора//​);​
 +
 +**target**:​в настоящее время данная ошибка обнаружена и подтверждена для **Dual-Core Xeon ****7000****,​ **но, вполне возможно,​ что она имеется и в других процессорах данного семейства;​
 +
 +**exploit**:​руками не трогать! оно и само упадет ;-) со временем… а чтобы помочь ему упасть,​ достаточно выполнять побольше переходов между 32-разрядной виртуальной гостевой машиной и 64-битной операционной системой. А как их выполнять?​ Да очень просто — достаточно,​ например,​ создать шторм TCP/IP пакетов,​ на физическом уровне обрабатываемый сетевой картой основной операционной системы,​ а, значит,​ переключающий контекст выполнения на ее драйвер для обработки очередного прерывания. Пройдет совсем немного времени как случиться глобальный завис!
 +
 +solution:​по утверждению Intel проблему можно решить на уровне BIOS'​а и фирма уже разослала ведущим производителям BIOS'​ов и материнских плат рекомендации по обходу бага, однако,​ что-то производители не спешат реагировать… и обновленные прошивки BIOS'​а к этому дефекту процессора совершенно перпендикулярны,​ ну а отдуваются как всегда конечные пользователи…
 +
 +{{exploit-review-0x19_Image_2.png?​552}}
 +
 +Рисунок 3 процессор Dual-Core Xeon 7000 на сайте Intel вместе со всей документацией и обновлениями спецификаций с перечнем обнаруженных дыр
 +
 +===== full disclose:\\ ошибка #IRET на службе руткитов =====
 +
 +**brief**:​поздравляем! Intel веников не вяжет! 14 мая 2008 года в новейшем кристалле **Core 2 Extreme ****QX9000**,​ обнаружен древний баг, известный еще с декабря 2005! Очень красивый,​ элегантный и чертовски полезный баг, затрагивающий множество процессоров,​ выпущенных корпорацией Intel за последние несколько лет, что позволяет использовать его для защиты программного кода от всяких там дизассемблеров,​ эмулирующих отладчиков и реверсеров,​ отлаживающих малварь на живых, но слегка устаревших машинах,​ в то время как легион геймеров всегда в авангарде,​ то есть с новым железом! Но все по порядку! Баг связан с инструкцией IRET, традиционно использующейся в обработчиках аппаратных прерываний. Однако,​ эта команда может использоваться и на прикладном уровне для передачи управления на кольцо с идентичным уровнем привилегий. При этом IRET последовательно выталкивает из стека регистр EIP, селектор CS и содержимое флагов,​ то есть, если предварительно сохранить в стеке флаги, текущий CS и указатель на метку label, то мы получим завуалированный аналог jmp label, но только если jmp label распознает любой дизассемблер,​ то IRET – обламывает ИДУ и по самые помидоры и создавать перекрестные ссылки приходится вручную. Но это — мелочи. Все интересное сидит внутри IRET. Это только с виду она кажется простой командой,​ но даже в x86-процессорах псевдокод,​ поясняющий действие IRET (приводимый в мануалах от Intel) занимал несколько страниц (а реальный микрокод и того больше). Поддержка 64-битного режима усложнила IRET в несколько раз. Во-первых,​ 64-битный режим требует обязательного выравнивания там, где в x86-процессорах оно было опционально,​ управляясь битом AM регистра CR0 (недоступного с прикладного режима) и битом AC регистра флагов EFLAGS (прекрасно доступным с прикладного режима). А теперь вопрос на засыпку:​ как должен вести себя процессор,​ если на момент начала выполнения IRET флаг AC сброшен (контроль выравнивания отключен),​ стек не выровнен,​ а в сохраненном значении регистра флагов (который будет извлечен после завершения инструкции IRET) флаг AC взведен?​ x86-процессоры (и некоторые x86-64) на это реагируют вполне адекватно,​ то есть врубают контроль выравнивания _после_ того, как IRET закончит свою работу,​ что вполне логично,​ поскольку с точки зрения программиста все инструкции атомарны,​ т. е. неделимы и выполняются за одну абстрактную итерацию. Однако,​ поскольку,​ в действительности мы имеем дело не со сферическими конями в вакууме,​ а с RISC-ядром,​ выполняющим микрокод,​ то из-за ошибок в этом самом микрокоде,​ контроль выравнивания включается _во_ _время_ выполнения инструкции IRET, что приводит к генерации прерывания Alignment Check Exception (#AC). Причем,​ ошибке подвержена только та часть микрокода IRET, которая отвечает за передачу управления с кольца 3 на кольцо 3. Межкольцевой вызов реализован в обозначенной ситуации исключения не вызывает.
 +
 +{{exploit-review-0x19_Image_3.jpg?​399}}
 +
 +Рисунок 4 Core 2 Duo – один из многих процессоров с дырой, официально именуемой "IRET under Certain Conditions May Cause an Unexpected Alignment Check Exception"​
 +
 +**target**:​дефект обнаружен и подтвержден в следующих процессорах (пристегните ремни безопасности,​ прежде чем читать):​ Dual-Core Xeon E3110, Dual-Core Xeon 3000, Quad-Core Xeon 3200, 64-bit Intel Xeon, Quad-Core Xeon 3300, Dual-Core Xeon 5000, Dual-Core Xeon 5100, Quad-Core Xeon 5300, 64-bit Xeon MP, Dual-Core Xeon 7000, Dual-Core Xeon 7100, Dual-Core Xeon 7200, Quad-Core Xeon 7300, Core2 Extreme QX9775, Core2 Extreme Quad-Core QX6000, Core2 Quad Q6000, Core2 Extreme QX9000, Core2 Quad Q9000, а так же, возможно,​ некоторых других.
 +
 +**exploit**:​как эту дыру можно использовать для атаки? а никак! если программное обеспечения,​ используемое жертвой,​ использует IRET для передачи управления с кольца 3 на кольцо 3 (а зачем ему это делать?​!) да еще работает с не выровненным стеком,​ да еще выталкивает в регистр флагов установленный бит AC – так оно само упадет. Intel даже наблюдала такое поведение на некоторых программах,​ правда,​ не сказала каких. Но падает только "​неправильное"​ приложение,​ а не вся система целиком и чтобы выполнить IRET на атакуемой машине,​ хакеру нужно иметь хотя бы минимальные правда для выполнения своего кода (исполняемого файла или shell-кода),​ но в таком случае уронить приложение можно и без всякого IRET'​а. Смысл?​! А смысл в том, что при данных обстоятельствах на багистном процессоре IRET передаст управление вовсе не туда, куда ожидалось! То есть, мы можем написать очень хитрый код, который в дизассемблере (или под эмулирующим отладчиком) выполняет невинные действия,​ а вот на живой машине (с багистным процессором) не только передает управления на основное тело, но так же использует код исключения для его расшифровки. Если исследователь малвари не в курсе этого бага, ему придется изрядно попыхтеть,​ не говоря уже за эвристический анализ,​ который отпадает сразу. Исходный код ассемблерного кода, демонстрирующего эту уязвимость,​ приведен ниже:
 +
 +DECESP; делаем стек не выровненным
 +
 +PUSHFD; сохраняем флаги в стеке
 +
 +POPEAX; выталкиваем в EAX
 +
 +OREAX, 40000h; взводим AC бит
 +
 +PUSHEAX; сохраняем EAX в стеке
 +
 +PUSHCS; сохраняем селектор кода
 +
 +PUSHoffset my_next; сохраняем адрес перехода
 +
 +IRET
 +
 +my_next:; сюда предполагается передать управление
 +
 +INCESP; возвращаем стек на место
 +
 +Листинг 3 ассемблерный текст exploit'​а,​ генерирующего #AC исключение на багистных процессорах и не генерирующего его на правильных ЦП
 +
 +**solution**:​а что тут можно сделать?​! нет, ну правда. конечным пользователям — просто расслабиться. реверсерам малвари — учитывать эту фичу при анализе кода.
 +
 +{{exploit-review-0x19_Image_4.jpg?​399}}
 +
 +Рисунок 5 дырявый Core 2 Extreme Dual -Core от Intel (стоимость дыр заложена в себестоимость изделия)
 +
 +**full disclose:**
 +
 +**под капотом ****Windows**
 +
 +Попытка практической реализации proof-of-concept exploit'​а по началу не предвещала никаких неожиданностей. Горизонт был чист, сияло солнце. А между тем, гроза уже висела над мыщъхиной норой, а за ней и градовая туча подоспела. #​AC-исключение не генерировалось! Ну хоть убей. Чего только мыщъх не делал… Курил, точил, долбил,​ перечитывал errata от Intel столько раз, что выучил наизусть. По конец даже засомневался в здравости рассудка (своего или инженеров из Intel), но, как всегда,​ виноватой оказалась Microsoft.
 +
 +{{exploit-review-0x19_Image_5.png?​553}}
 +
 +Рисунок 6 вот тут чел из MS открыто признает,​ что ядро "​зажимает"​ #​AC-исключение на x86-системах
 +
 +Анализ обработчика исключений,​ сосредоточенного в ядре, показал,​ что система самым наглым образом ныкает #​AC-исключение,​ не передавая его на прикладной уровень и потому до SEH/VEH обработчиков оно просто не доходит. "До Штирлица перестали доходить письма из Родины…"​. Мыщъхиные раскопки ядра подтвердились несколькими независимыми источниками. Так, например,​ Program Manager (Manager — не в смысле программы,​ это человек такойпо имени Kang Su Gatlin) из группы Microsoft Visual C++, без ложной скромности писал: "//On the x86 architecture,​ the operating system does not make the alignment fault visible to the application//"​ (http://​msdn.microsoft.com/​en-us/​library/​aa290049(VS.71).aspx),​ что испытал на своей шкуре хакер Zahical, цитируя мистера Kang Su Gatlin на форуме,​ где туссуются сишные программисты,​ причем довольно хорошо и плотно так тусуются:​ http://​www.tech-archive.net/​Archive/​VC/​microsoft.public.vc.language/​2004-12/​0199.html
 +
 +Уточним — это x86-ядро "​зажимает"​ #​AC-исключение,​ а вот что касается x86-64 – все зависит от того был ли запущен процесс с флагом SEM_NOALIGNMENTFAULTEXCEPT,​ переданным API-функции SetErrorMode() и если да, то исключение будет вновь "​зажиматься"​. К счастью,​ по умолчанию,​ процесс стартует без этого флага и приведенный выше исходный код exploit'​а будет работать как часы.
 +
 +{{exploit-review-0x19_Image_6.png?​553}}
 +
 +Рисунок 7 бедный старый MSDN, идущий на диске с MS Visual Studio 6.0 – он по своей наивности считал,​ что флаг SEM_NOALIGNMENTFAULTEXCEPT применим только к рискам! и не знал, что через несколько лет та же самая фигня будет и на x86-64
 +
 +Ладно, оставим x86-64 системы. С ними все слишком просто,​ да и не очень-то они широко распространены. Вернемся назад к x86 и посмотрим,​ что тут можно сделать. Итак, ядро зажевало исключение и нам его никак не получить,​ разве что спуститься на ядерный уровень… Стоп!!! А ведь это шикарный способ передачи управления ядерному модулю! Допустим,​ у нас есть rootkit, устанавливающий драйвер,​ с которым взаимодействует прикладной код. Стандартный интерфейс DeviceIoControl() слишком известен и слишком заметен. А вот если драйвер перехватывает вектор #​AC-исключения (что на ядерном уровне реализуется без проблем,​ например,​ путем прямого хука таблицы дескрипторов прерываний — она же IDT), то IRET с не выровненным стеком заставит процессор сгенерировать исключение,​ подхватываемое нашим драйвером. Можно до упаду анализировать малварь,​ но в упор не видеть,​ что IRET передает управление не с ring-3 на ring-3 (согласно документации),​ а на… ring-0. И уже нашему драйверу решать,​ что делать дальше. Можно передать управление обратно на ring-3 по адресу,​ занесенному в стек, но ведь можно же и не передавать! Или передавать,​ но не туда. Или (как уже говорилось выше), использовать вектор исключения для расшифровки остального тела rootkita. Конечно,​ ключ получается какой-то беспонтовый и не слишком криптостойкий,​ точнее совсем не криптостойкий,​ но здесь главное — скрыть сам _факт_ расшифровки. И благодаря ошибке в ЦП он очень даже хорошо скрывается. Конечно,​ данный код будет работать не на любом ЦП (хотя и на многих),​ но малварь (в отличии от коммерческих программ) это обстоятельство как ни будь переживет. Ну не один компьютер будет заражен,​ так другой…
 +
 +Хорошо,​ а как быть, если у нас драйвера нет, а писать его в лом. Можно ли обнаружить,​ что исключение имело место быть?! Конечно! Обработка исключений — далеко не самая дешевая операция (в плане процессорных тактов) и замеряя время выполнения IRET, мы легко установим истинное положение дел. "​Правильная"​ IRET занимает не больше нескольких сотен "​тиков",​ легко измеряемых инструкцией RDTSC, а вот скрытая обработка исключения ядром уже тянет на десятки тысяч. Если операция измерения времени выполнения IRET не сильно бросается в глаза, то хакер легко запутает реверсеров,​ анализирующих малварь. И уж точно обойдет всякие эмулирующие отладчики и многие виртуальные машины.
 +
 +Учитывая,​ что Intel фиксить эту багофичу не собирается,​ стоит взять ее на вооружение,​ смело кинувшись в бой! Тем более, что это не единственная дыра в процессорах. Есть и другие. Да там их сотни!!! Мыщъх как раз сейчас нарабатывает фактический материал и точит доклад,​ который (при благоприятном стечении обстоятельств) будет прочитан на хакерской конференции "​**Hack In The Box Security**",​ проводимой в Малайзии в октябре 2008 года:​ http://​conference.hackinthebox.org/​ (для желающих посетить сие мероприятие напоминаю,​ что Малайзия очень удобна тем, что не требует визы, достаточно одного паспорта).
 +
 +{{exploit-review-0x19_Image_7.png?​553}}
 +
 +Рисунок 8 HITBSecConf2008 – крупнейшая азиатская хакерская конференция,​ проводимая в Малайзии,​ на которой есть на что посмотреть и есть кого послушать,​ намотав кучу полезной инфы себе на хвост
 +
 +