Автор: (c)Крис Касперски ака мыщъх
Брандмауэры (они же firewall'ы) сейчас используются повсеместно. Их встраивают в DSL-модемы, Wi-Fi точки доступа, маршрутизаторы, операционные системы, антивирусы и другие программные пакеты типа SyGate Personal Firewall или Outpost. Но так ли они надежны, как утверждает реклама?

Введение

Прежде чем начать, необходимо выяснить, что такое персональные брандмауэры и чем они отличаются от не-персональных (за отсутствием подходящей терминологии назовем их "внешними"). Внешний брандмауэр представляет собой штуку, включенную в разрыв между сетевым кабелем (Ethernet/Wi-Fi/Dial-Up) и сетевой картой охраняемого узла (неважно - сервером или клиентской машиной). Конструктивно внешний брандмауэр может быть реализован и как микросхема, встроенная в DSL-модем/материнскую плату, и как самостоятельный узел - маршрутизатор/мост, построенный на базе IBM PC и управляемый любой подходящей операционной системой (например, Linux, хотя и Windows на худой конец сгодится тоже).

Возможности воздействия на внешний брандмауэр минимальны. Если он сконфигурирован правильно и не имеет дыр, то проникнуть на атакуемую машину извне сети очень трудно. А вот вырваться из-за внешнего брандмауэра на свободу ничего не стоит, поскольку он ничего не знает ни о процессах, ни о потоках. Ему неведомо понятие "зловредной программы". Все, что он имеет в своем распоряжении - это список открытых портов, среди которых в обязательном порядке присутствует 80-й порт, связанный с Web. Следовательно, любое приложение может беспрепятственно устанавливать соединения с любыми IP-адресами по 80-му порту, скрытно пересылая конфиденциальную информацию или устанавливая back-door, и брандмауэр ничего не сможет с этим сделать (особенно если зловредная программа "обернет" пересылаемые данные в HTTP-запросы), поскольку он не в состоянии отличить, кто посылает TCP/IP пакеты: FireFox.exe или evil-virus.exe!

Персональные брандмауэры устанавливаются непосредственно на защищаемый ими компьютер, поэтому не только поддерживают списки "доверенных приложений", но также пытаются отслеживать факт внедрения в них постороннего кода, чтобы малварь не смогла передать информацию "руками" FireFox'а или IE. Все это, конечно, очень замечательно, но(!) тот факт, что персональный брандмауэр находится на той же самой машине, что и малварь, делает его чрезвычайно уязвимым против атак на сам брандмауэр. Малварь, заполучившая администраторские права, может делать абсолютно все, что угодно, в том числе и обмениваться пакетами в обход брандмауэра!

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

Из внешней сети во внутреннюю через брандмауэр

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

Вообразим себе домашнюю (или корпоративную) сеть с приватными ресурсами (ведь это очень утомительно каждый раз вводить пароль при доступе к файловому хранилищу, реализованному через Microsoft Shared или FTP) или такой прозаичной вещью как HTTP-Proxy сервер. Чтобы не покупать для каждой машины свой IP (с IP-адресами сейчас проблема), администратор назначает всем машинам внутрисетевые IP. Реальный IP получает только одна машина, на ней же устанавливается Proxy-сервер, через который ходят все остальные. "Все" в данном случае следует понимать буквально. Любой хакер, обнаруживший путем сканирования работающий Proxy, может использовать его в своих целях. А за трафик будет платить владелец атакованной машины. Оно ему надо? Вот тут-то брандмауэр и выручает, закрывая Proxy-порт для всех нелокальных узлов (ну, при желании можно добавить несколько адресов удаленных партнерских фирм). То же самое и с FTP. Внутри сети с ним можно общаться беспрепятственно, но вот все внешние подключения будут безжалостно отсечены брандмауэром!

Отсюда - если у вас нет ни Proxy, ни FTP, и вы не используете разделяемые ресурсы, не защищенные паролем - нахрена вам вообще нужен брандмауэр?! Разве, что почувствовать себя крутым и продвинутым парнем. А то уже некоторые без брандмауэра в сеть вообще выходить боятся. Другой вопрос, что коварная Windows (в отличие от демократично настроенной Linux) открывает для своих нужд кучу нафиг никому не нужных портов, которые не так-то просто отключить и которые содержат уязвимости. Достаточно вспомнить червя MSBlast, распространяющегося через дыру в сервисе DCOM, висящем на 135-м порту и реально полезным только в корпоративных сетях, разделенных на домены.

Вот, к примеру, список портов, открытых на моем компьютере (см. рис. ниже). Для того, чтобы узнать - какие порты открыты, достаточно вызвать штатную утилиту netstat.exe, передав ей в командной строке ключ "-a".

http://www.insidepro.com/kk/293/293_3.jpg

Список портов, открытых на мыщъх'ином компьютере.

Бесплатная утилита TCPView от Марка Руссиновича (http://www.sysinternals.com/Utilities/TcpView.html), кстати говоря, распространяемая в исходных текстах(!), покажет намного больше информации (в частности, сообщит - какой процесс использует тот или иной порт) и поможет закрыть любое соединение, кроме, к сожалению, системных (см. рис. ниже) и такие порты приходится закрывать уже на брандмауэре или... постоянно устанавливать свежие заплатки, латая систему путем затыкания дыр (но это не лучшее решение, поскольку о многих дырах Microsoft узнает в последнюю очередь).

http://www.insidepro.com/kk/293/293_4.jpg

TCPView не может закрыть системное соединение.

Для более детального анализа трафика можно использовать sniffer (который встроен практически в каждый профессиональный брандмауэр) или утилиту TDIMon все от того же Марка Руссиновича (http://www.sysinternals.com/Utilities/TdiMon.html), которая покажет трафик, проходящий через TDI-драйвер - один из наиболее низкоуровневых сетевых драйверов (см. рис. ниже).
http://www.insidepro.com/kk/293/293_5.jpg

Внешний вид утилиты TDIMon.

Но все-таки! Как насчет ответа на поставленный ранее вопрос?! Можно ли проникнуть сквозь закрытый порт или нет? Ну... что тут сказать? Брандмауэры первых поколений обходились только так. Достаточно было послать сильно фрагментированный TCP-пакет, настолько фрагментированный, что целевой порт не попадал в первый IP-пакет, а поскольку функцией сборки IP-пакетов брандмауэр по ряду причин не оснащен, он свободно пропускал эту "бомбу". Но это в основном относится к внешним брандмауэрам. А персональные работают сразу на многих уровнях, в том числе контролируя пакеты, уже собранные драйвером TCPIP.SYS и с ними этот фокус уже не проходит. Хуже того! Они могут забить тревогу, поскольку в реальной жизни такие фрагментированные пакеты практически никогда не встречаются!!!

Но даже если брандмауэр пропустит такой пакет, то это не сильно поможет атакующему, поскольку все современные сервера (FTP, Proxy) давным-давно научились различать интерфейсы сетевых соединений, автоматически отсекая нежелательные подключения. Взять хотя бы установленный у меня Etlin HTTP Proxy Server, связывающий машины моей локальной сети с внешним миром. Чтобы не закрывать порт на брандмауэре и не назначать на доступ к Proxy пароль (его поддерживают не все программы), мыщъх поступил проще, разрешив Proxy принимать подключения только с одного интерфейса - интерфейса локальной сети (см. рис. ниже). То же самое относится и к внутреннему FTP-серверу.

http://www.insidepro.com/kk/293/293_6.jpg

HTTP Proxy Server принимает подключения только с одного интерфейса - интерфейса локальной сети.

Выходит, что даже если атакуемый порт открыт на брандмауэре (или брандмауэр удалось пробить каким-нибудь стенобитным орудием), вовсе не факт, что атака возымеет успех!

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

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

В-третьих, можно заманить жертву на специальным образом сконструированную Web-страничку, эксплуатирующую ту или иную уязвимость в IE. Или не обязательно уязвимость! Редкий пользователь знает про уровни безопасности. На странички, открываемые из сети, действуют весьма драконические ограничения и Java-скрипты отдыхают. Но вот при последующем открытии той же самой странички, сохраненной на диск, ситуация меняется до чрезвычайности! Так что проникнуть в локальную сеть для опытного хакера не составит никакого труда!

Наконец, всеми "горячо любимая" операционная система Windows содержит столько дыр, что может быть легко атакована с приобретением привилегий SYSTEM, с которыми отключить брандмауэр не составит никакого труда!!!

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

Из внутренней сети во внешнюю через брандмауэр

Что касается проникновения во внешнюю сеть, огражденную недемократически настроенным внешним брандмауэром, то мыщъх уже писал об этом в статье "Побег через брандмаузер плюс терминализация всей NT", так чего же здесь повторяться?! Напомню только, что мыщъх'ый сервер работает не все время, а только тогда, когда мыщъх активно вращает хвостом, то есть не спит (сейчас это где-то между 21:00 и 12:00 по Москве со сдвигами в ту или иную сторону).

Что же касается персональных брандмауэров, то вырваться из-под их гнета значительно сложнее. Большинство публикаций на эту тему предполагает, что атакующая программа имеет администраторские привилегии, с помощью которых она может спуститься на нулевое кольцо термоядерного уровня и дезактивировать все датчики брандмауэра с той же осторожностью, с какой сапер разминирует бомбу. Очень хорошая статья "Обход Outpost Firewall 3.x и 4.0 в Kernel mode" лежит на http://www.wasm.ru/article.php?article=outpostk. Она подробно описывает методику перехвата и фильтрации пакетов, используемую персональными брандмауэрами, а поэтому справедлива не только для одного лишь Outpost'а, но также и для других продуктов.

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

Начнем с того, что большинство брандмауэров не отслеживают локальные подключения по петле 127.x.x.x, поскольку такие пакеты идут совсем по другому маршруту. Поэтому если на компьютере установлен какой-нибудь сервер, хакер может напрямую подключаться к нему. Брандмауэр и знать ничего не будет. Если, конечно, сам сервер включает 127.x.x.x в список доступных интерфейсов. А если не включает?! Хорошо, тогда передаем атакующую программу на соседнюю локальную машину (локальный трафик, как правило, не запрещается брандмауэром - во всяком случае, пересылка файлов в большинстве случаев все-таки возможна) Ну а дальше атакующей программе остается всего лишь связаться с сервером по разрешенному интерфейсу локальной сети, если, конечно, локальная сеть вообще есть.

Очень многие ставят персональный брандмауэр на одиночный компьютер только затем, чтобы следить за активностью приложений, ломящихся в сеть. И если вдруг наша хакерская программа (не являющаяся ни IE, ни FireFox'ом) вдруг постучится в 80-й порт, брандмауэр тут же поднимет тревогу. Как, мол, это так? Многие хакеры пытаются внедриться в адресное пространство доверенных приложений (того же FireFox, например) посредством API-функций CreateRemoreThread()/WriteProcessMemory(), но брандмауэры за этим зорко следят и начинают жутко верещать - "Держите вора!". Модификация файла на диске также не дает ожидаемых результатов, поскольку брандмауэр проверяет (может проверять) контрольную сумму при его запуске. Правда, тут есть одна небольшая лазейка. Известна ветка реестра AppInit_DLLs - все DLL, перечисленные в ней, проецируются на адресные пространства каждого запускаемого процесса со всеми вытекающими отсюда последствиями. Однако все больше и больше брандмауэров начинает контролировать AppInit_DLLs, сообщая о появлении в ней новых элементов, а то и вовсе автоматически удаляет их, так что этот прием уже уходит в небытие.

А вот что по-прежнему остается актуальным - так это изменение настроек браузера, которые хранятся в совершенно бесхозном и никем неохраняемом виде. Взять хотя бы FireFox. Адрес Proxy-сервера хранится в файле \Documents and Settings\kris kaspersky\Application\ Data\Mozilla\Firefox\Profiles\4uszwife.default\prefs.js в строке "user_pref("network.proxy.http", "80.75.2.146");", которую никакой брандмауэр не проверяет. Если подставить сюда адрес нашего узла (естественно, для этого необходимо иметь статический IP или динамический IP, повешенный на динамический же DNS), мы сможем грабить весь трафик или даже подсовывать жертве левый контент (см. рис. ниже), а брандмауэр даже и не пикнет!

http://www.insidepro.com/kk/293/293_8.jpg

Изменение настроек FireFox в обход брандмауэра.

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

http://www.insidepro.com/kk/293/293_9.jpg
Типичная реакция персонального брандмауэра на неудачную атаку.

А вот тогда мы используем старый, как дуб, но все еще работающий трюк с эмуляцией клавиатурного/мышиного ввода. Попросту говоря, отследим появление окна брандмауэра с надписью "SyGate Personal Firewall" (что можно сделать с помощью API-функции FindWindow), перечисляем дочерние элементы управления через EnumWindows и... жмем на кнопку "yes" прежде, чем юзер успеет сообразить - что там промелькнуло на экране?

Естественно, каждый брандмауэр требует своего подхода, но поскольку их существует не так уж и много, нам будет легко написать программу, поддерживающую их все. Ключевой фрагмент, ответственный за нажатие, выглядит так:

Код:
// ПЕРЕЧИСЛЕНИЕ ДОЧЕРНИХ ОКОН БРАНДМАУЭРА
// =======================================
// получаем хэндлы всех интересующих нас окон
// (порядок окон определяем либо экспериментально,
// либо прогоном с отладочным выводом информации по каждому окну)
HWND CALLBACK EnumChildWindowsProc(HWND hwnd, LPARAM lParam)
{
        static int N = 0;

        switch (++N)
        {
                case 3: // галочка "remember"
                                remember = hwnd;
                                break;

                case 4: // кнопка "no"
                                no = hwnd;
                                break;

                case 5: // кнопка "detail"
                                detail = hwnd;
                                break;

                case 6: // кнопка "yes"
                                yes = hwnd;
                                return yes;

        } return 0;
}

// имитация нажатия на кнопку 'yes'
// ===============================
foo(HWND hWnd)
{
        SendMessage(hWnd, WM_SETFOCUS, 1, 0);
        SendMessage(hWnd, BM_SETSTATE, 1, 0);
        PostMessage(hWnd, WM_KILLFOCUS, 0, 0);
}

Ключевой фрагмент, имитирующий нажатие на кнопку "Yes".

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

Большая ошибка начинающих хакеров состоит в том, что они ограничиваются всего лишь одной посылкой сообщения BM_SETSTATE, а как показывает практика - для элемента управления типа "кнопка" этого явно недостаточно и такое сообщение еще не приводит к ее нажатию. Почему? Ошибка кроется в том, что для корректной эмуляции ввода мы, во-первых, должны установить фокус (сообщение WM_SETFOCUS), а после перевода кнопки в состояние "нажато" (сообщение BM_SETSTATE) этот фокус убить (сообщение WM_KILLFOCUS), ведь как известно даже желторотым пользователям, кнопки срабатывают не в момент их нажатия, а в момент отпускания. Не верите? Поэкспериментируйте с любым приложениям и убедитесь в справедливости сказанного.

Кстати, забавный трюк: если под NT/W2K в сообщение WM_KILLFOCUS передать недействительный дескриптор окна, получающего на себя бразды правления, то операционная система по понятным соображениям не передаст фокус несуществующему окну, но у активного окна фокус все-таки отберет. Windows 9x, напротив, оставляет фокус активного окна неизменным! Вот такая разница между двумя операционными системами. Еще одна деталь напоследок. Если в роли убийцы фокуса выступает функция API SendMessage, то поток, эмулирующий ввод, блокируется вплоть до того момента, пока обработчик нажатия кнопки не возвратит циклу выборки сообщений своего управления. Чтобы этого не произошло, используйте API-функцию PostMessage, которая посылает убийцу фокуса и, не дожидаясь от него ответа, как ни в чем не бывало продолжает выполнение.

Однако разработчики брандмауэров тоже не байтом деланы и всячески сопротивляются эмуляции ввода. Они могут вообще не обрабатывать указанных сообщений, реагируя, например, на WM_KEYDOWN или что-то еще. Коварство Windows заключается в том, что она позволяет нажать кнопку очень многими путями. Но ведь не ковыряться же с каждым отдельно взятым брандмауэром?!

Существует весьма простой и элегантный путь выхода из этой, казалось бы, безнадежной ситуации. Перемещаем мышиный курсор к нужной кнопке API-функцией MouseMove (координаты кнопки определяются как и прежде - через перечисление элементов управления), после чего вызываем API-функцию SendInput, имитирующую клавиатурный ввод на очень низком уровне. И все!!! Брандмауэр отдыхает!!!

Заключение

Разумеется, мы рассмотрели далеко не все возможные способы борьбы с персональными и внешними брандмауэрами и неизвестно, сколько времени они (способы, не брандмауэры!) еще продержатся на плаву. Но хакерская мысль не стоит на месте! Новые идеи рождаются буквально каждый день. Главное - крутить хвостом!