All-For-Kompa.RU

Сегодня:
Карта сайта форум Главная
Скрыть рекламный блок

Всё для компа

chat

Видео дня

Популярное

Реклама

Хочешь помочь проекту? Установи наш баннер!

Партнёры



Развлекательный портал по игре Dota 2. У нас вы первым узнаете о последних игровых новостях, сможете почитать интересные статьи и гайды, посмотреть стримы популярных комментаторов и многое другое.

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

Авторизация


Реклама

Хочешь помочь проекту? Установи наш баннер!

Опрос

Какую поисковую систему используете?

1. Яndex
2. Google
3. Rambler
4. Nigma
5. Другое
6. Mail
7. Yahoo!

Реклама

Хочешь помочь проекту? Установи наш баннер!

Популярные тэги

Комментарии

Счетчики

На сайте: 1
Прохожие: 1
Пользователей: 0
Статус:

Счётчик тИЦ и PR Rambler's Top100
АвторАвтор: leonP4 | ДатаДата: 05.01.2011 |Голосов: 0


Начиная с Server 2008 и Vista в винду был встроен механизм WFP, представляющий собой набор API и системных сервисов. С помощью него стало можно запрещать и разрешать соединения, управлять отдельными пакетами. Эти нововведения были предназначены для упрощения жизни разработчиков различных защит. Внесенные в сетевую архитектуру изменения затронули как kernel-mode, так и user-mode части системы. В первом случае необходимые функции экспортируются fwpkclnt.sys, во втором — fwpuclnt.dll (буквы "k" и "u" в названиях библиотек означают kernel и user соответственно). В этой статье мы расскажем о применении WFP для перехвата и фильтрации трафика, а после ознакомления с основными определениями и возможностями WFP мы напишем свой простой фильтр.

Основные понятия

Перед началом кодинга нам совершенно необходимо ознакомиться с терминологией Microsoft — и для понимания статьи будет полезно, и дополнительную литературу читать будет проще :). Итак, поехали.

Классификация — процесс определения того, что нужно делать с пакетом. Из возможных действий: разрешить, блокировать или вызвать callout.

Callouts — это набор функций в драйвере, которые проводят инспекцию пакетов. Они имеют специальную функцию, выполняющую классификацию пакетов. Эта функция может принять следующее решение:

  • разрешить (FWP_ACTION_PERMIT);
  • блокировать (FWP_ACTION_BLOCK);
  • продолжить обработку;
  • запросить больше данных;
  • прервать соединение.

Фильтры (Filters) — правила, указывающие, в каких случаях вызывается тот или иной callout. Один драйвер может иметь несколько callout’ов, а разработкой драйвера с callout’ом мы и займемся в этой статье. Кстати, колауты есть и встроенные, например, NAT-callout.

Layer — это признак, по которому объединяются различные фильтры (или, как говорят в MSDN, "контейнер").

По правде говоря, документация от Microsoft, выглядит достаточно мутно, пока не заглянешь в примеры в WDK. Поэтому, если вдруг надумаешь разрабатывать что-то серьезное, нужно непременно с ними ознакомиться. Ну что ж, теперь плавно перейдем к практике. Для успешной компиляции и тестов тебе потребуется WDK (Windows Driver Kit), VmWare, виртуальная машина с установленной Вистой и отладчик WinDbg. Что касается WDK, то у меня лично установлена версия 7600.16385.0 — там есть все необходимые либы (поскольку мы будем разрабатывать драйвер, нам нужны только fwpkclnt.lib и ntoskrnl.lib) и примеры использования WFP. Ссылки на весь инструментарий уже неоднократно приводились, поэтому повторяться не будем.

Coding

Для инициализации callout’а я написал функцию BlInitialize. Общий алгоритм создания callout и добавления фильтра таков:

  1. FWPMENGINEOPEN0 осуществляет открытие сеанса;
  2. FWPMTRANSACTIONBEGIN0 — начало операции с WFP;
  3. FWPSCALLOUTREGISTER0 — создание нового callout;
  4. FWPMCALLOUTADD0 — добавление объекта callout’а в систему;
  5. FWPMFILTERADD0 — добавление нового фильтра(ов);
  6. FWPMTRANSACTIONCOMMIT0 — сохранение изменений (добавленных фильтров).

Обрати внимание, что функции оканчиваются на 0. В Windows 7 некоторые из этих функций были изменены, например, появилась FwpsCalloutRegister1 (при  сохраненной FwpsCalloutRegister0). Отличаются они аргументами и, как следствие, прототипами классифицирующих функций, но для нас это сейчас неважно — 0-функции универсальны.

FwpmEngineOpen0 и FwpmTransactionBegin0 не особо нам интересны — это подготовительный этап. Самое интересное начинается с функции FwpsCalloutRegister0:

Прототип FwpsCalloutRegister0

NTSTATUS NTAPI FwpsCalloutRegister0
(
    __inout void *deviceObject,
    __in const FWPS_CALLOUT0 *callout,
    __out_opt UINT32 *calloutId
);

Я уже говорил, что callout — это набор функций, теперь пришло время рассказать об этом подробнее. Структура FWPS_CALLOUT0 содержит указатели на три функции — классифицирующую (classifyFn) и две уведомляющие (о добавлении/удалении фильтра (notifyFn) и закрытии обрабатываемого потока (flowDeleteFn)). Первые две функции являются обязательными, последняя нужна только в случае, если ты хочешь мониторить сами пакеты, а не только соединения. Также в структуре содержится уникальный идентификатор, GUID колаута (calloutKey).

Код регистрации callout

FWPS_CALLOUT sCallout = {0};
sCallout.calloutKey = *calloutKey;
sCallout.classifyFn = BlClassify;
// классифицирующая функция
sCallout.notifyFn = (FWPS_CALLOUT_NOTIFY_FN0)BlNotify;
// функция, уведомляющая о добавлении/удалении фильтра
// создаем новый колаут
status = FwpsCalloutRegister(deviceObject, &sCallout, calloutId);

Далее нужно добавить объект-callout в систему и присоединить его к определенному уровню (layer) с помощью функции FwpmCalloutAdd0:

DWORD WINAPI FwpmCalloutAdd0(
__in HANDLE engineHandle,
__in const FWPM_CALLOUT0 *callout,
__in_opt PSECURITY_DESCRIPTOR sd,
__out_opt UINT32 *id
);
typedef struct FWPM_CALLOUT0_ {
    GUID calloutKey;
    FWPM_DISPLAY_DATA0 displayData; // описание callout
    UINT32 flags;
    GUID *providerKey;
    FWP_BYTE_BLOB providerData;
    GUID applicableLayer;
    UINT32 calloutId;
} FWPM_CALLOUT0;

В структуре FWPM_CALLOUT0 нам интересно поле applicableLayer — уникальный идентификатор уровня, на который добавляется callout. В нашем случае это FWPM_LAYER_ALE_AUTH_CONNECT_V4. "v4" в названии идентификатора означает версию протокола Ipv4, есть также FWPM_LAYER_ALE_AUTH_CONNECT_V6 для Ipv6. Учитывая малую распространенность Ipv6 на настоящий момент, работать мы будем только с Ipv4. CONNECT в названии означает, что мы контролируем только установку соединения, о входящих и исходящих на этот адрес пакетах речи не идет! Вообще уровней, помимо использованного нами, много — они объявлены в заголовочном файле fwpmk.h из WDK.

Добавление объекта-callout в систему

// название callout
displayData.name = L"Blocker Callout";
displayData.description = L"Blocker Callout";
mCallout.calloutKey = *calloutKey;
mCallout.displayData = displayData;
// описание callout
//FWPM_LAYER_ALE_AUTH_CONNECT_V4
mCallout.applicableLayer = *layerKey;
status = FwpmCalloutAdd(gEngineHandle, &mCallout, NULL, NULL);

Итак, после того, как callout успешно добавлен в систему, нужно создать фильтр, то есть указать, в каких случаях будет вызываться наш callout, а именно — его классифицирующая функция. Новый фильтр создается функцией FwpmFilterAdd0, которой в качестве аргумента передается структура FWPM_FILTER0.

В FWPM_FILTER0 есть одна или несколько структур FWPM_FILTER_CONDITION0 (их число определяется полем numFilterConditions). Поле layerKey заполняется GUID’ом уровня (layer), к которому мы хотим присоединиться. В данном случае указываем FWPM_LAYER_ALE_AUTH_CONNECT_V4.

Теперь подробнее рассмотрим заполнение FWPM_FILTER_CONDITION0. Во-первых, в поле fieldKey нужно явно указать, что мы хотим контролировать — порт, адрес, приложение или что-то еще. В данном случае WPM_CONDITION_IP_REMOTE_ADDRESS указывает системе, что нас интересует IP-адрес. Значение fieldKey определяет, значения какого типа будут в структуре FWP_CONDITION_VALUE, входящей в FWPM_FILTER_CONDITION0. В данном случае в ней содержится ipv4-адрес. Идем дальше. Поле matchType определяет, каким образом будет производиться сравнение значения в FWP_CONDITION_VALUE с тем, что пришло по сети. Тут вариантов много: можно указать FWP_MATCH_EQUAL, что будет означать полное соответствие условию, а можно — FWP_MATCH_NOT_EQUAL, то есть, фактически, мы можем добавить таким образом исключение фильтрации (адрес, соединение с которым не отслеживается). Еще есть варианты FWP_MATCH_GREATER, FWP_MATCH_LESS и другие (см. энум FWP_MATCH_TYPE). В данном случае у нас стоит FWP_MATCH_EQUAL.

Я не стал сильно заморачиваться и просто написал условие на блокирование одного выбранного IP-адреса. В случае, когда какое-то приложение попытается установить соединение с выбранным адресом, будет вызвана классифицирующая функция нашего callout’а. Код, обобщающий сказанное, ты можешь посмотреть на врезке "Добавление фильтра в систему".

Добавление фильтра в систему

filter.flags = FWPM_FILTER_FLAG_NONE;
filter.layerKey = *layerKey;
filter.displayData.name = L"Blocker Callout";
filter.displayData.description = L"Blocker Callout";
filter.action.type = FWP_ACTION_CALLOUT_UNKNOWN;
filter.action.calloutKey = *calloutKey;
filter.filterCondition = filterConditions;
// одно условие фильтрации
filter.numFilterConditions = 1;
//filter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL;
filter.weight.type = FWP_EMPTY; // auto-weight.
// добавляем фильтр на удаленный адрес
filterConditions[0].fieldKey = FWPM_CONDITION_IP_REMOTE_ADDRESS;
filterConditions[0].matchType = FWP_MATCH_EQUAL;
filterConditions[0].conditionValue.type = FWP_UINT32;
filterConditions[0].conditionValue.uint32 = ntohl(BLOCKED_IP_ADDRESS);
// добавляем фильтр
status = FwpmFilterAdd(gEngineHandle, &filter, NULL, NULL);

Вообще, конечно, фильтрующих условий может быть много. Например, можно указать блокирование соединений с определенным удаленным или локальным портом (FWPM_CONDITION_IP_REMOTE_PORT и FWPM_CONDITION_IP_LOCAL_PORT соответственно). Можно вылавливать все пакеты определенного протокола или определенного приложения. И это еще не все! Можно, например, заблокировать трафик определенного пользователя. В общем, есть где разгуляться.

Впрочем, вернемся к фильтру. Классифицирующая функция в нашем случае просто блокирует соединение с указанным адресом (BLOCKED_IP_ADDRESS), возвращая FWP_ACTION_BLOCK:

Код нашей classify-функции

void BlClassify(
const FWPS_INCOMING_VALUES* inFixedValues,
const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
VOID* packet,IN const FWPS_FILTER* filter,
UINT64 flowContext,FWPS_CLASSIFY_OUT* classifyOut)
{
    // заполняем структуру FWPS_CLASSIFY_OUT0
    if(classifyOut){ // блокируем пакет
        classifyOut->actionType = FWP_ACTION_BLOCK;
        // при блокировании пакета нужно сбрасывать FWPS_RIGHT_ACTION_WRITE
        classifyOut->rights&=~FWPS_RIGHT_ACTION_WRITE;
    }
}

На практике функция классификации также может установить FWP_ACTION_PERMIT, FWP_ACTION_CONTINUE и др.

И в заключение при выгрузке драйвера нужно удалить все установленные callout’ы (угадай, что будет, если система попытается вызвать callout выгруженного драйвера? Правильно, BSOD). Для этого существует функция FwpsCalloutUnregisterById. В качестве параметра ей передается 32-битный идентификатор callout’а, возвращенный функцией FwpsCalloutRegister.

Завершение работы callout’а

NTSTATUS BlUninitialize(){
    NTSTATUS ns;
    if(gEngineHandle){
        FwpmEngineClose(gEngineHandle);
       
    }
    if(gBlCalloutIdV4){
        ns =FwpsCalloutUnregisterById(gBlCalloutIdV4);
    }
    return ns;
}

Как видишь, программирование WFP-фильтра — не такая сложная задача, поскольку MS предоставили нам весьма удобный API. Кстати, в нашем случае мы устанавливали фильтр в драйвере, но это можно делать и из юзермода! Например, семпл из wdk msnmntr (монитор трафика MSN Messenger-а) так и поступает — это позволяет не перегружать kernel-mode часть фильтра.

Свой GUID

Для регистрации callout ему нужен уникальный идентификатор. Для того, чтобы получить свой GUID (Globally Unique Identifier), используй guidgen.exe, входящий в Visual Studio. Лежит тулза в (VS_Path)\Common7\Tools. Вероятность коллизии очень мала, поскольку длина GUID составляет 128 бит, и всего доступно 2^128 идентификаторов.

Отладка фильтра

Для отладки дров удобно использовать связку Windbg+VmWare. Для этого нужно настроить как гостевую систему (в виде которой выступает Vista), так и отладчик WinDbg. Если у WinXP для удаленной отладки нужно было редактировать boot.ini, то для Vista+ есть консольная утилита bcdedit. Как обычно, нужно включить отладку:

BCDedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 BCDedit /debug ON (или BCDedit /set debug ON)

Далее нужно настроить последовательный порт удаленной системы (см. соответствующую иллюстрацию).

Теперь все готово! Запускаем батник с нижеприведенным текстом:

start windbg -b -k com:pipe,port=\\.\pipe\com_1,resets=0

и лицезреем отладочный вывод в окне windbg (см. картинку).

Заключение

Как видишь, область применения WFP довольно широка. Тебе решать, как применить эти знания — во зло или во благо :)



Теги к статье:

| : программирование, взлом
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Популярные файлыНовые файлы
Call of Duty 5: World at ...[ Скачали 67375 раз ]
Амфибии, Гайд по ассасина...[ Скачали 31758 раз ]
Амфибии, Гайд по шаманам.[ Скачали 30663 раз ]
cs 1.6 patch v48 full[ Скачали 29045 раз ]
Русский бот PW Alfa v 2.6[ Скачали 17192 раз ]
Огромный пак глюков и баг...[ Скачали 12743 раз ]
civilization 5 скачать бе...[ Скачали 11941 раз ]
PW MP5[ Скачали 11147 раз ]
MHS-Bot-PW 2.3 ботовод[ Скачали 10403 раз ]
Niko Bellic (нико белич) ...[ Скачали 10005 раз ]
Inkbound (2024/En/MULTI/R...[ Добавлен 13.04.2024 ]
The Planet Crafter (2024/...[ Добавлен 13.04.2024 ]
My Life: Farm Vet (2024/R...[ Добавлен 12.04.2024 ]
Headquarters: World War I...[ Добавлен 12.04.2024 ]
Ereban: Shadow Legacy (20...[ Добавлен 11.04.2024 ]
Broken Roads (2024/Ru/En/...[ Добавлен 11.04.2024 ]
Wallpapers Girls №1042[ Добавлен 11.04.2024 ]
Children of the Sun (2024...[ Добавлен 09.04.2024 ]
Wallpapers Girls №1041[ Добавлен 09.04.2024 ]
Wallpapers Girls №1040[ Добавлен 08.04.2024 ]