Антивирус чрезвычайно полезен, но не тогда, когда вам нужно остаться незамеченным в скомпрометированной сети. Сегодня мы поговорим о том, как обмануть антивирус и избежать обнаружения в скомпрометированной системе во время теста на проникновение и все же рассмотрим как обмануть антивирусную программу.
Безусловно вам известно обстоятельство, если осуществляется допуск ко взломанной сети, и для достижения цели остается только лишь единственный ход. Но антивирусная программа не позволяет выполнить запрошенное действие, запустить ту или иную программу. В моей практике были случаи, когда только одна попытка не удалась из-за предупреждения, выданного антивирусом. Иногда антивирусы могут удалять не только исполняемые файлы, но и совершенно безобидные файлы. Поэтому скрыть реальную угрозу — задача крайне сложная.
Вся информация предоставлена исключительно в информационных целях. Ни редакция, ни автор не несут ответственности за возможный ущерб, причиненный использованием информации в этой статье.
Вообще, вопрос обхода антивируса вероятен в 2-ух случаях:
В первом случае достаточно применить известный прием — Антивирус . Мы модифицируем код без изменения его функциональности. Хорошая тактика — написать код самостоятельно. Например, используя двадцать строк кода в VBS, вы можете реализовать простую обратную оболочку и успешно обойти любой антивирус. Мы сосредоточимся на втором случае, и это будет предметом данной статьи.
Многие полезные инструменты обхода антивируса можно запустить с одного и того же Meterpreter, но, по крайней мере, вам нужно сначала запустить его. Какой бы метод мы ни рассматривали, наша конечная цель — запуск Meterpreter. Ведь этот инструмент обладает всеми необходимыми функциями и при желании может также использоваться для запуска другого специального программного обеспечения непосредственно в основной памяти. А все, что происходит в оперативной памяти, практически недоступно для средств защиты, поскольку подробный и постоянный анализ памяти влечет за собой колоссальные накладные расходы, которые антивирусы не могут себе позволить.
В целях того чтобы обойти антивирус, нам нужно будет думать равно как антивирус, пробовать предугадать его логическое мышление. Антивирус обязательно будет для нас загадкой. Мы не знаем подробно, как он работает, но, основываясь на том как он себя ведет в различных ситуациях, мы можем сделать вывод, что он тщательно отслеживает источник загрузки исполняемого файла, а также отслеживает, был ли он выпущен ранее и запускался ли он до этого и сколько раз.
По большому счету мы имеем дело с двумя механизмами защиты:
При сигнатурном рассмотрении антивирус предусматривает большое число условий, в частности компилятор имеет большое влияние на результат. Вот несколько забавных результатов VirusTotal для безобидного приложения helloworld, написанного на C:
То что имеетт касательство к рассмотрению поведения ПО, здесь нужно понимать, что даже если вам удалось обойти подписи, вы все равно можете сгореть, так как любой перенесенный PID или sekurlsa :: logonPasswords
может быть перехвачен за счет использования комбинаций функций WinAPI особенности, что антивирусы внимательно отслеживают.
Я предлагаю сосредоточиться конкретно на движке сигнатур, которого в большинстве случаев бывает достаточно. В статье не будут прямо упоминаться конкретные названия антивирусов, чтобы никому не создавать рекламу или антирекламу. При этом «дорабатывать» под конкретный антивирус мы не будем. Результаты мы будем проверять на работающем антивирусе, стараясь использовать универсальный метод, чтобы каждый раз не находить новые методы обхода. В любом случае цель будет заключаться в том, чтобы внедрить на скомпрометированную машину Meterpreter, который позволит нам выполнить что угодно в памяти, запустить весь имеющийся в нашем распоряжении хакерский арсенал.
Каждый exe-файл (формат PE) содержит код. В то же время весь код представляет собой серию функций. С другой стороны, при компиляции функции размещаются не близко друг к другу, а с определенным выравниванием (16 байт). Еще большие промежутки вызваны выравниванием между секциями (4096 байт). И все эти выравнивания создают множество маленьких пустот в коде, в которые можно вписать код. Все очень сильно зависит от компилятора. Но для большинства PE-файлов, а нас в основном интересует операционная система Windows, изображение может выглядеть примерно так, как на следующем снимке экрана.
Графическое представление расположения функций и пустот между ними
Что представляет собой каждая такая «пустота»?
Code cave
Так, если мы более точно (сигнатурно) определим расположение всех пустот, то получим примерно следующую картину в исполняемом файле.
Поиск кодовых пустот в исполняемом файле
Визуальное расположение пустот по всему файлу
В этом примере мы искали только 12-байтовые пробелы, поэтому фактическое количество будет намного больше. Пробелов хоть и много, но для полноценной программы их явно недостаточно. Поэтому этот метод подходит только для вставки шелл-кодов, размер которых редко превышает 1 КБ.
Посмотрим, сможем ли мы разложить на эти пустые места небольшой многоступенчатый код оболочки Windows / Meterpreter / reverse_tcp
. Пещера кода редко превышает 16 байт, поэтому нам нужно разделить шеллкод больше, чем базовые блоки. Следовательно, вам придется вставить дополнительные инструкции jmp
, чтобы объединить их и настроить адреса условных переходов. На самом деле это вполне обычная операция.
Фрагментация и вставка шелл‑кода в code caves
В результате наш шелл‑код размером в 354 байта был разбит на 62 кусочка и помещен в рандомные пустоты между функциями.
Исходный исполняемый файл — пустота между функциями из‑за выравнивания
Модифицированный исполняемый файл — зараженная пустота между функциями
Теоретически такой подход должен дать нам полиморфизм, поскольку каждый раз шелл-код будет помещаться в случайные пустоты для двух или трех инструкций (это называется модным словом «перестановка»). Даже на уровне трассировки выполнения код будет запутан из-за достаточно большого количества инструкций jmp между фрагментами.
Оригинальная трасса исполнения шелл‑кода
Обфусцированная трасса исполнения шелл‑кода
C помощью этого способа мы можем обойти таким образом много «простых» антивирусов.
Выполнение вредоносного шелл‑кода в обход антивируса
Однако серьезные антивирусные продукты таким трюком все же не проведешь.
Я хорошо помню старый случай. Не было возможности открыть сеанс 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
Наша уязвимая служба успешно запустилась и ожидает поступления данных. Мы создаем payload и запускаем c ним эксплойт.
Эксплуатация нашего buffer overflow
В результате уязвимая служба принимает наши данные и в результате внутренней ошибки при работе с памятью невольно запускает код полезной нагрузки.
Переполнение буфера в действии
Эта полезная нагрузка открывает нам сессию Meterpreter.
Выполнение вредоносного кода в обход антивируса
И весь этот бардак происходит при запущенном антивирусе. Однако было замечено, что при использовании некоторых антивирусов защита срабатывает всегда. Предположим, почему. Кажется, нам удалось внедрить код крайне неожиданным образом — путем переполнения буфера. В то же время мы не передавали код в открытом виде по сети, поэтому механизмы подписи не работали. Но перед прямым выполнением мы получаем в памяти тот же машинный код. И тут, видимо, нас схватывает антивирус, признавая до боли знакомый Meterpreter.
Антивирус не доверяет ни одному exe-файлу, загруженному из неизвестного источника и запущенному впервые. Он эмулирует выполнение кода и достаточно тщательно анализирует его, может быть, даже по каждой инструкции. Это происходит за счет производительности, а антивирус не может сделать это для всех процессов. По этой причине процессы, которые уже проверены при запуске (например, системные компоненты или программы с известными контрольными суммами), менее отслеживаются. В них мы будем вводить нашу уязвимость.
Лучший бой — это тот, которого удалось избежать. Поэтому в борьбе с антивирусным ПО часто используются легальные средства. Да, они не могут предоставить много «продвинутых вещей», но они могут реализовать самый минимум в виде обратной оболочки с постоянством и боковым перемещением, а также встроенным прокси-сервером и гибкой системой перенаправления трафика во время вращение. А это замечательные и всем известные утилиты: nc.exe, ncat.exe, socat.exe, plink.exe. Примеры их использования были описаны в моих предыдущих статьях. Чернокожие иногда используют распространенные облачные инструменты удаленного администрирования, такие как RMS.
Если вам нужно обеспечить в скомпрометированной системе целую «опору» в виде metasploit и подобных хакерских инструментов, то вы можете спрятаться за виртуализацией. Пошаговое руководство описано в этой статье.
Как ни странно, классический хоr исполняемого файла с динамическим ключом по-прежнему успешно работает даже с самым грозным антивирусом. Например, возьмем очень бледный исполняемый файл и зашифруем все, что можно сделать, с помощью простого xor. Скрипт для секций .text
и .data
выглядит примерно так.
Xor с ключом 0x77 указанных адресов и размеров
Спрячем информацию о версии.
Шифрование ресурсов исполняемого файла
Раздел .rdata
содержит почти все палевные строки. Но проблема в том, что на них проецируются каталоги таблиц импорта и отложенного импорта, которые нельзя трогать, иначе файл не запустится. Поэтому в этом разделе мы просто найдем область, в которой в основном содержатся строки, и зашифруем ее.
Поиск области, содержащей строки, и ее шифрование
Поскольку мы зашифровали все в исполняемом файле, на момент запуска его смещения в коде не будут правильно скорректированы в соответствии с адресом расположения. Следовательно, вам все равно придется отключить ASLR:
PE->NT headers->Optional header->DllCharacteristics |=0x40
Теперь самое время проверить, что мы все спрятали, и наш mimikatz больше не вызывает подозрений.
Все вредоносное содержимое успешно скрыто
Хорошо. Только наш файл не работает, потому что в нем все зашифровано. Прежде чем мы пойдем дальше, я рекомендую вам попробовать запустить файл в отладчике, чтобы убедиться, что структуры формата PE не повреждены и что файл правильный.
Теперь потребуется написать небольшой машинный код для расшифровки. И, что немаловажно, ключ будет определен во время выполнения, то есть нигде в коде не сохранится. Поэтому запуск приложения в «песочнице» антивируса не должен выявлять никаких угроз.
Наш xor_stub.asm
сохранит исходное состояние и добавит разрешения на запись в зашифрованные разделы.
Изменение permissions зашифрованных секций
Здесь и далее не забудь изменить адреса WinAPI-функций на свои значения. Теперь мы скорректируем точку входа, так как в нее чуть позже будет вставлен jump
на данный код.
Восстановление инструкций точки входа
Запросим у пользователя ключ для расшифровки и выполним де-xor всех зашифрованных областей.
Запрос ключа и расшифровка им заксоренных областей
Наконец мы восстанавливаем начальное состояние, корректируем стек и перемещаемся в entry point.
Возврат на точку входа
Самое время добавить пустую секцию r-x
в mimikatz, куда мы разместим наш xor_stub.
Добавление секции, куда будет вставлен код расшифровки
Теперь скомпилируем данный ассемблерный код и вставим его в только что созданную секцию.
Компиляция и вставка кода для расшифровки
В конце не забудем из entry point сделать jump
на наш код.
Передача управления на код расшифровки
Запускаем и вводим ключ, которым мы шифровали, — в моем случае это символ w (0x77
).
Выполнение вредоносного кода в обход антивируса
Немного автоматизировав данный процесс, попробуем запустить Meterpreter.
Автоматическое шифрование описанным способом
Запускаем и вводим ключ w.
Запуск вредоносного кода
И получаем тот же эффект.
Запуск вредоносного кода в обход антивируса
Самый простой и удобный способ запустить код в чужом адресном пространстве (процессе) — это внедрить его в библиотеку. К счастью, 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-битный системный процесс
Наша DLL без ASLR успешно загружена по стандартному адресу.
Уязвимая DLL загружена
И теперь целевой процесс с занесенным buffer overflow готов получать данные по сети.
Уязвимый код начал работать в контексте легитимного процесса
Поскольку наш уязвимый модуль был загружен по адресу 0x10000000 (это адрес по умолчанию для библиотек, не относящихся к ASLR), нам нужно немного изменить код эксплойта.
Небольшая корректировка кода эксплоита
Время запустить сам эксплоит.
Запуск эксплоита
В контексте легитимного процесса происходит overflow.
Переполнение буфера в легитимном процессе в действии
И мы исполняем «вредоносный» код в обход антивируса.
Выполнение вредоносного кода в обход антивируса
Широко известна техника встраивания кода в процессы, которые уже запущены, то есть протестированы. По идее, у нас есть отдельная программа shellcode_inject.exe
и сам шеллкод в разных файлах. Антивирусу сложнее распознать угрозу, если она распространяется на несколько файлов, тем более что эти файлы по отдельности не представляют угрозы.
shellcode_inject.exe не содержит угроз
В свою очередь, наш шелл-код выглядит еще более безобидным, если мы преобразовываем его в печатные символы.
Cоздание автономного (не staged) шелл‑кода. Выглядит безобидно
Глядя на содержимое meter.
, я бы скорее решил, что это строка в Base64, чем шелл‑код.
Обратите внимание, что мы использовали шелл-код meterpreter_reverse_tcp
, а не meterpreter / reverse_tcp.
Это автономный код, который содержит все функции Meterpreter, он ничего не загружает в сеть, поэтому у нас будет меньше шансов быть обнаруженными. Но связка shellcode_inject.exe
и meter.txt
уже опасна. Посмотрим, сможет ли антивирус распознать угрозу?
Inject meterpreter
Обратите внимание: мы используем системный процесс для внедрения кода, он работает сразу в контексте System. И похоже, что наш экспериментальный антивирус даже в конце концов проклял shellcode_inject.exe
, но все равно пропустил этот трюк.
Выполнение вредоносного кода в обход антивируса
Запустив что-то вроде Meterpreter, злоумышленник может запустить полезную нагрузку непосредственно в хранилище, минуя жесткий диск.
Запуск вируса через Meterpreter в памяти
Мы применили эффект «неожиданного» применения програмного кода в памяти через 0-day-уязвимость, антивирус не смог предсказать и заблокировать угрозу. Загрузка DLL в чужой процесс — известный трюк, и мы использовали его просто для удобства: нам почти не приходилось что-либо менять.
Фактически, мы могли бы использовать еще более умный метод: просто подставляя ключевые инструкции в тот или иной момент в памяти процесса, в котором обрабатывается пользовательский ввод, а затем внедряли туда уязвимость (например, создавая антипатч). И, поместив пару полезных устройств ROP в code caves, мы также сделаем его пригодным для использования. Но пока этого даже не требуется.
Методика сокрытия выполнения программного кода посредством buffer overflow никак не свежа, хотя и довольно мало известна. Сдесь был использован простейший пример переполнения буфера в стеке, и он принес нам успех. Но есть гораздо более сложные ошибки памяти, которые приводят к RCE (скрытому выполнению): use after free, double free, overflow in heap, format strings и так далее. далее. Это открывает практически неисчерпаемый потенциал методов обхода антивирусов.
Чтобы взломать сеть Wi-Fi с помощью Kali Linux, вам нужна беспроводная карта, поддерживающая режим мониторинга…
Работа с консолью считается более эффективной, чем работа с графическим интерфейсом по нескольким причинам.Во-первых, ввод…
Конечно, вы также можете приобрести подписку на соответствующую услугу, но наличие SSH-доступа к компьютеру с…
С тех пор как ChatGPT вышел на арену, возросла потребность в поддержке чата на базе…
Если вы когда-нибудь окажетесь в ситуации, когда вам нужно взглянуть на спектр беспроводной связи, будь…
Elastic Security стремится превзойти противников в инновациях и обеспечить защиту от новейших технологий злоумышленников. В…