вторник, 31 января 2017 г.

Можно ли скрыть ключ в реестре изменив 1 бит?

Таким вопросом я задался когда-то давно, и тогда же получил ответ, а сейчас хочу его озвучить.

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

Тем не менее, изменив 1 бит можно скрыть любой ключ реестра. Как это возможно?

Это возможно, если установить CM_KEY_CONTROL_BLOCK *keyCtrlBlock->TransKCBOwner не равным нулю, то есть достаточно установить 1 бит, чтобы сделать ключ реестра невидимым для regedit и системы в целом.

Как такое возможно? Все дело в транзакциях, именно так они работают.

NtOpenKey => CmpBuildHashStackAndLookupCache => CmpCacheLookup => CmRmIsKCBVisible => if (CM_TRANS *transOwner = keyCtrlBlock->TransKCBOwner ) != NULL ).

Собственно, в этом и кроется ответ, достаточно изменить один бит в keyCtrlBlock->TransKCBOwner и ключ реестра станет невидимым для любых существующих антивирусов и антируткитов.

Как это ловить? Да очень просто, перечисляем транзации, сравниваем их хендлы с keyCtrlBlock->TransKCBOwner, если не равно - руткит активность!

А можно ли обойти то, что описано выше? Естественно! Просто создаем валидную транзакцию, которая скрывает ключ реестра, но восстанавливает/удаляет ее когда нужно!

Что такое транзакции и как они работают я постараюсь описать в следующих постах.