R0 CREW

Антируткиты - в поисках процессов

Предисловие.

Эта статья не предназначена для разжёвывания материала новичкам. Предполагается, что вы обладаете минимальным набором знаний в области программирования драйверов для Windows. Также предполагается, что вы хотя бы в общих чертах владеете информацией об устройстве ОС Windows и знакомы с темой руткитов. Ниже приводятся ссылки, помогающие восполнить пробелы в вашей подготовке, если они имеются:

Windows Internals на русском - четвёртое издание

Windows Internals на английском - пятое издание

Уолтер Они - Использование WDM

Хоглунд и Батлер - Руткиты, Внедрение в ядро Windows

Всё, что здесь написано, справедливо для ОС Windows XP SP3. Возможно, информация правдива и для других сервиспаков, но мне было лень это проверить. Что касается других версий Windows, то их обладателям предлагается скачать отладочные символы и с помощью pdbdump узнать и скорректировать смещения нижеописываемых структур.

Руткиты вокруг нас.

Случалось ли вам стать жертвой вируса или эксплоита? Я не жду ответа на этот вопрос, т.к. он носит больше риторический характер. Любой, кто понимает смысл этих терминов, ответит утвердительно. Каждый, кто хоть раз имел дело с этой гадостью не как создатель последней, согласится, что стал жертвой не по своей воле (к вирусным аналитикам – не относится, у них карма такая). И действительно – на практике всё очень просто: либо товарищ принёс флэшку с фильмом, а потом этот «фильм» ещё неделю вычищали из системы, либо вы подключились к интернету, а дальше всё произошло само собой.

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

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

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

За свою очень скромную практику борьбы с руткитами я понял, что лишь очень немногие из них являются действительно стойкими к направленным атакам по их удалению. Большинство же удалятся из вашей системы с полпинка – пара ключей реестра, несколько перехватов – по сути, это всё, что связывает руткит с вашей ОС. Другое дело – скрытность. Для того, чтобы найти руткит, нужно его искать.

Правильно спроектированный вирус или эксплоит обязательно содержит руткит, который сделает их работу прозрачной для пользователя. А если пользователь не видит ничего «подозрительного», зачем ему тогда пытаться найти зловредный код? Ведь «всё работает и так» (Если бы вы знали, сколько раз я слышал эту фразу!).

Приведу простой пример из жизни – один мой друг жаловался, что с его компьютером происходят «странные вещи». Я посоветовал ему скачать RKU, что он и сделал. Позже мы с ним встретились, и я спросил, не нашёл ли он чего у себя. И как ему вообще Rootkit Unhooker. В ответ он сказал, что RKU он удалил, но перед этим запустил его один раз. Там было «ничего не понятно», но какие-то перехваты были, кажется, в Services.exe. Короче – он (RKU) ничего не нашёл. Знаете, я даже не знал, что на такое ответить!

Больше ни примеров, ни задач из жизни приводить не буду. Вернёмся к нашему злободневному вопросу. Я заметил, что очень часто руткит разрабатывается отдельно от других проектов, он вообще может быть никак не связан с программными компонентами, которыми будет пользоваться атакующий. У руткита – две основные задачи: скрыть и защитить зловредный код.

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

Как вы понимаете, некоторые из вышеперечисленных компонентов могут отсутствовать. Некоторые могут быть объединены друг с другом. Но вышеописанная ситуация наиболее удобна злоумышленнику, поскольку позволяет усовершенствовать какой-то один модуль, не пересобирая все остальные.

Логичным будет вопрос – а как же антивирус? Антивирусы сейчас активно развивают технологии противодействия руткитам, но на сегодня эти технологии оставляют желать лучшего. Более подробно вопросы, связанные с антивирусами, здесь рассматриваться не будут.

На вопрос «как противостоять руткитам» есть ответ: «нужно искать их». В принципе, что именно искать, ясно и так. Когда вы запускаете RKU, там чётко написано, на что нужно обратить внимание. Что-то добавить к этому списку сложно. Но т.к. RKU доступен не только нам с вами, но и злоумышленникам, руткит может атаковать конкретно RKU, или же скрываться только от тех методик, которые реализованы в этом прекрасном антирутките.

Давайте рассмотрим простейший этап поиска скрытых процессов. На эту тему есть прекрасная статья:

Обнаружение скрытых процессов

автор которой, тем не менее, утверждает, что каждый из упомянутых там способов обнаружения процессов можно обойти. RKU не использует всё разнообразие методик, которые описаны там. А даже, если бы и использовал, возможность сокрытия от него всё равно оставалась бы.

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

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

Поиск процессов.

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

С чего стоит начать поиск? Очевидно, штатные утилиты третьего кольца защиты тут не подходят. Нужен поиск в ядре? Ладно, загрузим в ядро свой драйвер, но что дальше? Давайте посмотрим, как работает недокументированная PspCreateProcess. Если у вас возник вопрос, почему на неё, то скажу, что в ХР и старше процесс создаётся с помощью NtCreateProcessEx, которая вызывает PspCreateProcess. Последняя проделывает всю основную работу, а NtCreateProcessEx – просто обёртка вокруг неё. Более подробно про создание процесса – уже упоминавшиеся Соломон и Руссинович.

Мы не будем изучать всю работу PspCreateProcess досконально, рассмотрим только самое начало. Вначале вызывается ObReferenceObjectByHandle, основная задача которой - увеличить счётчик ссылок на объект-процесс. Далее ObCreateObject создаёт объект-процесс, о чём свидетельствует её второй параметр PsProcessType. Вещи, которые происходят дальше, на данном этапе нам менее интересны. Мы же уделим внимание диспетчеру объектов.

Диспетчер объектов предоставляет набор недокументированных функций для манипулирования объектами ОС. Тем не менее, кое-какую информацию можно извлечь из «Внутреннего устройства Windows», которое уже ранее упоминалось. Информация оттуда, а также реверсинг ОС позволяют понять, что для создания объекта функции ObCreateObject нужно указать тип этого объекта. PsProcessType – это всего лишь указатель на структуру OBJECT_TYPE. Помимо всего, что нас сейчас не интересует, эта структура содержит значение счётчика объектов заданного типа. Т.е. в нашем случае она содержит счётчик процессов. Взгляните на объявление, полученное из отладочных символов с помощью утилиты pdbdump:

Поле TotalNumberOfObjects как раз и представляет для нас интерес. Как только ObCreateObject создаст новый объект-процесс, этот счётчик сразу увеличится на 1. Внутри ObCreateObject вызывается ObpAllocateObject, в которую четвёртым параметром передаётся уже известный нам PsProcessType. В случае успешного создания объекта выполняется следующий код:

lea     eax, [esi+50h]
lock xadd [eax], edx

В esi – структура OBJECT_TYPE, а в edx:

xor     edx, edx
inc     edx

Таким образом, метод определения наличия скрытых процессов сводится к чтению этой переменной из ядра, а потом – сравнению полученного значения с количеством процессов, посчитанным в третьем кольце. Например, мы определяем, сколько процессов мы смогли перечислить через Toolhelp API, а потом сравниваем это количество с TotalNumberOfObjects. Если равенство не наблюдается – в системе есть скрытые процессы.

В случае, когда объект удаляется, вызывается ObpFreeObject. Код, который уменьшает TotalNumberOfObjects, выглядит так:

lea     edx, [ecx+50h]
or      edi, 0FFFFFFFFh
lock xadd [edx], edi

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

Вывод.

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

Исходники к статье

ARCHANGEL © AHTeam, r0 Crew

Не плохо, так же от более “продвинутых” руткитов можно написать простой дров, который будет контролировать ZwLoadDriver и NtOpenSection. Но это уже немного за рамками этой статьи, так как здесь речь шла только о процессах.

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