av-shield

армирование антивирусов и брандмауэров

крис касперски, ака мыщъх, a.k.a. nezumi, a.k.a. souriz, a.k.a. elraton, no-email

очень часто антивирусы и брандмауэры превращаются из охотника в жертву. в борьбе с активной малварью еще и не такое случается. и хотя разработчики всячески пытаются защититься от посягательств со стороны зловредного кода, воздвигая целый комплекс средств противовоздушной обороны, при схватке с грамотно спроектированным зловредным кодом они обречены на поражение. как усилить защиту уже существующих антивирусов/брандмауэров, не вмешиваясь в их машинный код и не ковыряя исходные тексты, которых у нас все равно нет? как заковать антивирус/брандмауэр в надежную броню, способную противостоять активной малвари? мыщъх знает. и сейчас расскажет. не волнуйтесь, владения ассемблером для этого не потребуется — статья ориентирована на простых пользователей

Мужская часть населения еще помнит те время, когда антивирус (вместе со всеми базами и самой MS-DOS) умещался на одной «стерильной» дискетке с защитой от записи откуда его настоятельно рекомендовалось запускать. Проверка на «живой» машине (то есть запуск антивируса из-под зараженной операционной системы) часто приводил к ложным негативным срабатываниям, то есть антивирус не находил даже известные ему вирусы, а все потому, что зловредный код слишком хорошо знал антивирус и модифицировал его код, отвечающий за распознавание заразы.

Современные антивирусы на дискету уже не влезают и вынуждены сражаться с _активной_ малварью в арсенале которой помимо многочисленных маскировочных методов имеется и оружие возмездия. Аналогичным образом дела обстоят и с персональными брандмауэрами. Их тяжело пробить снаружи (то есть с удаленной машины), но легко отключить локально, внедрившись в адресное пространство брандмауэра или «проигравшись» с элементами управления путем эмуляции клавиатурного/мышиного ввода (атаки типа WM_).

Конечно, разработчики всячески защищаются от нападок со стороны вредоносного кода (например, путем проверки целостности собственного тела), однако, у них это не очень хорошо получается и создается впечатление, что они в первую очередь озабочены качеством детекции и количеством распознаваемых вирусов, то есть предпочитают нападать, а не обороняться. Вот только вырвавшись вперед они рискуют оказаться в плотном кольце окружения. «Независимые» обзоры так же не придают факту защиты никакого внимания, тестируя антивирусы/брандмауэры в лабораторных условиях.

Проактивные технологии, проверяющие все открываемые файлы на лету, действительно, имеют хорошие шансы остановить распространение заразы, поскольку, малварь уничтожается еще до того, как получит управление. А вот автономные сканеры, запускаемые раз в несколько дней (а то и недель) намного более уязвимы и, как показывает практика, очень плохо справляются с поиском root-kit'ов. А если вспоминать, что зловредный код часто распространяется через дыры безопасности (антивирусами неконтролируемые), их судьба становится совсем незавидной.

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

Рисунок 1 Sygate Personal Firewall – существо нежное, беззащитное, неспособное постоять за себя

Как работает малварь? Какие приемы используются для «ослепления» защитных механизмов? Возможных способов очень много и каждый день появляются все новые и новые. Чтобы навести в этом хаосе хотя бы какое-то подобие порядка, необходимо классифицировать основные методы, а так же их производные. Тогда станет понятно от кого и как нам обороняться.

Порядка ~80% зловредных программ открывают процесс-жертву API-функцией OpenProcess, получая (в случае успешного завершения операции) дескриптор процесса, передаваемый API-функции ReadProcessMemory, читающий содержимое памяти процесса-жертвы и копирующей его во внутренний буфер малвари, которая путем сигнатурного поиска пытается отловить все известные ей защитные программы (список активных процессов можно получить средствами TOOLHELP32). Если такая программа действительно найдена, малварь смотрит в свою базу сигнатур, извлекая смещение машинных команд, которые надлежит нейтрализовать, что осуществляется путем перезаписи памяти жертвы API-функцией WriteProcessMemory. В большинстве случаев достаточно заменить пару условных переходов, навсегда отучив антивирус/брандмауэр ругаться грязными словами.

Рисунок 2 API-функция ReadProcessMemory на MSDN

В более сложных случаях, малварь «впрыскивает» внутрь защитной программы свой код, ведущий партизанскую войну с защитным механизмом с учетом конкретных ситуаций, что намного более предпочтительно, поскольку новые версии антивирусов/брандмауэров выходят достаточно часто и создателю малвари приходится постоянно обновлять базу сигнатур, С закрытых позицией (т. е. из соседнего процесса) нанести прицельный удар не так-то просто! Ошибка в один единственный байт может стоить защите зависания, что не есть хорошо. Напротив, оказавшись внутри антивируса/брандмауэра, хакерский код без проблем обезвредит все «детонаторы» вполне универсальным путем, например, установит еще один перехватчик открываемых файлов поверх установленного антивирусом, а перед передачей управления последнему — вычистит из проверяемого файла все следы своего присутствия (естественно, «вычистит» только в памяти).

Внедрение в посторонние процессы осуществляется различными путями. Классический способ (работающий только в NT-подобных системах) — создать удаленный поток вызовом API-функции CreateRemoteThread или NativeAPI-функции NtCreateThread, однако перед этим необходимо забросить зловредный код внутрь атакуемого процесса. И тут хакеру на помощь приходят API-функции:AllocateVirtualMemory(для выделения блока памяти) или QueryVirtualMemory (для поиска уже выделенного блока, пригодного для внедрения) с последующим вызовом WriteProcessMemory.

Внедрение в стиле «модерн» апеллирует к манипуляциям с процессорным контекстом. Новые потоки при этом не создаются. Внутрь процесса-жертвы записывается зловредный код (и тут без WriteProcessMemory никак не обойтись!), а затем API-функциями GetThreadContext/SetThreadContext регистр-указатель команд перемещается на начало зловредного кода, длина которого обычно составляет несколько десятков байт — вполне достаточно чтобы загрузить свою динамическую библиотеку или «отрыть портал». Но это — уже детали реализации.

Некоторые, между прочим, достаточно многие, антивирусы/брандмауэры перехватывают вызовы WriteProcessMemory/SetThreadContext и поднимают тревогу, если запись происходит в секцию кода, однако, во-вторых, этот перехват достаточно легко обойти (например, вызывать API-функции не с первого байта, эмулируя выполнение пропущенных команд, или же внедряться в область данных, правда, при активном аппаратном DEP попытка внедрения в область данных ведет к исключению, завершающему работу атакуемого приложения в аварийном режиме).

Обойти контроль за SetThreadContext можно путем подключения псевдо-отладчика (созданного малварью) к процессу-жертве API-функцией DebugActiveProcess, за которой не следит ни один известный мне защитный механизм и хакер может преспокойно получать контекст потока в свое распоряжение через генерацию отладочных событий. И такой способ внедрения в антивирусы/брандмауэры встречается все чаще и чаще.

Примерно ~10% зловредных программ лезут в следующую ветку системного реестра HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs, добавляя туда свою динамическую библиотеку, которую операционная система будет проецировать на адресное пространство всех GUI-приложений, передавая ей бразды правления до их запуска. Практически все современные защитные комплексы следят за AppInit_DLLs и начинают жутко матерится, если там обнаружится новая DLL, однакоесли малварь хакнула AppInit_DLLs _до_ запуска антивируса/брандмауэра им остается только утереться, поскольку кто первый получает управление, тот царь и король.

Еще ~10% зловредных программ борются с защитами через оконный интерфейс. Что может быть проще! Находим окно по его заголовку (API-функции FindWindow или EnumWindows), добираемся до элементов интерфейсного управления и начинаем хачить их по своему усмотрению. Зловредный код может подавить появление нежелательных окон (например, сделав их невидимыми — API-функция ShowWindow), найти кнопку с надписью «yes» и «надавить» на нее путем посылки соответствующих Windows-сообщений. Или же заблокировать все кнопки (API-функция WindowDisable). Наконец, можно забраться в настройки и отключить защиту, а чтобы пользователь ничего не заметил — каждый раз подсовывать ему поддельный экран. И это не фантастика! Такие вирусы уже есть, причем в количестве намного больше одного, а написать их может даже школьник, едва осиливший DELPHI и пролиставший по диагонали SDK.

Рисунок 3 файл \WINNT\System32\Drivers\ect\hosts после набега малвари — заблокированы практически все web-адреса антивирусных компаний

Другой излюбленный объект атаки — файл \WINNT\System32\Drivers\etc\hosts, позволяющий сопоставлять IP-адреса с доменными именами и имеющий приоритет над DNS-сервером. То есть, если малварь не хочет, чтобы антивирус обновлялся, она просто добавляет в hosts-файл одну строчку, перенаправляя запросы к серверу обновлений куда-нибудь еще, например, на локальный узел жертвы (которому соответствует адрес 127.0.0.1) или, что еще хуже, на сервер самого создателя малвари, распространяющий вредоносные обновления, содержащие не только сигнатуры, но и машинный код. И хотя антивирусные базы в большинстве своем защищены цифровыми подписями и другими криптографическими средствами, при большом желании со стороны хакера их можно обойти.

Вот такая мрачная перспектива вырисовывается. Хакерские технологии не стоят на месте, а разработчики защитных комплексов больше думают о маркетинге и поддержке новых операционных систем, благо Microsoft постоянно преподносит сюрпризы, вынуждая переписывать тысячи строк отлаженного кода для сохранения совместимости. В общем, тут не до защиты…

Малварь нужно бить еще на излете. Самое простое, что можно только сделать — это упаковать антивирус/брандмауэр достойным протектором, препятствующим сигнатурному поиску и внедрению в охраняемый процесс постороннего кода. Крутых протекторов сейчас как никогда много, взять, например туже Themid'у (в просторечии называемую Фемидой). На официальном сайте — http://www.oreans.com — лежит только демонстрационная версия (а что делать?! это просто время такое — кушать каждый хочет), однако хакнутые версии Фемиды без труда можно найти в сети.

Рисунок 4 Фемида на страже порядке

Чем хороша Фемида? А тем, что перехватывает и блокирует следующие API-функции: NtAllocateVirtualMemory, NtCreateThread, NtQueryVirtualMemory, NtReadVirtualMemory, ZwTerminateProcess, NtWriteVirtualMemory (кажется, я ничего не упустил?! вот черт — не помню!). Префикс «Nt» означает, что мы имеем дело с NativeAPI-функциями, самыми низкоуровневыми системными функциями, доступными на прикладном уровне, что одним махом срубает до ~80% всей малвари (конечно, если малварь работает на уровне ядра, то это дело другое, но и в этом случае ей придется изрядно напрячься, поскольку, тело упакованного файла зашифровано и расшифровывается динамически по ходу его исполнения, тут же зашифровываясь вновь).

Без функции NtReadVirtualMemory малварь обломается с чтением содержимого защищенного процесса, а, значит, не сможет отличить антивирус/брандмауэр от остальных программ. Запрет на создание удаленных потоков NariveAPI-функцией NtCreateThread не позволит внедриться в адресное пространство жертвы, тем более, что NtWriteVirtualMemory все равно не работает. Ну, и как бедной малвари предполагается копировать зловредный код?!

Аналогичным образом обстоят дела и с другими атаками. Обработанный Фемидой файл _практически_ неуязвим, зачастую, настолько неуязвим, что порой вообще неработоспособен. Фемида — не самый корректный упаковщик и простейший контроль целостности, выполняемый антивирусом/брандмауэром тут же показывает, что с файлом что-то не то. Как следствие — антивирус/брандмауэр выдает предупреждающее сообщение на экран или вообще отказывается работать. В такой ситуации нам остается либо брать в лапы hiew и вырезать из антивируса/брандмауэра систему самоконтроля, которая нам только мешает, либо же проигравшись с настройками протектора выбрать компромиссный вариант, который и от малвари защищает и ругательств со стороны защиты не вызывает.

av-shield_image_4.jpg

Рисунок 5 ручной анализ кода антивируса, препятствующего его работе под Фемидой

Если примирить защиту с протектором никак не получается, имеет смысл обратиться за помощью к отладчику, например, к бесплатно распространяемому OllyDdb (www.ollydbg.de). Просто загружаем защищаемую программу в Ольку (или прицепляется к уже запущенному процессу: File  Attach) и нажимаем <F9> (Run) для нормального продолжения выполнения программы без трассировки.

Что это дает? Во-первых, поскольку отладка в Windows нереентерабельна, то процесс, находящийся под «покровительством» Ольки не может отлаживать никто другой и попытки малвари зацепиться за него ни к чему не приведут. Так же Олька позволяет отслеживать появление новых потоков (как локальных, так и удаленных). Достаточно в меню Options  Debugging Options взвести галочку «Break on new thread» во вкладке «Event». Тогда отладчик будет останавливаться всякий раз при создании нового потока. И хотя антивирусы/брандмауэры активно создают свои собственные потоки в целях производственной необходимости (что очень аноит), все-таки такая защита лучше, чем совсем никакой.

А если еще взвести и галочку «Break on new module (DLL)», то отладчик будет останавливаться при загрузке всякой динамической библиотеки. И хотя, опять-таки, антивирусы/брандмауэры могут подгружать библиотеки по ходу дела, обычно это происходит в строго определенных ситуациях при совершении пользователем тем или иных действий. Беспричинная загрузка DLL с вероятностью близкой к единице свидетельствует об атаке!!!

Наконец, высший пилотаж — защита кодовых секций от внедрения. Работает только на процессорах с поддержкой битов NX/XD (то есть, достаточно современных процессорах) и с XP SP2 с задействованным аппаратным DEP для всех приложений (по умолчанию, DEP распространяется только на системные компоненты).

Рисунок 6 защита кодовой секции от чтения с помощью OllyDebugger

В отладчике нажимаем <ALT-M>, чтобы увидеть карту адресного пространства. Находим там модуль, имя которого совпадает с именем антивирусного процесса, видим секцию «.text» (реже «CODE»), щелкаем правой клавишей мыши, в контекстом меню выбираем пункт Set Access  Execute и все! С этого момента любая попытка чтения секции кода приведет к исключению, отлавливаемому отладчиком и блокирующим атаку. Напоминаю, что этот трюк действует _только_ при соответствующей поддержке со стороны операционной системы и процессора (за подробностями отсылаю к своей статье: http://nezumi.org.ru/zq-nx.uncensored.zip, где все это описано). Правда, если антивирус/брандмауэр попытается подсчитать контрольную сумму кодовой секции для проверки собственной целостности, то его встретит жестокий облом. Впрочем, мы можем нажать <F9> для продолжения выполнения кода или на время снять запрет на чтение кодовой секции, только это все равно не спасет от малвари, модифицирующей стек или секцию данных, но, к счастью, умной малвари в живой природе практически не встречается и все больше приходится бороться со студенческими подделками.

Другая возможная проблема — антивирус/брандмауэр может не захотеть запускаться из-под отладчика, например, потому, что доверху нашпигован различными анти-отладочными приемами. Ну и что нам делать?!

Хорошая идея — запустить антивирус/брандмауэр от имени администратора, а самим работать в пользовательской сессии. Тогда малварь, обладающая пользовательскими правами, просто не сможет открыть процесс защищенного приложения. Запуск программ от имени другого пользователя (в данном случае — администратора) осуществляется штатной командой runas с ключами /profile и /env, копирующими профиль и среду текущего пользователя. Без этих ключей антивирус/брандмауэр, не найдя своих настроек может просто не запустится!!!

Запуск приложений от имени администратора — достаточно надежное средство защиты от посягательств на адресное пространство защищаемого процесса со стороны малвари, но! Эмуляция клавиатурного/мышиного ввода продолжает работать, что не есть хорошо. Как этому противостоять?! Увы, ответ обескураживающий. Даже со всеми нововведениями Вислы — никак. Единственная зацепка — заголовок окна. Большинство зловредных программ именно так и «палят» антивирусы/брандмауэры. Ну, изменить заголовок — не проблема. Это умеет делать любой продвинутый твикер, например, добрый-старый Customozer. Он же умеет двигать элементы управления (например, кнопки), изменяя их размеры. Зачем это нужно?! А затем, что более продвинутая малварь, смотрит не на заголовок главного окна, а сечет раскладку дочериных элементов управления, поскольку, положение и размеры элементов управления уникальны для каждого приложения и их (в целях маскировки) рекомендуется слегка изменять. Customizer (как и большинство других твикеров подобного типа) позволяют сохранять профили изменений, автоматически восстанавливая их при каждом запуске, освобождая нас от необходимости долбать эту рутинную работу вновь и вновь.

Рисунок 7 Customizer за работой

Следуя обозначенным рецептам защиты, мы намного увеличим безопасность своего компьютера, нанося малвари сокрушающий ответный удар. Ах да, чуть не забыл. Следите так же за файлом \WINNT\System32\Drivers\etc\hosts — удаляя посторонние записи. В принципе, ничего не мешает грохнуть и сам файл hosts, поскольку, очень мало пользователей используют его по назначению. А как его можно использовать?! Да просто охренеть как можно его использовать! Например, создавать короткие алиасы длинным доменным именам или переделывать доменные имена под свой вкус.

Возьмем www.microsoft.com. С помощью утилиты ping определим ее IP-адрес (равный в данном случае 207.46.19.254, однако, следует учитывать, что с одним доменным именем может быть связано множество IP-адресов, выбираемых в зависимости от географии или загрузки каналов, но это уже детали). Открываем hosts-файл в любом текстовом редакторе (внимание! требуются права администратора!) и пишем 207.46.19.254, а напротив, через пробел — www.ms.com или, нет, www.necrosoft.com. Сохраняем файл и набираем www.necosoft.com в любом браузере. Далее смотрим результат. (Перезагрузка не требуется). Короче, будет чем удивить друзей. Кстати, сохранять иерархию доменных имен совершенно необязательно. «must-die» (без всяких www и com) работает ничуть не хуже, а вот удивление у неподготовленных пользователей вызывает просто огромное. Естественно, влияние hosts-файла сугубо локальное и на соседние компьютеры не распространяется (разве что незаметно скопировать его на машину подруги и тогда вместо ее любимого love.mail.ru откроется, ну… например… сайт венерологической клиники). Но это все шуточки, ладно, не будем уходить в оффтопик.

Рисунок 8 империя зла переехала на адрес www.necrosoft.com

В мире нет и не может быть защиты, которую нельзя обойти. Поместив антивирус/брандмауэр в бронежилет, мы всего лишь уменьшаем вероятность прямых попаданий, отсекая большое количество «шрапнели», пущенной пионерами. Приемы, предлагаемые мыщъх'ем, не претендуют ни на универсальность, ни на полноту, однако с учетом того, что они не требуют никакой квалификации и доступны каждому пользователю для немедленной реализации… плюс многолетний опыт эксплуатации на мыщъхиных знакомых и знакомых знакомых… Все это убеждает в том, что защищаться от малвари — можно и нужно!

ASCII

Рисунок 9 пират компьютерных сетей