Как при пен­тесте обма­нуть анти­вирус­ную прог­рамму

Как обма­нуть анти­вирус­ную прог­рамму

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

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

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

Во­обще, вопрос обхо­да анти­виру­са вероятен  в 2-ух слу­чаях:

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

В первом случае достаточно применить известный прием — Антивирус . Мы модифицируем код без изменения его функциональности. Хорошая тактика — написать код самостоятельно. Например, используя двадцать строк кода в VBS, вы можете реализовать простую обратную оболочку и успешно обойти любой антивирус. Мы сосредоточимся на втором случае, и это будет предметом данной статьи.

Многие полезные инструменты обхода антивируса можно запустить с одного и того же Meterpreter, но, по крайней мере, вам нужно сначала запустить его. Какой бы метод мы ни рассматривали, наша конечная цель — запуск Meterpreter. Ведь этот инструмент обладает всеми необходимыми функциями и при желании может также использоваться для запуска другого специального программного обеспечения непосредственно в основной памяти. А все, что происходит в оперативной памяти, практически недоступно для средств защиты, поскольку подробный и постоянный анализ памяти влечет за собой колоссальные накладные расходы, которые антивирусы не могут себе позволить.

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

По боль­шому сче­ту мы име­ем дело с дву­мя механиз­мами защиты:

  • сиг­натур­ным;
  • эв­ристи­чес­ким (поведен­ческим).

При сигнатурном рассмотрении антивирус предусматривает большое число условий, в частности компилятор имеет большое влияние на результат. Вот несколько забавных результатов VirusTotal для безобидного приложения helloworld, написанного на C:

  • i686-w64-mingw32-gcc — 11/68 детек­тов;
  • msvc — 2/64 детек­та;
  • win-gcc — 0 детек­тов.

То что имеетт касательство к рассмотрению поведения ПО, здесь нужно понимать, что даже если вам удалось обойти подписи, вы все равно можете сгореть, так как любой перенесенный PID или sekurlsa :: logonPasswords может быть перехвачен за счет использования комбинаций функций WinAPI особенности, что антивирусы внимательно отслеживают.

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

Code caves

Каждый exe-файл (формат PE) содержит код. В то же время весь код представляет собой серию функций. С другой стороны, при компиляции функции размещаются не близко друг к другу, а с определенным выравниванием (16 байт). Еще большие промежутки вызваны выравниванием между секциями (4096 байт). И все эти выравнивания создают множество маленьких пустот в коде, в которые можно вписать код. Все очень сильно зависит от компилятора. Но для большинства PE-файлов, а нас в основном интересует операционная система Windows, изображение может выглядеть примерно так, как на следующем снимке экрана.

Графическое представление расположения функций и пустот между ними Как обма­нуть анти­вирус­ную прог­рамму

Гра­фичес­кое пред­став­ление рас­положе­ния фун­кций и пус­тот меж­ду ними

Что пред­став­ляет собой каж­дая такая «пус­тота»?

Code cave Как обма­нуть анти­вирус­ную прог­рамму

Code cave

Так, если мы более точ­но (сиг­натур­но) опре­делим рас­положе­ние всех пус­тот, то получим при­мер­но сле­дующую кар­тину в исполня­емом фай­ле.

Поиск кодовых пустот в исполняемом файле Как обма­нуть анти­вирус­ную прог­рамму

По­иск кодовых пус­тот в исполня­емом фай­ле

Визуальное расположение пустот по всему файлу Как обма­нуть анти­вирус­ную прог­рамму

Ви­зуаль­ное рас­положе­ние пус­тот по все­му фай­лу

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

Посмотрим, сможем ли мы разложить на эти пустые места небольшой многоступенчатый код оболочки Windows / Meterpreter / reverse_tcp. Пещера кода редко превышает 16 байт, поэтому нам нужно разделить шеллкод больше, чем базовые блоки. Следовательно, вам придется вставить дополнительные инструкции jmp, чтобы объединить их и настроить адреса условных переходов. На самом деле это вполне обычная операция.

Фрагментация и вставка шелл-кода в code caves Как обма­нуть анти­вирус­ную прог­рамму

Фраг­мента­ция и встав­ка шелл‑кода в code caves

Как обма­нуть анти­вирус­ную прог­рамму

В резуль­тате наш шелл‑код раз­мером в 354 бай­та был раз­бит на 62 кусоч­ка и помещен в ран­домные пус­тоты меж­ду фун­кци­ями.

Исходный исполняемый файл — пустота между функциями из-за выравни Как обма­нуть анти­вирус­ную прог­раммувания

Ис­ходный исполня­емый файл — пус­тота меж­ду фун­кци­ями из‑за вырав­нивания

Модифицированный исполняемый файл — зараженная пустота между функциямиКак обма­нуть анти­вирус­ную прог­рамму

Мо­дифи­циро­ван­ный исполня­емый файл — заражен­ная пус­тота меж­ду фун­кци­ями

Теоретически такой подход должен дать нам полиморфизм, поскольку каждый раз шелл-код будет помещаться в случайные пустоты для двух или трех инструкций (это называется модным словом «перестановка»). Даже на уровне трассировки выполнения код будет запутан из-за достаточно большого количества инструкций jmp между фрагментами.

Оригинальная трасса исполнения шелл-кода Как обма­нуть анти­вирус­ную прог­рамму

Ори­гиналь­ная трас­са исполне­ния шелл‑кода

Обфусцированная трасса исполнения шелл-кода Как обма­нуть анти­вирус­ную прог­рамму

Об­фусци­рован­ная трас­са исполне­ния шелл‑кода

C помощью это­го спо­соба мы можем обой­ти таким обра­зом мно­го «прос­тых» анти­виру­сов.

Выполнение вредоносного шелл-кода в обход антивируса Как обма­нуть анти­вирус­ную прог­рамму

Вы­пол­нение вре­донос­ного шелл‑кода в обход анти­виру­са

Как обма­нуть анти­вирус­ную прог­рамму

Од­нако серь­езные анти­вирус­ные про­дук­ты таким трю­ком все же не про­ведешь.

Vuln inject (spawn)

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

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

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

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

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

Мы не будем вдаваться в подробности buffer overflow и цепочек ROP, поскольку это выходит за рамки данной статьи. Вместо этого возьмем готовое решение. Компилируем сервис без поддержки ASLR (а можно и без DEP):

cl.exe /c vuln_rop.c

link.exe /out:vuln_rop.exe vuln_rop.obj /nxcompat:no /fixed

Наша сетевая служба будет работать в режимах listen и reverse connect. И все данные будут передаваться в зашифрованном виде, чтобы не сгореть на анализаторе сигнатур. И это очень важно, поскольку некоторые антивирусы настолько «недолюбливают» Meterpreter, что даже простая отправка его на любой открытый порт спровоцирует неизбежное оповещение и последующий бан на IP-адрес злоумышленника.

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

Запуск сервиса с заложенной нами buffer overflow Как обма­нуть анти­вирус­ную прог­рамму

За­пуск сер­виса с заложен­ной нами buffer overflow

Наша уязвимая служба успешно запустилась и ожидает поступления данных. Мы создаем payload и запускаем c ним эксплойт.

Эксплуатация нашего buffer overflow Как обма­нуть анти­вирус­ную прог­рамму

Экс­плу­ата­ция нашего buffer overflow

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

Переполнение буфера в действии Как обма­нуть анти­вирус­ную прог­рамму

Пе­репол­нение буфера в дей­ствии

Эта полез­ная наг­рузка откры­вает нам сес­сию Meterpreter.

Выполнение вредоносного кода в обход антивируса Как обма­нуть анти­вирус­ную прог­рамму

Вы­пол­нение вре­донос­ного кода в обход анти­виру­са

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

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

Legal

Лучший бой — это тот, которого удалось избежать. Поэтому в борьбе с антивирусным ПО часто используются легальные средства. Да, они не могут предоставить много «продвинутых вещей», но они могут реализовать самый минимум в виде обратной оболочки с постоянством и боковым перемещением, а также встроенным прокси-сервером и гибкой системой перенаправления трафика во время вращение. А это замечательные и всем известные утилиты: nc.exe, ncat.exe, socat.exe, plink.exe. Примеры их использования были описаны в моих предыдущих статьях. Чернокожие иногда используют распространенные облачные инструменты удаленного администрирования, такие как RMS.

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

Crypt

Как ни странно, классический хоr исполняемого файла с динамическим ключом по-прежнему успешно работает даже с самым грозным антивирусом. Например, возьмем очень бледный исполняемый файл и зашифруем все, что можно сделать, с помощью простого xor. Скрипт для секций .text и .data выглядит примерно так.

Xor с ключом 0x77 указанных адресов и размеров Как обма­нуть анти­вирус­ную прог­рамму

Xor с клю­чом 0x77 ука­зан­ных адре­сов и раз­меров

Спря­чем информа­цию о вер­сии.

Шифрование ресурсов исполняемого файла Как обма­нуть анти­вирус­ную прог­рамму

Шиф­рование ресур­сов исполня­емо­го фай­ла

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

Поиск области, содержащей строки, и ее шифрование Как обма­нуть анти­вирус­ную прог­рамму

По­иск области, содер­жащей стро­ки, и ее шиф­рование

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

PE->NT headers->Optional header->DllCharacteristics |=0x40

Те­перь самое вре­мя про­верить, что мы все спря­тали, и наш mimikatz боль­ше не вызыва­ет подоз­рений.

Все вредоносное содержимое успешно скрыто Как обма­нуть анти­вирус­ную прог­рамму

Все вре­донос­ное содер­жимое успешно скры­то

Хорошо. Только наш файл не работает, потому что в нем все зашифровано. Прежде чем мы пойдем дальше, я рекомендую вам попробовать запустить файл в отладчике, чтобы убедиться, что структуры формата PE не повреждены и что файл правильный.

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

Наш xor_stub.asm сохранит исходное состояние и добавит разрешения на запись в зашифрованные разделы.

Изменение permissions зашифрованных секций Как обма­нуть анти­вирус­ную прог­рамму

Из­менение permissions зашиф­рован­ных сек­ций

Здесь и далее не забудь изме­нить адре­са WinAPI-фун­кций на свои зна­чения. Теперь мы скор­ректи­руем точ­ку вхо­да, так как в нее чуть поз­же будет встав­лен jump на дан­ный код.

Восстановление инструкций точки входа Как обма­нуть анти­вирус­ную прог­рамму

Вос­ста­нов­ление инс­трук­ций точ­ки вхо­да

Зап­росим у поль­зовате­ля ключ для рас­шифров­ки и выпол­ним де-xor всех зашиф­рован­ных областей.

Запрос ключа и расшифровка им заксоренных областей Как обма­нуть анти­вирус­ную прог­рамму

Зап­рос клю­ча и рас­шифров­ка им зак­сорен­ных областей

На­конец мы вос­ста­нав­лива­ем началь­ное сос­тояние, кор­ректи­руем стек и переме­щаем­ся в entry point.

Возврат на точку входа Как обма­нуть анти­вирус­ную прог­рамму

Воз­врат на точ­ку вхо­да

Са­мое вре­мя добавить пус­тую сек­цию r-x в mimikatz, куда мы раз­местим наш xor_stub.

Добавление секции, куда будет вставлен код расшифровки

До­бав­ление сек­ции, куда будет встав­лен код рас­шифров­ки

Те­перь ском­пилиру­ем дан­ный ассем­блер­ный код и вста­вим его в толь­ко что соз­данную сек­цию.

Компиляция и вставка кода для расшифровки

Ком­пиляция и встав­ка кода для рас­шифров­ки

В кон­це не забудем из entry point сде­лать jump на наш код.

Передача управления на код расшифровки

Пе­реда­ча управле­ния на код рас­шифров­ки

Запус­каем и вво­дим ключ, которым мы шиф­ровали, — в моем слу­чае это сим­вол w (0x77).

Выполнение вредоносного кода в обход антивируса

Вы­пол­нение вре­донос­ного кода в обход анти­виру­са

Нем­ного авто­мати­зиро­вав дан­ный про­цесс, поп­робу­ем запус­тить Meterpreter.

Автоматическое шифрование описанным способом

Ав­томати­чес­кое шиф­рование опи­сан­ным спо­собом

За­пус­каем и вво­дим ключ w.

Запуск вредоносного кода

За­пуск вре­донос­ного кода

И получа­ем тот же эффект.

Запуск вредоносного кода в обход антивируса

За­пуск вре­донос­ного кода в обход анти­виру­са

Vuln inject (attach)

Самый простой и удобный способ запустить код в чужом адресном пространстве (процессе) — это внедрить его в библиотеку. К счастью, DLL мало чем отличается от EXE, и мы можем перекомпилировать нашу уязвимую службу в форм-фактор библиотеки, просто изменив main() на DllMain():

cl.exe /c vuln_rop.c

link.exe vuln_rop.obj /out:vuln_rop.dll /dll /nxcompat:no /fixed

Я использую 32-битные программы для максимальной переносимости, поэтому нам придется внести уязвимость в 32-битные процессы. Можно взять любой уже запущенный или запустить самостоятельно. В 64-битной Windows мы всегда можем найти 32-битные системные программы в c: \ windows \ syswow64.

Запуск 32-битного процесса

За­пуск 32-бит­ного про­цес­са

Те­перь в тот или иной 32-бит­ный про­цесс мы можем внед­рить уяз­вимость, прос­то заин­жектив туда нашу биб­лиоте­ку.

Инжект библиотеки в только что запущенный 32-битный системный процесс

Ин­жект биб­лиоте­ки в толь­ко что запущен­ный 32-бит­ный сис­темный про­цесс

На­ша DLL без ASLR успешно заг­ружена по стан­дар­тно­му адре­су.

Уязвимая DLL загружена

Уяз­вимая DLL заг­ружена

И теперь целевой про­цесс с занесен­ным buffer overflow готов получать дан­ные по сети.

Уязвимый код начал работать в контексте легитимного процесса

Уяз­вимый код начал работать в кон­тек­сте легитим­ного про­цес­са

Поскольку наш уязвимый модуль был загружен по адре­су 0x10000000 (это адрес по умолчанию для библиотек, не относящихся к ASLR), нам нужно немного изменить код эксплойта.

Небольшая корректировка кода эксплоита

Не­боль­шая кор­ректи­ров­ка кода экс­пло­ита

Вре­мя запус­тить сам экс­пло­ит.

Запуск эксплоита

За­пуск экс­пло­ита

В кон­тек­сте легитим­ного про­цес­са про­исхо­дит overflow.

Запуск сервиса с заложенной нами buffer overflow Как обма­нуть анти­вирус­ную прог­рамму

Пе­репол­нение буфера в легитим­ном про­цес­се в дей­ствии

И мы исполня­ем «вре­донос­ный» код в обход анти­виру­са.

Выполнение вредоносного кода в обход антивируса Как обма­нуть анти­вирус­ную прог­рамму

Вы­пол­нение вре­донос­ного кода в обход анти­виру­са

Shellcode injecting

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

shellcode_inject.exe не содержит угроз

shellcode_inject.exe не содер­жит угроз

В свою очередь, наш шелл-код выглядит еще более безобидным, если мы преобразовываем его в печатные символы.

Cоздание автономного (не staged) шелл-кода. Выглядит безобидно

Cоз­дание авто­ном­ного (не staged) шелл‑кода. Выг­лядит безобид­но

Гля­дя на содер­жимое meter.txt, я бы ско­рее решил, что это стро­ка в Base64, чем шелл‑код.

Обратите внимание, что мы использовали шелл-код meterpreter_reverse_tcp, а не meterpreter / reverse_tcp. Это автономный код, который содержит все функции Meterpreter, он ничего не загружает в сеть, поэтому у нас будет меньше шансов быть обнаруженными. Но связка shellcode_inject.exe и meter.txt уже опасна. Посмотрим, сможет ли антивирус распознать угрозу?

Инжект Meterpreter

Inject meterpreter

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

Выполнение вредоносного кода в обход антивируса

Выполнение вредоносного кода в обход антивируса

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

Запуск вредоносного ПО через Meterpreter в памяти

Запуск вируса через Meterpreter в памяти

Выводы

Мы применили эффект «неожиданного» применения програмного кода в памяти через 0-day-уяз­вимость, антивирус не смог предсказать и заблокировать угрозу. Загрузка DLL в чужой процесс — известный трюк, и мы использовали его просто для удобства: нам почти не приходилось что-либо менять.

Фактически, мы могли бы использовать еще более умный метод: просто подставляя ключевые инструкции в тот или иной момент в памяти процесса, в котором обрабатывается пользовательский ввод, а затем внедряли туда уязвимость (например, создавая антипатч). И, поместив пару полезных устройств ROP в code caves, мы также сделаем его пригодным для использования. Но пока этого даже не требуется.

Методика сок­рытия выпол­нения программного кода посредством buffer overflow никак не свежа, хотя и довольно мало известна. Сдесь был использован простейший пример переполнения буфера в стеке, и он принес нам успех. Но есть гораздо более сложные ошибки памяти, которые приводят к RCE (скрытому выполнению): use after free, double free, overflow in heap, format strings и так далее. далее. Это открывает практически неисчерпаемый потенциал методов обхода антивирусов.

 

 

 

 

 

 

 

 

 

 

 

 

Click to rate this post!
[Total: 0 Average: 0]

Leave a reply:

Your email address will not be published.