• XSS.stack #1 – первый литературный журнал от юзеров форума

[?] Хуки AV в ядре

xChimera

Malware...
Пользователь
Регистрация
19.08.2024
Сообщения
778
Реакции
552
Гарант сделки
2
Депозит
0.0282
Касаемо юзермода все ясно, интересуют возможности ав в ядре

В ядре насколько я знаю есть различные колбеки - создание процесса, потока, загрузка изображение (NtOpenSection + NtMapViewOfSection)

А что на счет других апи? Ставить патч в SSDT - прямой путь к бсоду из за патч гварда

Слышал про гипервизоры, и мол у аваста он есть - но пишут их на отъебись
 
все на мини фильтрах и калбеках.
хуки стали проблемными из-за производительности и уже нормально не обработать хуки в многоядерных системах
 
Хуки возможны


Через ETW в ядре хукает, врубается логирование и потом подменяется nt!HalpPerformanceCounter.QueryCounter <- он патч гвардом не защищён и тянется из EtwpReserveTraceBuffer а ЕТВ ( если включено в кернеле логирование ) тянется из сисколов. Может из графических не тянется но это можно самому проверить в дизасме

Более того если делаешь авкил для сентинела или фалкона эти хуки убирать надо - вот этот поинтер nt!HalpPerformanceCounter.QueryCounter заменять
 
Слышал про гипервизоры, и мол у аваста он есть - но пишут их на отъебись
Конкретно аваста - да, его в принципе использует ещё кто-то помимо самих авастов (исходя из пары функций его инициализации). Помнится, что на старых его версиях (пару лет назад) можно было девиртуализовать ядра (не помню причину правда, то ли из-за неправильной обработки NMI, то ли из-за чего-то ещё).
Как правило у гипервизоров это страничные EPT/NPT хуки (в зависимости от вендора процессора будет либо VT-x, либо SVM, всё настолько прекрасно, что даже базовый VMCB будет отличаться у двух вендоров). Как правило, конкретно аверы не сильно заморачиваются и можно детектить присутствие страничных хуков, например через тайминг чеки или через чеки на запись (как это делается - можно найти самостоятельно), что, наверное, облегчит некоторые задачи. Fun fact: KPP тоже детектит страничные хуки, смотри на так называемые Errata функции.

А что на счет других апи? Ставить патч в SSDT - прямой путь к бсоду из за патч гварда
Как и закинули выше - многие придумывают форки InfinityHook (найди на гитхабе) и атакуют ETW, прибавляй сюда коллбеки, которые ты сам упомянул.
Есть ещё пара методов, например, абьюзить поле AltSyscall в KTHREAD, предварительно зарегистрировав обработчик через PsRegisterAltSystemCallHandler, в обработчик приходит trap frame со всеми регистрами. Но если мне память не изменяет - это работает только для одного процесса и можно зарегать только один обработчик, и то когда повезёт, так как и свободный обработчик может быть занят и ты бсоднешься спокойно (прибавляем факт, что нужно инициализировать его до инита KPP). Немного не про сисколлы, но если вдруг нужно - есть такая ядерная забава - Kernel Shim Engine, которая хукает IAT драйверов и обработчики внутри драйвера (DispatchIO, FastDispatch, Create и т.д) - может кому-то пригодится инфа (эту вещь можно обнаружить по дополнительному полю внутри DRIVER_OBJECT), уверен, что её кто-то да юзает (помимо каспера, хотя вроде бы и не юзает уже).

По сути - форки InfinityHook и гипервизоры это самый распространённый вариант сейчас.

Вы должны провести 100 дней на форуме для просмотра контента.
 
Хуки возможны


Через ETW в ядре хукает, врубается логирование и потом подменяется nt!HalpPerformanceCounter.QueryCounter <- он патч гвардом не защищён и тянется из EtwpReserveTraceBuffer а ЕТВ ( если включено в кернеле логирование ) тянется из сисколов. Может из графических не тянется но это можно самому проверить в дизасме

Более того если делаешь авкил для сентинела или фалкона эти хуки убирать надо - вот этот поинтер nt!HalpPerformanceCounter.QueryCounter заменять
Также достаточно просто обнулить _ETW_SILODRIVERSTATE.SystemLoggerSettings.EtwpActiveSystemLoggers (смещение 0x1098 относительно silodriverstate, сам адрес можно вытащить из EtwSendTraceBuffer). Проверял на аваст, это работает.
 
Сталкивался ли кто-то с редким патч гуардом (в 2-3% случаев) при обнулении CallbackNodes[50] в FLT_INSTANCE? Альтернативы простому обнулению не нашел, пробовал заменять _CALLBACK_NODE.PreOperation и _CALLBACK_NODE.PostOperation на гаджеты mov eax, 1; ret и xor eax, eax; ret, но, что очевидно, срабатывает патч гуард.
 
Сталкивался ли кто-то с редким bugcheck KERNEL_SECURITY_CHECK_FAILURE (в 2-3% случаев) при обнулении CallbackNodes[50] в FLT_INSTANCE?
Это же багчек KPP, после того, как он решил запустить свои коллбеки для проверки целостности ядреных структур (у него разные тайминги, видимо поэтому и "редкий"). Ноды с пре и пост операциями, которые ты обнуляешь - обнулять, логично, нельзя, так как это коллбеки, которые по кд юзаются минифльтрами.

Если речь идёт о хуке коллбеков минифильтра, то есть два варианта:
1. Спиздить сам минифильтр, но как это делать - надо ресёрчить.
2. Если есть возможность прокидывать драйвера, то:
а) Найти самостоятельно нужный минифильтр;
б) Извлечь его таблицу коллбеков и ЗАКЕШИРОВАТЬ её;
в) В каждой ноде пройтись по полям PreOperation и PostOperation, если они валидные - похукать обе. Тут подойдёт pointer swap (i.e хукаем через вызов условного InterlockedExchangePointer);
г) Когда минифильтр вызовет коллбек и попадёт на наш хук, то после всех необходимых операций в обязательном порядке вызываем оригинальную функцию.
 
Это же багчек KPP, после того, как он решил запустить свои коллбеки для проверки целостности ядреных структур (у него разные тайминги, видимо поэтому и "редкий"). Ноды с пре и пост операциями, которые ты обнуляешь - обнулять, логично, нельзя, так как это коллбеки, которые по кд юзаются минифльтрами.

Если речь идёт о хуке коллбеков минифильтра, то есть два варианта:
1. Спиздить сам минифильтр, но как это делать - надо ресёрчить.
2. Если есть возможность прокидывать драйвера, то:
а) Найти самостоятельно нужный минифильтр;
б) Извлечь его таблицу коллбеков и ЗАКЕШИРОВАТЬ её;
в) В каждой ноде пройтись по полям PreOperation и PostOperation, если они валидные - похукать обе. Тут подойдёт pointer swap (i.e хукаем через вызов условного InterlockedExchangePointer);
г) Когда минифильтр вызовет коллбек и попадёт на наш хук, то после всех необходимых операций в обязательном порядке вызываем оригинальную функцию.
Редкий багчек у меня происходит именно в момент обнуления структуры (цикл записи пустой uint64_t вместо указателя), далее через некоторое время никаких багчеков нет. А обнуляю я сам массив указателей в FLT_INSTANCE, а не сами ноды, там предусматриваются что элементы массива могут быть пустыми.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх