четверг, мая 18, 2006

Утилита AVZ v4.16: некоторые "забавные" особенности

В списке доработок и модификаций данной версии утилиты имеются следующие строки:
[+] Доработан avz.sys - введена защита от атаки на драйвер посылкой ему IRP пакетов сторонними приложениями
[+] Доработан AVZ Guard - введено несколько новых контуров защиты процесса AVZ от типовых методик закрытия
процесса, применяемого распространенными троянскими программами

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

Рассмотрим сначала "защиту от атаки на драйвер посылкой ему IRP пакетов сторонними приложениями".

Драйвер утилиты AVZ с именем avz.sys служит двум основным целям:
- обеспечивает поиск перехватчиков системных сервисов в таблице SSDT (KiServiceTable);
- производит блокирование работы kernel mode руткитов.

Чтобы обеспечить выполнение указанных функций, основной модуль утилиты, avz.exe, динамически загружает драйвер avz.sys посредством интерфейса к Service Control Manager (SCM), после чего осуществляет обмен с драйвером путем пересылки IRP пакетов. В частности, таким способом avz.exe может получить адрес таблицы SDT (KeServiceDescriptorTable), адрес таблицы SSDT (KiServiceTable), общее число системных сервисов в таблице SSDT, получить текущий адрес системного сервиса по его номеру, установить новый (и, в том числе, восстановить в оригинал) адрес системного сервиса по его номеру и т.п. Этот обмен информацией до сих пор (до версии 4.16) осуществлялся в полностью открытой форме, что позволяло любому стороннему приложению воспользоваться загруженным драйвером avz.sys в своих целях, и, в частности, воспрепятствовать попыткам AVZ его обнаружить и обезвредить, "завалив систему" в BSOD в тот момент, когда утилита подгружает драйвер. Этому также способствует то обстоятельство, что для выполнения одной из функций драйвера, а именно установки нового адреса системного сервиса по его номеру, avz.exe передает драйверу как номер, так и новый адрес системного сервиса, что, по сути, является довольно опасным с точки зрения безопасности системы действием, т.к. любое злонамеренное приложение может в качестве адреса передать, к примеру, нулевое значение, что неминуемо приведет к падениею системы в BSOD. Некоторые время назад я указал на наличие этой уязвимости в AVZ и написал довольно простое приложение, которое демонстрировало ее, после чего автор, Олег Зайцев, решил "исправить оплошность" и доработал процедуру обмена в новой версии утилиты.

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

Как показало мое небольшое исследование, Олег решил обойтись лишь дополнительной проверкой источника IRP пакета, передаваемого драйверу. "Надежный", или "доверенный" источник (к примеру, модуль avz.exe), прежде чем воспользоваться одной из вышеперечисленных функций драйвера, должен передать драйверу специальный пакет, где в качестве аргументов используются идентификатор "доверенного" процесса, а также 3 числа, сформированные специальным образом. Драйвер сначала проверяет эти числа в соответствии с некоторым алгоритмом, а потом, если проверка успешна, записывает во внутреннюю переменную полученный идентификатор "доверенного" процесса. В дальнейшем только процесс с указанным идентификатором может обращаться к функциям драйвера, всем же остальным процессам выдается код ошибки (STATUS_NOT_IMPLEMENTED). Приведем кусочек кода драйвера avz.sys, где осуществляется эта проверка на "надежность" источника:
.text:00011069            call    ds:IoGetCurrentProcess
.text:0001106F cmp ebx, 222024h ; DeviceIoControl.IoControlCode == 'Set "trusted" process Id'?
.text:00011075 jnz short loc_110A3 ; No, skip...
.text:00011077 cmp [esp+18h+var_8], 10h ; DeviceIoControl.OutputBufferLength == 16?
.text:0001107C jb short loc_110A3 ; No, skip...
.text:0001107E mov ecx, [ebp+0Ch] ; UserBuffer.argC
.text:00011081 mov eax, [ebp+8] ; UserBuffer.arg8
.text:00011084 mov edx, [ebp+4] ; UserBuffer.arg4
.text:00011087 lea eax, [ecx+eax+5] ; arg8 + argC + 5
.text:0001108B imul eax, ecx ; * argC
.text:0001108E cmp edx, eax ; arg4 == (arg8 + argC + 5) * argC ?
.text:00011090 jnz short loc_110A3 ; No, skip...
.text:00011092 cmp eax, 5DCh ; (arg8 + argC + 5) * argC > 1500
.text:00011097 jbe short loc_110A3 ; No, skip...
.text:00011099 mov eax, [ebp+0] ; UserBuffer.arg0 == "trusted" process Id
.text:0001109C mov _dwProcessId, eax ; Set "trusted" process Id
.text:000110A1 xor esi, esi
.text:000110A3
.text:000110A3 loc_110A3:
.text:000110A3 call PsGetCurrentProcessId
.text:000110A8 cmp eax, _dwProcessId ; CurrentProcessId == "trusted" process Id?
.text:000110AE jnz loc_112A1 ; No, return STATUS_NOT_IMPLEMENTED code
.text:000110B4 cmp ebx, 222000h ; DeviceIoControl.IoControlCode == 'Get SDT address'?
.text:000110BA jnz short loc_110DC ; ...etc.

Как видим, автор утилиты в качестве "головоломки" предлагает решить нам следующую систему с 3-мя неизвестными:
x = (y + z + 5) * z
x > 1500

Положим y = 0, тогда получаем систему с 2-мя неизвестными:
x = (z + 5) * z
x > 1500

Для простоты перепишем ее в качестве следующего неравенства с одним неизвестным:
(z + 5) * z > 1500

Возьмем z = 40, тогда:
x = (z + 5) * z = 45 * 40 = 1800

Итак, в результате мы имеем: x = 1800, y = 0, z = 40. Теперь эти цифры, наряду с идентификатором текущего процесса, можно использовать в качестве параметров, передаваемых в драйвер avz.sys!

Вот такой немного примитивной проверкой автор AVZ решил обмануть взломщиков своей программы! :) Для демонстрации указанной уязвимости я немного переделал свой "эксплойт", добавив в него код для установки собственного процесса в качестве доверенного. Его исходный текст и исполнимый модуль вы сможете найти здесь: AVZDriverCrash. Будьте, однако, внимательны и осторожны: этот "эксплойт" укладывает систему в BSOD в тот момент, когда вы посредством кнопки "Пуск" в AVZ начинаете исследование системы и дело доходит до пункта "1.2 Поиск перехватчиков API, работающих в KernelMode"!. Если же во время запуска "эксплойта" на выполнение драйвер AVZ уже загружен - произойдет немедленный BSOD!

У вас, возможно, возник вопрос, а зачем все эти танцы с бубнами вокруг установки и проверки в драйвере идентификатора доверенного процесса?. Не проще ли было сделать это ровно один раз или не делать вообще - ведь утилита, будучи запущенной, динамически загружает драйвер, а потом динамически выгружает его? Так вот, дело обстоит несколько сложнее. Все эти "игры" с идентификаторами процессов нужны для тех случаев, когда пользователь загружает несколько экземпляров утилиты одновременно - в результате все эти экземпляры обслуживаются одним единственным (загруженным первым) драйвером! Когда последний экземпляр AVZ завершает работу, он и выгружает драйвер! Хорошо, скажете вы, а почему бы тогда не запретить возможность запуска нескольких экземпляров утилиты - ведь это сразу бы решило все проблемы! Однако же и тут есть подводный камень: к сожалению, практически вся утилита (за исключением момента, когда идет сканирование файловой системы) написана в одном потоке (thread), ее GUI в этом смысле не отделен от функциональной части, и - даже более того - повсюду используются т.н. модальные окна, что вообще препятствует одновременному отображению более чем одного окна! Таким образом, программа, позиционируемая как "утилита для исследования системы" превращается в очень неудобный для всестороннего исследования системы инструмент, имея, тем не менее, все функциональные составляющие для такого исследования! В результате, для того чтобы с помощью утилиты получить более-менее исчерпывающую картину состояния системы, приходится загружать одновременно несколько (иногда 6-8) ее экземпляров!

Итак, с IRP пакетами мы как-будто разобрались, теперь можно перейти ко "второму блюду нашего меню", т.е. к тому, что в "AVZ Guard введено несколько новых контуров защиты процесса AVZ от типовых методик закрытия процесса, применяемого распространенными троянскими программами".

Я готов поверить в то, что троянские программы в своей массе довольно примитивны и пользуются, в основном, довольно простыми и хорошо описанными методиками - это касается, естественно, и "типовых методик закрытия процесса". Режим AVZGuard, введенный в версии 4.15 утилиты AVZ, одной из своих главных задач как раз и поставил защиту процесса avz.exe от возможного терминирования злонамеренными программами. Насколько она успешна, можно судить о той критике, которой подвергся этот режим, на форуме VirusInfo. Понимая, что простой защиты может быть не всегда достаточно (а, может быть, и вняв указанной критике), автор утилиты ввел ряд модификаций в драйвер avzsg.sys, являющийся "сердцем" режима AVZGuard. Я не буду сейчас подробно останавливаться на этих доработках (возможно, я сделаю это позднее) - скажу лишь то, что самый простой метод терминирования процесса avz.exe, о котором я рассказал еще при обсуждении версии 4.15, успешно работает до сих пор! Да, речь идет о терминировании с использованием стандартного "Диспетчера процессов" (taskmgr.exe), входящего в состав операционной системы! Тогда, во время обсуждения, автор сослался на то, что трояны не будут применять таких методик, потому что это, якобы, "довольно сложно" для них! Насколько это на самом деле просто, вы можете убедиться сами: для демонстрации этой возможности я написал небольшую программу, исходный текст и исполнимый модуль которой вы сможете найти здесь: AVZGuardKill. Программа должна быть запущена на выполнение до установки в AVZ режима AVZGuard или же вообще до запуска AVZ (как это бывает с большинством злонамеренных программ), чтобы произошло терминирование процесса avz.exe. Кроме того, программа будет ждать именно установки режима AVZGuard, чтобы показать, что именно в этом режиме она эффективна против AVZ! Не забудьте также, что после терминирования AVZ драйвер avzsg.sys будет оставаться активным и продолжать препятствовать запуску других программ, в связи с чем вам ничего не останется, как просто завершить работу компьютера (перегрузиться)!

И еще один момент: старая ошибка, о которой говорилось еще для версии 4.15, так и осталась существовать в новой версии! Суть ее в следующем: если вы запустите AVZ на выполнение и сразу же после этого установите режим AVZGuard, то провести полное исследование системы с поиском kernel mode руткитов вам уже не удастся! Дело тут в том, что AVZ в режиме AVZGuard препятствует, в частности, загрузке драйверов "чужими" процессами, блокируя доступ к реестру, но разрешая все эти действия только своему и доверенным процессам, запущенным пользователем. Учитывая же тот факт, что AVZ делает динамическую установку и загрузку драйвера не самостоятельно, а, как я уже отмечал выше, через интерфейс к SCM, становится понятно, что AVZ активно препятствует выполнению порученной им же функции "недоверенному" процессу SCM - иными словами, AVZ в данном случае опосредованно запрещает загрузку своего собственного драйвера, т.е. "бьет своих, чтобы чужие боялись!" :) Чтобы избежать этого, нужно включать режим AVZGuard только после исследования системы посредством кнопки "Пуск", т.е. после предварительной загрузки драйвера avz.sys!

понедельник, мая 15, 2006

Комментарий к 1-й части статьи Ms-Rem-а 'Инжект как метод обхода фаерволлов...'

Недавно на сайте WASM.RU появилась 1-я часть статьи Ms-Rem'Инжект как метод обхода фаерволлов, жив или мертв?', посвященная методам "обхода" широко известного персонального файерволла Outpost Firewall PRO (далее Outpost FW). Моей первой реакцией на публикацию было недоумение и раздражение, связанные с тем, что, с одной стороны, этот материал не представляет никакой новизны (по крайней мере для тех, кто более-менее "знаком" с Outpost FW), а с другой - тем, что Ms-Rem представил исходные тексты эксплойтов, которые могут быть быстро перенесены в дешевые поделки трояно- и вирусо-писателей, что в конечном счете может неблагоприятно отразиться на пользователях этого продукта.

Вместе с тем, статья содержит ряд ошибок (или неточностей - кому как больше нравится). Оговорюсь сразу, что эти ошибки ни в коей мере не умаляют достоинств автора - ведь, как говорится, "не делает ошибок лишь тот, кто вообще ничего не делает!". В этом посте я опишу лишь несколько ошибок, которые сразу бросились мне в глаза при беглом прочтении. Есть, конечно, и другие неточности - часть из них я опущу в надежде, что вы и сами их найдете. :) Итак, прямо по тексту...

Ошибка 1
В самом начале статьи, в разделе "Outpost Firewall, или пример простой защиты", автор пишет: "Outpost отслеживает инжектинг путем перехвата ZwWriteVirtualMemory в SDT ntoskrnl...". Тут на самом деле две неточности. Первая (не очень существенная) состоит в том, что, конечно же, в SDT (т.е., в Service Descriptor Table, или, точнее, в KeServiceDescriptorTable) никто ничего не перехватывает, ибо там бессмысленно что-то перехватывать. В этом месте, видимо, подразумевалась таблица SSDT (т.е. System Service Dispatch Table, или KiServiceTable), в которой как раз и находятся адреса т.н. "системных сервисов", т.е. функций модуля ntoskrnl.exe с префиксами Nt, которые очень часто перехватываются всякими файерволлами, антивирусными программами, HIPS-ами и т.д. (более подробно см. в очень известной книге 'Undocumented Windows NT', выпущенной издательством M&T Books, текст которой также можно найти на сайте http://www.windowsitlibrary.com). Вторая же неточность (более существенная) состоит в том, что Outpost FW перехватывает не ZwWriteVirtualMemory, а вызов NtWriteVirtualMemory! Пусть вас не смущает то, что имена этих функций очень похожи (и даже более того - одна в конечном счете передает управление в другую) - между этими функциями есть ряд принципиальных различий, связанных со спецификой вызова системных сервисов в user и kernel mode. Не буду сейчас вдаваться в подробности по этому поводу - для тех, кто хочет более детально разобраться в этом вопросе, я рекомендую прочитать статью 'Nt vs. Zw - Clearing Confusion On The Native API' из журнала 'The NT Insider' (см. также на сайте http://www.osronline.com).

Ошибка 2
В следующем абзаце автор пишет: "Экспериментальным путем было установлено, что Outpost позволяет записать в память процесса не более 16 байт данных". Здесь тоже две неточности. Первая: на самом деле в подавляющем большинстве случаев (а, может быть, даже во всех без исключения случаях - этого я не проверял) Outpost FW позволяет записать в память контролируемого процесса любое (приемлемое) количество байт, однако лишь запись 15-ти байт (а не 16-ти, как написано в статье - и это вторая неточность) не вызывает срабатывания "защиты" Outpost FW и, соответственно, блокирования сетевого доступа для этого процесса. Для каждого процесса в системе Oupost FW ведет счетчик суммарно записанных в него байт (неважно каким процессом/процессами), поэтому, к примеру, такая хитрость, как запись 15 байт, потом запись еще 15 байт (например, из другого процесса) и т.д., не сработает, хотя, насколько мне помнится, на форуме WASM Phorum кое-кто из постоянно заявлюящих о своей "крутизне" (не хочу упоминать тут его ник - он и сам себя узнает!) утверждал, что таким образом можно решить "проблему" с защитой Outpost FW! :) Немного позднее я приведу кусочек из драйвера Outpost FW, где будет ясно видно, в каком конкретно месте идет контроль на эти 15 байт.

Ошибка 3
В разделе "Баги в Outpost" (если честно, то я не понял, зачем автор включил этот раздел в статью об инжекте - ведь к инжекту это вообще не имеет никакого отношения!) автор поместил дизассемблированный код из драйвера filtnt.sys, из которого, якобы, видно, что "всем процессам с именем svchost.exe разрешается запись в память других процессов во избежание ложных срабатываний защиты". На самом деле даже беглого взгляда на этот кусочек кода достаточно, чтобы понять, что ничего подобного из него не следует, несмотря даже на такую строку:
.text:00017C84            mov     edi, offset aSvchost_exe ; "SVCHOST.EXE"

Для тех, кто еще не понял, в чем дело, я уточню, что в аргументе arg_8 упомянутой автором "функции с адресом 0x00017B90" находится число записываемых в память процесса байт ("number of bytes to be written to the specified process"). Поместим снова небольшую часть этого кусочка кода с моим комментарием:
.text:00017C79            mov     ecx, [ebp+arg_8]         ; число записываемых в память процесса байт
.text:00017C7C cmp ecx, 4 ; == 4?
.text:00017C7F jnz short loc_17CA0 ; нет, дальнейшая проверка
.text:00017C81 lea esi, [esi+0Eh]
.text:00017C84 mov edi, offset aSvchost_exe ; "SVCHOST.EXE"
.text:00017C89 mov ecx, 18h ; 24 == длина unicode-строки "SVCHOST.EXE"
.text:00017C8E repe cmpsb
.text:00017C90 jnz short loc_17CA0

Действительный же код, который разрешает процессу svchost.exe запись в память других процессов, находится в драйвере filtnt.sys немного дальше (примерно в 150-ти байтах). Я приведу этот кусочек кода (это, естественно, дизассемблер немного другой версии драйвера, так что адресация и некоторые детали могут немного отличаться):
.text:00018B67 loc_18B67:
.text:00018B67 mov eax, [ebx+28h] ; счетчик числа байт, _уже_ записанных в память процесса
.text:00018B6A cmp eax, 10h ; >= 16? (это, кстати, и есть проверка на "те самые" 16 байт)
.text:00018B6D jnb short loc_18B88 ; да, тогда проверим на имя процесса "SVCHOST.EXE"
.text:00018B6F add eax, [ebp+arg8] ; добавим к счетчику число записываемых _сейчас_ байт
.text:00018B72 mov [ebx+28h], eax ; сохраним это значение
.text:00018B75 cmp eax, 10h ; полученная сумма >= 16?
.text:00018B78 jnb short loc_18B88 ; да, проверим на имя процесса "SVCHOST.EXE"
.text:00018B7A mov eax, 1 ; нет, т.е. общая сумма записанных в память процесса байт < 16
.text:00018B7F pop edi ; ... это значит все ОК, разрешить без ограничений
.text:00018B80 pop esi
.text:00018B81 pop ebx
.text:00018B82 mov esp, ebp
.text:00018B84 pop ebp
.text:00018B85 retn 10h
.text:00018B88 loc_18B88: ; а вот и "то самое" место, где имя процесса проверяется
.text:00018B88 mov ecx, [ebp+var_4] ; ... на "SVCHOST.EXE"!
.text:00018B8B mov edi, offset aSvchost_exe ; "SVCHOST.EXE"
.text:00018B90 mov esi, [ecx+0Ch]
.text:00018B93 mov ecx, 18h
.text:00018B98 lea esi, [esi+0Eh]
.text:00018B9B repe cmpsb
.text:00018B9D jnz short loc_18BAD
.text:00018B9F mov eax, 1 ; имя процесса "SVCHOST.EXE" - разрешить все без ограничений
.text:00018BA4 pop edi
.text:00018BA5 pop esi
.text:00018BA6 pop ebx
.text:00018BA7 mov esp, ebp
.text:00018BA9 pop ebp
.text:00018BAA retn 10h

Ошибка 4
Далее, в этом же разделе, автор пишет: "Дальнейшее изучение драйвера оутпоста позволило мне найти еще один баг в нем, видимо в целях отладки программисты писавшие оутпост сделали в драйвере вывод отладочных сообщений (точнее сообщения драйвер выводит не сам, а передает их службе), и в числе прочих сообщений там имеется дамп содержимого инжектируемого куска памяти" и приводит ассемблерный код эксплойта, от которого якобы "система упадет в синий экран". Так вот, опять же беглого взгляда достаточно, чтобы понять, что приведенный код не "уронит" систему! В чем же дело? Обратите внимание на следующую строку кода:
  invoke   WriteProcessMemory, esi, edi, 0, 10, 0

Мы видим, что здесь делается попытка записать в память процесса 10 (!) байт из буфера с адресом 0. Но, как мы помним, только запись 16 и более байт вызывает "реакцию" драйвера Outpost FW и, соответственно, выполнение упомянутого куска кода, который выводит "отладочное сообщение" - именно поэтому данный код никак не может вызвать BSOD! Но... не торопитесь пока делать выводы! Вы еще помните о суммарном счетчике числа байт, записываемых в память процесса, который ведет Outpost FW? Так вот, если данный эксплойт запустить на выполнение не однократно, а дважды (а при этом суммарный счетчик байт, т.е. 10 + 10, превысит пороговое значение в 15 байт!) - система успешно упадет! :) Упадет она, естественно, и с первого запуска эксплойта, если мы все же исправим ошибку и напишем:
  invoke   WriteProcessMemory, esi, edi, 0, 16, 0

Причем в данном случае можно даже не исправлять строку:
  invoke   VirtualAllocEx, esi, 0, 10, MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE

Почему так? Попробуйте догадаться сами! :)

понедельник, марта 20, 2006

Руткит на основе виртуальной машины (VM-based rootkit)

Извините, сообщение ожидается в ближайшее время...

понедельник, марта 13, 2006

Утилита AVZ и ее "белый" список программных файлов: достоинства и недостатки

Как известно, наличие собственного "белого" списка программных файлов (базы "чистых" файлов) выгодно отличает утилиту AVZ от многих анти-троянских программ и является, наряду с возможностью получения файлов-отчетов Исследования системы, безусловным достоинством, отмечаемым многими пользователями утилиты. Однако же, при более детальном рассмотрении оказывается, что в некоторых обстоятельствах это, казалось бы, неоспоримое достоинство может легко превратиться в серьезный недостаток. Итак, ближе к делу...

Несколько дней назад при обсуждении на форуме VirusInfo программ, динамически устанавливающих свои драйверы (путем создания временного файла-драйвера, активации этого драйвера и последущего удаления файла-драйвера - так, как известно, поступают многие программы, в частности, утилиты от компаний Sysinternals, F-Secure, некоторые анти-троянские программы и т.д.), пользователь МОСТ выдвинул предложение о том, что было бы неплохо такие временные файлы помещать в базы "чистых" файлов AVZ с тем, чтобы они при анализе (в частности, в Исследовании системы) не попадали в "черный" список и не смущали неопытного пользователя.

Не будем сейчас останавливаться на том, как это лучше сделать - путем ли "выдирания" этих файлов из ресурсов, посредством ли программ восстановления файлов на диске или еще как-то (с последующим добавлением в базу "чистых") - это не важно, т.к. проблему попадания таких файлов в "черный" список AVZ, как оказалось, это вообще не решает! Связано это с тем, что AVZ, чтобы принять решение о том, поместить ли файл, соответствующий некоторому процессу/модулю, в "белый" список или нет, должен непременно увидеть этот файл на диске, т.е. проверяемый файл банально должен существовать в момент проверки - а иначе, казалось бы, как сравнить сигнатуру и ее объект? Отсюда мы сделаем вывод #1: файл, соответствующий процессу/модулю, но не существующий в момент проверки сигнатуры на диске, AVZ стопроцентно помещает в "черный" список.

Для проверки этого обстоятельства я провел простой эксперимент. AVZ, как известно, помещает свой основной драйвер, avz.sys, в "белый" список:



Я загрузил AVZ, затем "на лету" переименовал этот файл, avz.sys, в _avz.sys (т.е. файл драйвера для AVZ как бы "исчез"!) - и AVZ сразу же поместил его в "черный" список:



Тогда я пошел дальше: вместо оригинального avz.sys, который так и остался пока что переименованным, я сделал копию avz.exe и переименовал ее в avz.sys - AVZ, само собой, никакого подлога не заметил и сразу же стал считать "новый" avz.sys (а на самом деле - старый avz.exe) "чистым" (обратите внимание на длину файла avz.sys в папке AVZ!):



OK, подумал я, а что будет, если начать "подменять" файлы на диске, т.е. после запуска "грязного" файла-оригинала его тут же переименовывать (не важно, в какое имя!), а в каталог, где он лежит, переписывать заведомо "чистый", например, системный, файл, давая ему старое имя "грязного" файла-оригинала? И - о чудо! "Грязные" файлы, с которыми я провел такие манипуляции, тут же для AVZ превратились в "чистые" - как во всех окнах и отчетах AVZ, так и в Исследовании системы! Я провел этот эксперимент с постоянно запущенным агентом программы Winamp (ему соответствует файл winampa.exe), который изначально не находился в "белом" списке AVZ. Я переименовал этот файл в _winampa.exe, в каталог программы Winamp (C:\Program Files\Winamp) переписал заведомо "чистый" файл Блокнота (notepad.exe), переименовал его в winampa.exe - и все! Процесс, инициированный winampa.exe, для AVZ тут же стал "чистым" (кстати, обратите внимание на графу Описание в Диспетчере процессов AVZ!):



Итак, делаем вывод #2: описанным выше способом в AVZ можно сделать "чистым" любой запущенный на выполнение файл - даже новый троян или вирус (и это совсем просто!), и этот троян/вирус не попадет в Исследование системы AVZ, а во всех ее отчетах будет выглядеть "чистым"! Понятно, однако, что если сигнатура такого файла заранее известна AVZ, и мы запустим сканирование файлов, то этот файл неминуемо будет обнаружен. А что, если сигнатура не будет известна?

Для демонстрации этой уязвимости я написал простое приложение, AVZWhiteListC (в архиве находятся исходный текст и загрузочный модуль), которое, будучи запущенным на выполнение, попадает в "белый" список процессов AVZ и, как следствие, отсутствует в отчете Исследования системы.

Учитывая вышеизложенное, можно сделать вывод #3: существующую в AVZ методику определения "чистых" процессов и соответствующих им файлов нужно менять, и чем скорее - тем лучше, т.к. в указанных выше обстоятельствах она не только не помогает, а даже наоборот - вводит в полное заблуждение! Более того, во время формирования базы "чистых" объектов имя объекта не учитывается, а при анализе же на "чистоту" AVZ ищет объект в файловой системе только по имени (плюс полный путь) - никакие другие признаки/атрибуты в расчет не берутся! Даже в этом факте налицо некоторое противоречие!

Что же нужно сделать? Казалось бы, простую вещь: при проверке процесса на "чистоту" проверять не файл на диске, соответствующий этому процессу, а его загруженный образ в памяти, учитывая при этом только те атрибуты, которые остаются неизменными при загрузке файла в память (ведь изначально база "чистых" формируется из файлов, а не из их образов в памяти!). Это, кстати, решило бы проблему и временных файлов-драйверов, а также прочих похожих объектов - ведь в памяти компьютера все эти объекты практически постоянно присутствуют! Да, казалось бы простую вещь... Но, конечно же, на деле совсем не простую: вполне вероятно, что эта "простая вещь" потребует пересмотра даже принципа формирования базы "чистых" объектов, не говоря уже о самой методике проверки!

Такие вот дела...

This page is powered by Blogger. Isn't yours?