Когда мы напишем пример, то компилятор должен будет знать о функциях фильтрации. В Visual Studio .NET для этого есть нужный заголовочный файл - fltdefs.h, а вот Borland что-то в этом деле отстает. Мне пришлось потратить целый день на поиски нормального варианта этого файла для Delphi, и, в конце концов, было найдено решение в виде модуля fltdefs.pas. Данный модуль вы можете найти на компакт-диске в каталоге Additional\PacketFilter.

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

Листинг 5.1. Установка фильтров

procedure TFirewaПForm.btStartFilterClick(Sender: TObject). var
wsaData: TWSAData;
begin
if (WSAStartup(MakeWordd.l), wsaData) <> 0) then begin
ShowMessage('Ошибка WinSock');
exit, end;
if not GetLoca1IPAddr(@ipLocal) then exit;

// Создание интерфейса

PfCreateInterface(0. PF_ACTION_FORWARD. PF_ACTION_FORWARD.
False. True, hlF).

// Добавление нескольких фильтров

AddFilterCtrue, '192.168.1.1'. FILTER_PROTO_TCP. nil);
AddFiIter(true. '192.168.8.57'. FILTER_PROTO_TCP. '21');
AddFiIter(false. '192.168.1.3'. FILTER_PROTO_ANY. '7');
AddFilterUrue. '192.168.1.4', FILTER_PROTO_UDP. '1024');
// Блокировка любых исходящих обращений к порту 80 AddFilterCfalse, nil. FILTER_PROTO_TCP, '21'); // Привязка интерфейса к локальному адресу PfBindInterfaceToIPAddress(hIF. PFJPV4. @ipLocal);
btStopFi1ter.Enabled.=true;
end;

Обратите внимание, что в самом начале загружается библиотека WinSock, так как для работы понадобятся сетевые функции. Если этого не сделать, то ошибок во время выполнения программы будет очень много.

Далее создается новый интерфейс PfCreatelnterface, и к нему добавляются фильтры с помощью функции AddFilter. Эту функцию мы рассмотрим чуть позже.

Обратите внимание, что фильтры можно устанавливать на определенную машину и не указывать порт:

AddFilterCtrue. '192.168.1.1'. ptTcp. nil);

В этом случае обращения на любой порт с адреса 192.168.1.1 будут закрыты. Можно запретить обращение на определенный порт с любого компьютера, используя такую запись:

AddFilter(true. nil. ptTcp. '21');

Функция PfBindlnterfaceToIPAddress вызывается после того, как фильтры сформированы, для их связи с локальным сетевым интерфейсом. Мы также делаем кнопку останова фильтрации доступной, чтобы можно было остановить сетевой экран.

Теперь посмотрим на функцию AddFilter. Ее текст приведен в листинге 5.2. Листинг 5.2. Функция установки фильтра

procedure TFirewal1Form.AddFi1ter(inP: Boolean:1pszRemote: PChar:
protoType: DWORD: IpszPort: PChar);
var
ipFlt: PF_FILTER_DESCRIPTOR: dwPort: Integer;
ipDest: TIpBytes;
ipSrcMask: TIpBytes;
ipDstMask: TIpBytes;
begin
ZeroMemory(@ipFlt. SizeOf(ipFlt));
ipFlt.dwFilterFlags := FD_FLAGS_NOSYN;
ipFlt.dwRule := 0; ipFlt.pfatType := PFJPV4; ipFlt.fLateBound := 0;
ipFlt.dwPrOtOCOl := protoType;

if Assigned(lpszPort) then dwPort := StrToIntDef(IpszPort. FILTER_TCPUDP_PORT_ANY) ~" продолжение #

Листинг 5.2 (продолжение) else dwPort -= FILTER_TCPUDP_POPJ_ANY:

if inP then begin
ipFlt.wDstPort := FILTER_TCPUDP_PORT_ANY, ipFlt wDstPortHighRange := FILTER_TCPUDP_PORT_ANY;
ipFlt.wSrcPort :" dwPort: ipFlt.wSrcPortHighRange := dwPort:
end
else
begin
ipFlt.wDstPort := dwPort;
ipFlt.wDstPortHighRange -= dwPort;
ipFlt.wSrcPort •= FILTER_TCPUDP_PORT_ANY;
ipFlt.wSrcPortHighRange : = FILTER_TCPUDP_PORT_ANY:
end:
StrToIP("255.255.255.0'. @ipSrcMask): StrToIP('255.255.255.0'. @ipDstMa sk);
if inP then begin
if Assigned(lpszRemote) then begin
ipFlt.SrcAddr := PByteArray(StrToIp(lpszRemote. @ipDest)). ipFlt.SrcMask := @ipSrcMask:
end
else
beg'in
ipFlt.SrcAddr := PByteArrayCStrToIpC 0.0.0 0'. @ipDest)): StrToIP('0.0.0.0'. @ipSrcMask): ipFlt.SrcMask := @ipSrcMask;
end.
ipFlt.DstAddr .= (MpLocal: ipFlt.DstMask := @ipDstMask.
PfAddFiltersToInterface(hIF. 1. @ipFlt. 0. nil. nil):
end
else
begin
ipFlt.SrcAddr := @ipl_ocal;
ipFlt.SrcMask := @ipSrcMask. if Assigned(lpszRemote) then begin
ipFlt.DstAddr := PByteArray(StrToIp(lpszRemote, @ipDest)). ipFlt.DstMask := @ipDstMask:
end
else
begin
ipFlt DstAddr := PByteArray(StrToIp('0.0.0.0'. @ipDest)):
StrToIPC'O.0.0.0'. @ipDstMask);
ipFlt.DstMask := @ipDstMask;
end:
PfAddFiltersToInterface(hIF. 0. nil. 1. @ipFlt. nil):
end, end:

В функции AddFi 1 ter вначале обнуляется содержимое структуры i pFl t, имеющей тип _Р FF ILTERDESCRIPT0R. Для этого вызывается функция ZeroMemory, у которой в первом параметре нужно задать указатель на обнуляемую память, а во втором - размер.

После этого заполняются поля структуры. Как мы уже говорили, в параметре dwFilterFlags должны указываться флаги, но на данный момент поддерживается только FD_FLAGS_NOSYN.

Так как сейчас пока используется четвертая версия IP-адресации, в параметре pf at-Туре устанавливается флаг PFIPV4. Для протокола (параметр dwProtocol ) задается значение, которое было указано в параметре protoType функции AddFi Iter.

Далее заполняются параметры адреса DstAddr, SrcAddr, масок и портов, в зависимости от того, предназначен ли фильтр для входящих пакетов или нет. Когда структура сформирована, можно вызывать функцию Pf AddFi ItersToInterfасе для установки нужного фильтра.

По нажатии кнопки останова выполняется следующий код:

procedure TFi rewa11 Form.btStopFi1terCl i ck(Sender : TObject);
begin
PfUnBindlnterface(hlF). PfDeletelnterface(hlF);
WSACleanup:
btStopFiIter.Enabled := false, end:

Сначала отсоединяем интерфейс с помощью функции PfUnBindlnterface и только потом удаляем его функцией Pf Del etelnter face. Теперь нам уже не нужна сетевая библиотека WinSock, поэтому ее можно выгрузить.

ПРИМЕЧАНИЕ -

Исходный код рассмотренного здесь примера находится на компакт-диске в каталоге Sources\ch05\Firewall.

Как видите, создать свой собственный сетевой экран не так уж и сложно. Только вот в качестве движка будет использоваться встроенный в систему сервис Packet Filtering от MS. Системное окно настройки безопасности сетевого соединения представлено на рис. 5.3.

Для решения простых задач этого достаточно.

Данный пример описывал создание сетевого экрана на основе правил. Более мощные системы имеют возможность определения основных атак, защиту от сканирования, проверку правильности входящих данных, отслеживание корректности заголовков пакетов и т. д.

5.1.2. Пример использования фильтрации

Рис. 5.3. Системное окно настройки безопасности

5.1.1. Функции фильтрации пакетов || Оглавление || 5.2. SMTP-клиент на WinSock API


Delphi в шутку и всерьез: что умеют хакеры



Новости за месяц

  • Январь
    2022
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс