Russian
Интернет находится в нормальном состоянии, крупных эпидемий и других серьезных инцидентов службой мониторинга «Лаборатории Касперского» не зафиксировано. Уровень опасности: 1

Вернуть все как было

Вячеслав Русаков
Эксперт «Лаборатории Касперского»
опубликовано 19 июн 2009, 17:16  MSK
Сюжеты: Руткиты, Противодействие антивирусам
1
 

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

Мешать антивирусному продукту можно различными способами. Можно использовать руткит-технологии для предотвращения обнаружения и удаления, а можно следить за своими компонентами и, в случае удаления, восстанавливать их. Рассмотрим те, которые восстанавливают компоненты в случае их лечения антивирусным продуктом.

Некоторые из способов, которые используются в современных вредоносных программах под Windows:

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

Вышеперечисленные способы - основные, однако, вариаций существует намного больше.

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

Авторы данного руткита подошли к вопросу о перепроверке MBR с интересной стороны. На ранней стадии загрузки операционной системы запускается поток в режиме ядра, который в цикле проверяет наличие в памяти системного процесса explorer.exe и ожидает его завершения. После инициации перезагрузки операционная система завершает все процессы, в том числе и explorer.exe. Схематично этот код выглядит так:

NTSTATUS InitThreadWithExplorer(...)
{
        // выделяем память под MBR
        status = AllocateAndZeroMemory( &g_MainMbrBuf, 512, 0, ' kdD' );

        // читаем зараженный MBR в глобальный буфер
        status = SendIrpMjRead( g_MainMbrBuf ); 

        // запускаем поток, который находит explorer.exe и ждет
        status = RunSystemThread( FindExplorerWaitAndCallOnReboot, ... ); 
}

NTSTATUS FindExplorerWaitAndCallOnReboot(...)
{
        // запускаем цикл поиска explorer.exe
        do
        {
                explorerpid = ReturnProcessPidByName( L"explorer.exe" );

                // если найден explorer.exe, то выходим из цикла
                if ( explorerpid )
                        break;
        } while(...);

        // получаем объект процесса explorer.exe по его идентификатору
        status = PsLookupProcessByProcessId( explorerpid, &pProcess  );

        // ожидаем завершения процесса explorer.exe
        KeWaitForMultipleObjects( 2, &Objects, WaitAny, 0, 0, 0, 0, 0 )

        // если explorer.exe завершился, то вызываем функцию проверки MBR
        CallOnReboot(...);
}

Функция CallOnReboot сравнивает текущий MBR с эталоном (зараженной загрузочной записью). Делается это для того, чтобы на момент перезагрузки системы восстановить вылеченную антивирусом загрузочную запись:

NTSTATUS CallOnReboot(...)
{
        pMBR = 0;

        // выделяем память под MBR
        status = AllocateAndZeroMemory( &pMBR, 512, 0, ' kdD' );

        // читаем MBR
        status = SendIrpMjRead( pMBR );

        i = 0;

        // запускаем цикл проверки
        do
        {
                k = i;
                l = i;

                // если какой-либо байт MBR отличается, то выходим из цикла
                if ( *(_BYTE *)(pMBR + i) != *(_BYTE *)(g_MainMbrBuf + i) )
                        break;

                k = i++ + 1;

        } while ( l < 432 );

        // если был найден отличающийся байт
        if ( k < 432 )
        {
                // копируем в pMBR зараженный MBR
                memmove( pMBR, g_MainMbrBuf, 432u );

                // перезаписываем вылеченный MBR
                status = SendIrpMjWrite( pMBR );
        }
}

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


11 комментариев

старые сверху
«дерево»
 

aglu

21 июн 2009, 17:31
0
 

Ух ты! Мне попадался пару раз этот вирусок, спасибо)))

Danilka

22 июн 2009, 11:47
2
 

Re:

"Спасибо" за то что попадался?

Fixxxer

22 июн 2009, 18:15
1
 

Кстати о Бутките

Кстати, последняя версия буткита GMERом детектится? И по каким перехватам (в AVZ) лучше его отслеживать? В статье фигурировал, например, IRP_MJ_INTERNAL_DEVICE_CONTROL 81ae35a0 - это показательно или есть иные признаки?

Вячеслав Русаков

22 июн 2009, 21:08
0
 

Re: Кстати о Бутките

Последняя версия только так и детектируется, плюс конечно же проверка MBR'ов считанных двумя способами.

Fixxxer

23 июн 2009, 16:25
0
 

Re: Re: Кстати о Бутките

"Только так" - это как? Я просто два варианта написал.

Вячеслав Русаков

23 июн 2009, 20:58
1
 

Re: Re: Re: Кстати о Бутките

По IRP_MJ_INTERNAL_DEVICE_CONTROL .

Fixxxer

23 июн 2009, 22:38
0
 

Re: Re: Re: Re: Кстати о Бутките

А что насчёт Gmer или RkU?

Вячеслав Русаков

24 июн 2009, 19:32
0
 

Re: Re: Re: Re: Re: Кстати о Бутките

Не смотрел. RKU думаю что-то увидит, может перехват, но врядли поможет в лечении. Gmer - не знаю. RootRepeal может, если доточили для последней модификации :)

Umnik

29 июн 2009, 16:20
0
 

RootRep

Последняя модификация - это .def и иже с ней? Если да, то RR справляется.

Umnik

29 июн 2009, 17:13
2
 

Поздравляю

Да, кстати. Что-то не поздравил тебя с первой записью. Спешу сделать это хоть сейчас :)

Вячеслав Русаков

02 июл 2009, 12:28
2
 

Re: Поздравляю

Спасибо! Не последняя, я надеюсь :)

Для добавления комментариев необходимо