Вирусы нового поколения

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

Этот способ основан на создании удаленного потока посредством вызова API-вызова CreateRemoteThread, которому в качестве стартового адреса передавался указатель на вредоносный код, записанный в адресное пространство программы тем или иным способом. Например, выделением памяти на куче с последующим копированием shell-кода API-вызовом WriteProcessMemory. Для обнаружения, достаточно взглянуть на стартовый адрес программы — у "нормальных" потоков он указывает в область страничного имиджа PE-файла, а у "рукотворных" — лежит в стеке, куче или еще где-нибудь.

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

Оказалась, что стартовый адрес формируется до инициации TLS/Dllmain, а после инициализации обращения к оригинальной точке входа, прописанной в PE-заголовке, уже не происходит — система использует адрес, сохраненный в стеке и этот адрес действительно может быть изменен. Антивирусы (не говоря уже о отладчиках) к такому действию разумеется не готовы и они просто теряют контроль над исполняемым файлом!

Технологию изменения точки входа, использованная в вирусах нового поколения, которая статическими антивирусными сканерами не обнаруживается в принципе! Как минимум, нужен полноценный эмулятор ЦП с качественным эмулятором окружения Windows, учитывающим недокументированные особенности системного загрузчика PE-файлов.

В ноября 2008 года, из всех существующих антивирусов вирус нового поколения могли обнаруживать только NOD32, F-Secure, Symantec, KAV, Dr.Web, и то, только после усовершенствования эмулятора окружения Windows. Остальные же ни как не реагируют.

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

В конце февраля 2009 года компания Endeavor Security, Inc работает над защитой AMP (Active Malware Protection), добавляя к ней перехаченный x86emu вместе с эмулятором окружения Windows, "осведомленным" о недокументированных возможностях системного загрузчика PE-файлов. Так что AMP имеет все шансы оказаться первым коммерческим продуктом, способным распознавать вирус нового поколения и не только распознавать, но и блокировать.

А проблема действительно очень большая и чем дальше, чем больше. Какое-то время антивирусы не смогут обнаруживать вирус, изменяющую точку входа в PE-файл, и для борьбы с вирусом придется сражаться с ней вручную, а для этого нужно не только уверенно пользоваться различными отладчиками (например, DIA-pro) и hex-редакторами, но и разбираться в недокументированных тонкостях работы системного загрузчика.

Спецификация на PE-файл от Microsoft описывает специальное поле в PE-заголовке, хранящее относительный виртуальный адрес (RVA) точки входа в файл, с которого как бы и начинается его выполнение. "Как бы" потому что точка входа (она же Entry Point) выполняется не первой, а последней. До передачи управления на Entry Point система загружает все статически прилинкованные динамические библиотеки, вызывая функции Dllmain, исполняющиеся в контексте загрузившего их процесса и способные воздействовать на него любым образом. TLS-callback'и так же получают управление до выполнение точки входа, которой вообще-то может и не быть. В самом деле! Если Dllmain или TLS-callback не возвратит управление, точку входа вызывать уже будет некому и потому она может указывать на любой код.

Отладчики, антивирусы и другие программы, работающие с анализом исполняемых файлов ставят точку остановки на Entry Point, в надежде, что он сработает. Но он не сработает, если адрес точки входа изменен. Когда отладчик порождает отладочный процесс и запускает его на выполнение, то первым срабатывает бряк, засунутый системой в функцию NTDLL!DbgBreakPoint, сигнализирующую о том, что отлаживаемый файл спроецирован в адресное пространство и с ним можно работать как со своим собственным. В частности, считывать PE-заголовок и устанавливать точку остановки на точку останова. Дело в том, что операционная система никак не информирует отладчик о передаче управления на точку входа и отслеживать этот процесс отладчик должен самостоятельно.

Некоторые вирусы используют довольно хитрый трюк, совершая прыжок из TLS-callback'а, т.е. фактически выполнения TLS-callback без возврата управления, в результате чего оригинальная точка останова не вызывается и может содержать что угодно. Конечно, в разумных пределах. Наглеть не стоит. В частности, начиная с XP системный загрузчик выполняет ряд проверок и файлы с точкой останова вылетающей за пределы страничного образа просто не загружаются в память!

На самом деле, антивирус, эмулирующий TLS (а проэмулировать его несложно, благо он уже давно документирован) определит эту комбинацию, хотя на практике подавляющее большинство антивирусов либо вообще не знают о существовании TLS, либо эмулируют их некорректно.

Вирусы нового поколения в TLS-callback добавляет какое-то значение к некоторой ячейке памяти, лежащей в области стека и возвращает управление системе. Человек-с-отладчиком чисто теоретически может проверить тысячи машинных инструкций, ответственных за инициализацию файла, дожидаясь момента передачи управления на точку входа или хотя бы область памяти не принадлежащую системе, а находящуюся в границах PE-файла или одной из принадлежащих ему динамических библиотек. Тогда можно будет обнаружить, что точка входа каким-то магическим образом не получает управления! Антивирусам приходится еще хуже. Они не могут трассировать код, исполняющийся на живой операционной системе.

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

Точка входа представляет собой аргумент API-функции CreateRemoteThread(), имеющей документированный прототип. Причем, этот аргумент попадает на стек до отработки Dllmain/TLS-callback, а извлекается из стека после того, как они возвратят управление. Причем, никакие проверки валидности стартового адреса потока не выполняются, а это значит, что Dllmain/TLS-callback могут изменять стартовый адрес потока по своему усмотрению.

Антивирусы, притендующие на роль "лекарства" вот вирусов нового поколения

Участники рынка антивирусов испытывают серьезные проблемы с поиском образцов свежей малвари. Наглядный тому пример — Rustock.C. Когда одни компании уже выпустили лекарство, другие— лихорадочно пытались заполучить хотя бы один рабочий образец. По данным компаний, владеющих распределенными сенсорными сетями, эпидемия завершилае еще до выпуска лекарства в свет (по другим данным — спустя несколько дней после его выхода).

IDS и IPS

Новое время требует новых решений. Лучшими для борьбы с червями стали системы обнаружения вторжений, они же Intruder Detection System или, сокращенно, IDS. В отличие от антивирусов и pro-активных механизмов, работающих с файлами и хучащих операционную систему, так что она постоянно засоряет систему. IDS работает с аппаратной частью, прогоняя через себя весь входящий/исходящий сетевой трафик, и через специальную базу «правил» (фактически, тех же самых сигнатур) ловит подозрительные пакеты или детектит специфичную сетевую активность.

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