Задача кеша Wininet, что это такое

Обновлено: 03.07.2024

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

Цитирую прямо сообщение FireEye (потому что я ленивый AF):

Временная замена файла и временная модификация задачи

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

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

Вы можете найти исходный код TaskShell (очень неоригинальное название) здесь

Замена файла

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

Например, давайте рассмотрим это запланированное задание, связанное с FireFox:

Было бы довольно просто заменить файл default-browser-agent.exe произвольным исполняемым файлом и снова запустить задачу.

Давайте быстро поэкспериментируем с calc.exe :

Выполним задачу еще раз (флаг -r):


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

Замена задачи

С запланированными задачами связан набор «действий». Мы можем изменить действия, связанные с конкретной задачей, для выполнения произвольного кода (используя EXE или LOLbin).

Аналогичный подход популяризировал Mr-Un1k0d3r со своей оболочкой SCShell. SCShell использовал API-интерфейсы диспетчера управления службами (SCM) для изменения значения binpath данной службы.

На тот случай, если нам нужен причудливый блокнот вместо калькулятора старой школы:


Преимущество этого метода заключается в том, что нам не нужно сбрасывать EXE-файлы на удаленный хост, но мы можем полагаться на другие LOLbin'ы для более скрытного выполнения кода.

Обработчики COM

Запланированные задачи могут делать больше, чем запуск EXE. Например, они могут создавать объекты COM, реализующие интерфейс ITask.

Идея состоит в том, чтобы идентифицировать исполняемый файл, связанный с COM-сервером, который также уязвим для перехвата DLL.

В приведенном здесь примере мы видим класс NGenTaskLauncher, связанный с двоичным файлом ngentask.exe:


Если мы попытаемся создать его с помощью powershell:

С помощью procmon мы получаем следующие отсутствующие библиотеки DLL:


Как видно, bcrypt.dll отсутствует в каталоге приложения.

Теперь мы можем выбрать задачу, которая уже использует обработчик COM, и изменить ее следующим образом:

Если мы поместим вредоносную DLL в соответствующий каталог (отсутствующие DLL могут измениться в зависимости от версии ОС) и экспортируем ожидаемые функции, мы сможем выполнить код!


Следует отметить, что процесс ngentask.exe будет иметь короткую жизнь, и поэтому для получения стабильного канала C2 вам потребуется внедрить свой код в другой процесс.

Кроме того, DLL, которую я выбрал для этого взлома, может работать не на каждой ОС.На самом деле, та же самая атака не сработала в другой системе Windows 10 18363. Чтобы атака сработала в другой системе, я нацелился на mscoree.dll, и это сработало просто отлично.


Обнаружение

Я хотел бы поговорить об аспекте обнаружения, но этот блог освещает эту тему с удивительным уровнем детализации.

Уклонение

С точки зрения уклонения мы хотим максимально слиться с тем, что уже происходит в окружающей среде. Если удаление EXE-файла и изменение задачи неприемлемо для вашего стандарта opsec, вы можете использовать обычные LOLbins, такие как rundll32 и имена DLL, которые не слишком отличаются от того, что уже есть.

Первым шагом всегда является базовый уровень. С помощью программы TaskShell это можно сделать следующим образом:


Как мы видим, у нас есть много возможных кандидатов на роль rundll. Я бы порекомендовал операторам выбрать уже используемую библиотеку DLL и экспортировать ту же функцию, которая вызывается запланированной задачей. Это необязательно, но желательно иметь.

Подход к захвату DLL из обработчика COM более незаметен, но требует немного больше работы, чтобы сделать его стабильным.

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

Поведение кэша во время обработки ответа

  • WinINet кэширует только ответы HTTP и FTP.
  • Только правильные ответы могут быть сохранены в кэше и использованы в ответе на последующий запрос. Ответы с хорошим поведением определяются как ответы, которые возвращаются успешно.
  • По умолчанию WinINet будет кэшировать успешные ответы, если только директива управления кэшем с сервера или определенный приложением флаг не указывают, что ответ не может быть кэширован.
  • Как правило, ответы на команду GET кэшируются, если выполняются перечисленные выше требования. Ответы на команды PUT и POST не кэшируются ни при каких обстоятельствах.
  • Элементы будут кэшироваться, даже если кэш заполнен. Если добавленный элемент приводит к превышению предельного размера кеша, запускается сборщик кеша. По умолчанию не гарантируется, что элементы останутся в кэше более 10 минут. Дополнительную информацию см. в разделе Cache Scavenger ниже.
  • По умолчанию протокол HTTPS кэшируется. Это управляется глобальным параметром, который не может быть переопределен определяемыми приложением директивами кеша. Чтобы переопределить глобальную настройку, выберите апплет «Свойства обозревателя» на панели управления и перейдите на вкладку «Дополнительно». Установите флажок "Не сохранять зашифрованные страницы на диск" в разделе "Безопасность".

Очиститель кеша

Поглотитель кеша периодически очищает элементы из кеша. Если элемент добавляется в кеш, а кеш заполнен, этот элемент добавляется в кеш, и запускается сборщик кеша. Если поглотитель кеша завершает раунд очистки, а кэш не достиг предела кеша, поглотитель назначается для следующего раунда, когда в кеш добавляется новый элемент. Как правило, сборщик мусора назначается, когда добавленный элемент приводит к превышению лимита размера кеша. По умолчанию минимальное время жизни в кеше установлено на 10 минут, если иное не указано в директиве управления кешем. При запуске очистки кеша нет гарантии, что самые старые элементы будут удалены из кеша первыми.

Кэш используется всеми приложениями WinINet на компьютере для одного и того же пользователя. Начиная с Windows Vista и Windows Server 2008 размер кэша устанавливается равным 1/32 размера диска, с минимальным размером 8 МБ и максимальным размером 50 МБ.

Использование флагов для управления кэшированием

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

Для управления кэшированием можно использовать следующие флаги.

Функции постоянного кэширования

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

Функции кэширования обеспечивают постоянное кэширование и автономный просмотр.Если флаг INTERNET_FLAG_NO_CACHE_WRITE явно не указывает на отсутствие кэширования, функции кэшируют все данные, загруженные из сети. Ответы на данные POST не кэшируются.

Использование функций кэширования постоянных URL

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

Перечисление кеша

Функции FindFirstUrlCacheEntry и FindNextUrlCacheEntry перечисляют информацию, хранящуюся в кэше. FindFirstUrlCacheEntry начинает перечисление, используя шаблон поиска, буфер и размер буфера, чтобы создать дескриптор и вернуть первую запись кэша. FindNextUrlCacheEntry принимает дескриптор, созданный FindFirstUrlCacheEntry, буфер и размер буфера, чтобы вернуть следующую запись кэша.

Обе функции сохраняют структуру INTERNET_CACHE_ENTRY_INFO в буфере. Размер этой структуры варьируется для каждой записи. Если размер буфера, переданный любой из функций, недостаточен, функция завершается ошибкой, и GetLastError возвращает ERROR_INSUFFICIENT_BUFFER. Переменная размера буфера содержит размер буфера, необходимый для извлечения этой записи кэша. Буфер размера, указанного переменной размера буфера, должен быть выделен, и функция должна быть вызвана снова с новым буфером.

Структура INTERNET_CACHE_ENTRY_INFO содержит размер структуры, URL-адрес кэшированной информации, имя локального файла, тип записи в кэше, количество использований, частоту совпадений, размер, время последнего изменения, истечение срока действия, последний доступ, время последней синхронизации, информацию о заголовке, заголовок размер информации и расширение имени файла.

Функция FindFirstUrlCacheEntry принимает шаблон поиска, буфер, в котором хранится структура INTERNET_CACHE_ENTRY_INFO, и размер буфера. В настоящее время реализован только шаблон поиска по умолчанию, который возвращает все записи кэша.

После перечисления кеша приложение должно вызвать FindCloseUrlCache, чтобы закрыть дескриптор перечисления кеша.

В следующем примере URL каждой записи кэша отображается в списке IDC_CacheList. Он использует MAX_CACHE_ENTRY_INFO_SIZE для первоначального выделения буфера, поскольку в противном случае ранние версии WinINet API не перечисляют кэш должным образом. Более поздние версии правильно перечисляют кеш, и нет ограничений на размер кеша. Все приложения, работающие на компьютерах с версией WinINet API от Internet Explorer 4.0, должны выделять буфер необходимого размера. Дополнительные сведения см. в разделе Использование буферов.

Получение информации о записи кэша

Функция GetUrlCacheEntryInfo позволяет получить структуру INTERNET_CACHE_ENTRY_INFO для указанного URL-адреса. Эта структура содержит размер структуры, URL-адрес кэшированной информации, имя локального файла, тип записи в кэше, количество использований, частоту совпадений, размер, время последнего изменения, срок действия, последний доступ, время последней синхронизации, информацию заголовка, размер информации заголовка и расширение имени файла.

GetUrlCacheEntryInfo принимает URL-адрес, буфер для структуры INTERNET_CACHE_ENTRY_INFO и размер буфера. Если URL найден, информация копируется в буфер. В противном случае функция завершается ошибкой, и GetLastError возвращает ERROR_FILE_NOT_FOUND. Если размер буфера недостаточен для хранения информации о записи кэша, функция завершается ошибкой, и GetLastError возвращает ERROR_INSUFFICIENT_BUFFER. Размер, необходимый для извлечения информации, хранится в переменной размера буфера.

В следующем примере извлекается информация о записи кэша для указанного URL-адреса. Затем функция отображает информацию заголовка в поле редактирования IDC_CacheDump.

Создание записи кэша

CreateUrlCacheEntry принимает URL-адрес, ожидаемый размер файла и расширение имени файла. Затем функция создает локальное имя файла для сохранения записи кэша, соответствующее URL-адресу и расширению имени файла.

Используя имя локального файла, запишите данные в локальный файл. После записи данных в локальный файл приложение должно вызвать CommitUrlCacheEntry.

CommitUrlCacheEntry принимает URL-адрес, локальное имя файла, срок действия, время последнего изменения, тип записи кэша, информацию заголовка, размер информации заголовка и расширение имени файла. Затем функция кэширует данные в файле, указанном в хранилище кеша, и связывает его с заданным URL-адресом.

В следующем примере имя локального файла, созданное предыдущим вызовом CreateUrlCacheEntry и сохраненное в текстовом поле IDC_LocalFile, используется для сохранения текста из текстового поля IDC_CacheDump в записи кэша. После записи данных в файл с помощью fopen, fprintf и fclose запись фиксируется с помощью CommitUrlCacheEntry.

Удаление записи кэша

Функция DeleteUrlCacheEntry принимает URL-адрес и удаляет связанный с ним файл кеша. Если файл кеша не существует, функция завершается ошибкой, и GetLastError возвращает ERROR_FILE_NOT_FOUND.Если файл кеша в настоящее время заблокирован или используется, функция завершается ошибкой, и GetLastError возвращает ERROR_ACCESS_DENIED. Файл удаляется при разблокировке.

Получение файлов записей кэша

Для приложений, которым требуется имя файла ресурса, используйте функции RetrieveUrlCacheEntryFile и UnlockUrlCacheEntryFile. Приложения, которым не требуется имя файла, должны использовать функции RetrieveUrlCacheEntryStream, ReadUrlCacheEntryStream и UnlockUrlCacheEntryStream для извлечения информации из кэша.

RetrieveUrlCacheEntryFile принимает URL-адрес, буфер, в котором хранится структура INTERNET_CACHE_ENTRY_INFO, и размер буфера. Функция извлекается и блокируется для вызывающей стороны.

После использования информации в файле приложение должно вызвать UnlockUrlCacheEntryFile, чтобы разблокировать файл.

Группы кеша

Чтобы создать группу кэша, необходимо вызвать функцию CreateUrlCacheGroup, чтобы сгенерировать GROUPID для группы кэша. Записи можно добавить в группу кэша, указав URL-адрес записи кэша и флаг INTERNET_CACHE_GROUP_ADD в функцию SetUrlCacheEntryGroup. Чтобы удалить запись кэша из группы, передайте URL-адрес записи кэша и флаг INTERNET_CACHE_GROUP_REMOVE в SetUrlCacheEntryGroup.

Функции FindFirstUrlCacheEntryEx и FindNextUrlCacheEntryEx можно использовать для перечисления записей в указанной группе кэша. После завершения перечисления функция должна вызвать FindCloseUrlCache.

Обработка структур с информацией о переменном размере

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

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

Что это такое, какие компоненты используют папку WebCache, можно ли отключить это кеширование?

Если это связано с Internet Explorer, отключение IE в функциях остановит его или вам придется удалить весь IE?

Я остановил задачу Wininet и удалил папку WebCache. Не знаю, работает ли это, пока я не перезапущу, так как где-то может быть другой переключатель. Я не могу удалить папку webcache без разрешения, cmd стонет, что она используется, интересно, чем. Есть несколько других папок, которые выглядят как кэширование IE в C:\Users\username\AppData\Local\Microsoft\Windows. Черт возьми, WebCache был воссоздан, fsb.

Клэнджер

Известный участник

Я получил пакетный файл от TairikuOkami , он опубликовал отдельный файл, но он является частью его файла Windows Tweaks. Он закрывает веб-кэш, и папка не воссоздается, диван так хорош, но я не работаю с компьютером в автономном режиме, поэтому я не знаю, работает ли он, когда он онлайн, он говорит, что это работает для него.

Я сравню ваши записи и его, посмотрим, смогу ли я объединить и посмотреть, что получится, как вы сказали, это не стоило хлопот, мне самому это интересно.

Это его файл, я удалил веб-ссылки из оригинала. Перезапустите, затем удалите папку веб-кэша.

Не используйте приведенный ниже код в Windows 8.1, это нарушит работу проводника.

Клэнджер

Известный участник

[-HKEY_CLASSES_ROOT\WinInetCache.WinInetCache]
[-HKEY_CLASSES_ROOT\WinInetCache.WinInetCache.1]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WinInetCache.WinInetCache]
[-HKEY_LOCAL_MACHINE\SOFTWARE \Classes\WinInetCache.WinInetCache.1]


Файл e_web Tairiku дает проводнику жесткое предупреждение, и он жалуется на высшую лигу, проводник перезагружается, и я не всегда получаю пригодный для использования рабочий стол, мне приходится перезагружаться. Используйте последние 2 из ваших записей и тот же результат. Вы правы, не стоит хлопот, я сейчас закрою это.

идроко

Новый участник

Удаление [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\<0358b920-0ac7-461f-98f4-58e32cd89148>] (на любой Win7–Win10) оставит кеш фиксированным в 0, местоположение пустым и нарушит работу Office Outlook: Не отображаются изображения из-за отсутствия временной папки. Исправить этот беспорядок нигде в Интернете. Решение заключается в восстановлении этого ключа регистрации и, возможно, также может потребоваться восстановление папок кэша по умолчанию:

Редактор реестра Windows версии 5.00

; Исправляет размер кэша настроек параметров Интернета, фиксированный в 0 и пустом месте.

кэширование задач

ИДГ

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

Пока все хорошо. Теперь мы много раз использовали кэширование данных в наших приложениях для повышения производительности приложения. Но мы также можем кэшировать объекты Task!

Кэширование задач

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

Что делать, если Задача не удалась? Обратите внимание, что мы не должны кэшировать неудачные или неисправные задачи, т. е. отрицательное кэширование не должно рассматриваться. Давайте теперь углубимся в код и поймем, как это можно реализовать.

Реализация кэширования задач

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

публичная статическая асинхронная задача GetOrAddDataInCache(строковый ключ)

вернуть Task.FromResult (null);

if (!cache.TryGetValue(ключ, выходной результат))

результат = ожидание SomeMethodAsync();

Здесь используется следующая коллекция кеша:

статический кэш ConcurrentDictionary = new ConcurrentDictionary();

Теперь в этом примере мы кэшировали данные, а не экземпляр Task. Следующий метод иллюстрирует, как можно добиться кэширования задач.

публичная статическая асинхронная задача GetOrAddTaskInCache(строковый ключ)

вернуть Task.FromResult (null);

if (!cache.TryGetValue(ключ, выходной результат))

result = await Task.FromResult(SomeMethodAsync());

Обратите внимание, как объект Task добавляется в кеш, если он недоступен. Если экземпляр Task доступен в кэше, он возвращается в противном случае, выполняется вызов асинхронного метода, и результирующий экземпляр Task вставляется в кэш.

А вот и объект кеша для справки.

статический ConcurrentDictionary > cache = new ConcurrentDictionary >();

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

публичная статическая асинхронная задача SomeMethodAsync()

//Напишите здесь свой код для какой-нибудь длительной операции

ждать Task.Delay(100); //Имитирует задержку в 100 миллисекунд

вернуть "Привет, мир!";

Хорошо, но нужно ли всегда кэшировать объекты Task? Точно нет! Обычно накладные расходы на выделение конечного автомата при создании экземпляра задачи незначительны, но вы все равно можете воспользоваться преимуществами кэширования задач, когда вам нужно часто выполнять относительно дорогостоящие операции в ваших приложениях.

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

Читайте также: