Принципи побудови та функціонування мережевих екранів (firewall) в ОС WINDOWS

Сюди я виклав частину своєї курсової яка була присвячена Мережевим Екранам. Кінцевим результатом роботи стала реалізація простого мережевого екрану - фільтру пакетів.
При використанні нижче наведеної інформації посилання на сайт обовязкове.


Мережеві екрани та їхні можливості
Дати якесь конкретне означення мережевого екрану доволі важко, оскільки вони дуже відрізняються за функціями та типами використання. Загалом, мережевий екран призначений для заборони чи дозволу користування певними сервісами зовнішньої мережі комп’ютерові чи їх групі, а також навпаки. Точніше зрозуміти призначення мережевих екранів нам допоможе нижче наведений розподіл за функціями та класифікація. Перш за все мережеві екрани поділяються на персональні та міжмережні. Персональний мережевий екран призначений для захисту одного комп’ютера, в той час коли міжмережні використовують для цілої робочої групи чи підмережі. Мережеві екрани бувають програмні, а також апаратні (тільки міжмережні). Апаратні мережеві екрани підключають у вигляді окремого пристрою до мережі.

Функції мережевих екранів:

• Фільтрація пакетів. Це одна з трьох загальновідомих функцій мережевого екрану. У цьому випадку виконуються зовсім прості функції (фактично як у спеціалізованого маршрутизатора), які полягають у перегляді заголовка кожного пакету та перевірки ІР адреси та порта на правильність. Наприклад, пакет, який передається в Інтернет, але має локальну адресу призначення, блокується. Ця функція присутня у всіх сучасних мережевих екранах і відрізняється високою швидкодією та відсутністю необхідності діалогу з користувачем.
• Проксі сервер. Це друга загальновідома функція. Різниця між проксі сервером та фільтрацією пакетів полягає в тому, що проксі сервер вимагає, щоб всі сеанси зв’язку встановлювались через нього, а не напряму. Отримавши дані, проксі сервер відсилає їх далі від свого імені, а отримавши відповідь, пересилає її потрібному комп’ютеру внутрішньої мережі. Як можна здогадатись, продуктивність не є такою ж високою, як при фільтрації пакетів, але достатньою, оскільки відбувається тільки заміна заголовка пакета. Головною перевагою проксі сервера є те, що він приховує справжні адреси ваших комп’ютерів, замінюючи їх на свою. Це унеможливлює атаку на конкретний комп’ютер в підмережі.
• Проксі сервер програм. Це третя функція. Цей різновид проксі сервера відрізняється “розумінням” протоколів програм, що ведуть передачу даних. Хороший приклад такого сервера –поштовий сервер. Проксі сервер програм може проводити ідентифікацію користувачів, а не тільки покладатись на ІР адресу, в деяких випадках можливе виявлення передавання вірусів та іншого шкідливого коду. Це все звичайно потребує набагато більших обчислювальних потужностей, а також в більшості випадків вимагає значного перенастроювання робочих станцій, через що втрачається прозорість роботи мережевого екрану.
• Кешування даних. Це не є традиційною функцією мережевих екранів, але на даний час стає надзвичайно популярною властивістю. Ідея полягає у тому, що, оскільки всі дані проходять через мережевий екран, він може зберігати найбільш популярну інформацію і при наступному звертанні за нею видати її зі свого кешу.
• Статистика та повідомлення. Важливою властивістю мережевого екрану є ведення історії всіх мережевих з’єднань, а також вивід повідомлень про атаки на мережу чи комп’ютер. Історія з’єднань допомагає правильно настроїти мережевий екран, щоб комп’ютер був одночасно захищений від нападів і відкритий для доступу авторизованим користувачам.
• Керування. Для персональних мережевих екранів основна характеристика – зручність їхнього налаштування. Керування міжмережними екранами здебільшого відбувається дистанційно (використовуючи HTML інтерфейс чи інший), що потребує впевненості в надійності авторизації та каналу зв’язку.


Можливості реалізації мережевого екрану в Windows
Наведемо схему мережевої підсистеми Windows 2000/XP: рисунки взяті з сайту www.ndis.com

Розглянемо можливі варіанти реалізації фільтрації мережевого трафіку. Для цього можна використати два принципово різні підходи: фільтрація на рівні прикладних програм та фільтрація на рівні ядра.

Фільтрація на рівні прикладних програм
Такий спосіб фільтрації накладає певні обмеження, так як не забезпечує обов’язкового перегляду всієї інформації, що передається мережевою підсистемою, оскільки програма, при потребі, може напряму звертатися до інтерфейсу TDI, оминаючи Windows Sockets. Але у зв’язку з простотою реалізації цей метод варто розглянути.
• Winsock Layered Service Provider (LSP). Цей метод полягає у перехопленні викликів прикладних програм функцій з бібліотеки сокетів. Крім цього, він дозволяє ідентифікувати процес, який ініціалізував виклик. LSP можна використати для реалізації таких задач як QOS (Quality Of Service), шифрування потоків даних тощо. Але цей метод зовсім не підходить для захисту від вірусів і їм подібного, оскільки TCPIP.sys можна викликати оминаючи Windows Sockets, використовуючи TDI. Також цей спосіб зовсім не підходить для фільтрації пакетів на маршрутизаторі, оскільки вона виконується драйвером протоколу, а деколи не доходить і до нього.
• Windows 2000 Packet Filtering Interface. Цей метод можна використовувати тільки в операційних системах Windows класу сервер версії 2000 або вище. Він полягає у встановленні прикладною програмою набору фільтрів (ІР адреса та порт), на основі яких операційна система здійснює фільтрацію пакетів.
• Заміна Winsock DLL. Як можна зрозуміти з назви, цей спосіб полягає у заміні бібліотеки winsock.dll на свою. Враховуючи сучасні можливості фільтрації пакетів в Windows, цим методом слід користуватись в останню чергу, оскільки використання своєї бібліотеки може призвести до нестабільності системи.
• Глобальне перехоплення. Можливо реалізувати глобальне перехоплення всіх потенційно небезпечних функцій. Але цей метод також не є раціональним, оскільки він трудомісткий і загрожує стабільності системи.


Фільтрація на рівні ядра
Фільтрація на рівні ядра перш за все означає написання драйвера з подальшим введенням в нього необхідної функціональності, відповідно до вибраного способу реалізації фільтрації.
• Kernel-mode sockets filter. Цю технологію можна використовувати для Windows NT/2000/XP. Вона полягає у перехопленні всіх викликів з msafd.dll (найнижча з user-mode бібліотек Windows Sockets) до модуля ядра afd.sys (TDI-клієнт, kernel-частина зі складу Windows Sockets). Цей метод заслуговує на увагу, але його можливості не набагато ширші від LSP.
• TDI-filter. Цю технологію можна використовувати у всіх 32 розрядних версіях Windows, хоча конкретні реалізації відрізняються. А полягає цей метод у написанні драйвера, який розташується безпосередньо над драйвером ТСР/ІР, таким чином фільтруючи всі дані, що передаються від нього вищим рівням. Це досить відомий спосіб фільтрації і використовується у ряді комерційних мережевих екранів. Однак його можна використовувати тільки для персональних мережевих екранів (з вищезгаданих причин).
• NDIS Intermediate Driver. Microsoft передбачила цей клас драйверів якраз для потреб подібних нашим. Однак їх функціональність в операційних системах Windows 98/Me/NT залишає бажати кращого, а в Windows 95 вони взагалі відсутні. Крім цього, ці драйвери дуже незручні в інсталяції для кінцевого користувача.
• Windows 2000 Filter-Hook Driver. Цей метод можна використовувати в операційних системах Windows 2000 і вище. Полягає він у написанні драйвера, який реєструє callback функцію для фільтрації пакетів.
• NDIS Hooking Filter Driver. Якщо коротко, то цей метод зводиться до перехоплення деякої підмножини функцій бібліотеки NDIS. В подальшому за допомогою цих функцій можна відслідковувати реєстрацію всіх протоколів, встановлених в операційній системі, і відкриття ними мережевих інтерфейсів. Серед переваг даного методу слід також згадати легкість інсталяції та прозору роботу з Dial-Up інтерфейсами.

Реалізація мережевого екрану
Для реалізації мережевого екрану був вибраний один із вищенаведених способів. Критеріїв вибору було декілька, а саме: відносна простота реалізації, наявність мінімально необхідної функціональності, перспективність технології. На варіанті фільтрації на рівні користувача ми вирішили не зупинятись, оскільки це дещо нераціональний спосіб. Отже, було вибрано написання драйвера, який би реалізував технологію Windows 2000 Filter-Hook Driver. Цей варіант дозволяє повною мірою реалізувати фільтрацію пакетів на рівні ядра, в той же час не надто заглиблюючись в особливості написання модулів ядра Windows. Те, що цей варіант працює тільки в операційних системах Windows 2000/XP, на нашу думку серйозним недоліком не являється, оскільки за наявною інформацією всі наступні версії Windows будуть продовженням саме цих ОС, а не сімейства 9x/Me.
Драйвер фільтрації може бути під’єднаний до операційної системи та запущений у будь-який момент роботи Windows і не потребує перезавантаження. Під час ініціалізації драйвер реєструє в системі функцію зворотного виклику, яку система викликає для кожного переданого чи прийнятого пакету. Проаналізувавши передані в функцію дані, можна дозволити проходження пакету або ж заблокувати.

Написання драйвера Windows
Для написання драйвера можна користуватися будь-яким зручним для вас середовищем С/С++. Але компіляція та лінкування драйвера повинні виконуватись спеціальним засобами, які входять в пакет Windows DDK (Driver Development Kit). Оскільки ми пишемо драйвер з достатньо новою архітектурою, тому версія DDK повинна бути не нижчою 2000. Можна також скористатися інтегрованими середовищами розробки драйверів, які позбавляють нас від компіляції в командній стрічці. Зокрема, добре відомим пакетом є Numega SoftICE Driver Suite, який складається з великої кількості допоміжних програм та утиліт, а що найголовніше – пропонує розробникам свою власну бібліотеку класів для написання драйверів, що значно полегшує цю роботу. Для написання драйвера було вирішено послугами Numega SoftICE Driver Suite не користуватись, оскільки це б потягнуло за собою надзвичайну кількість додатково коду порівняно з корисним. Ми користувались чистим Windows 2000 DDK, в деяких випадках використовуючи утиліти Numega Driver Suite, наприклад, DriverMonitor.
В системі Windows є два основні типи драйверів: рівня користувача та рівня ядра. До драйверів рівня користувача відносяться деякі драйвери принтерів, а також драйвери віртуальних пристроїв для DOS. Драйвери ядра – це драйвери логічних, віртуальних або фізичних пристроїв. Ці драйвери також діляться на три рівні відносно їхнього наближення до апаратної частини. Нижче наведена схема дає уявлення про цю класифікацію:

При написанні драйверів ядра ніколи не слід забувати, що вони вважаються операційною системою перевіреними компонентами, а тому при неправильному функціонуванні легко можуть вивести систему з робочого стану.
Реалізація Filter-Hook Driver
Як ми вже згадували, Filter-Hook Driver – це драйвер ядра, який реалізує callback функцію, яку називають filter hook, і реєструє її в драйвері IP фільтра системи. IP фільтр використовує цю функцію для визначення як поступати з вхідним чи вихідним пакетом. Отже, наш драйвер повинен реалізовувати такий собі фільтр, яким би користувався системний драйвер для визначення дії щодо кожного пакета.
Розглянемо спочатку головну функцію фільтрації пакетів:
typedef PF_FORWARD_ACTION (*PacketFilterExtensionPtr)(
IN unsigned char *PacketHeader,
IN unsigned char *Packet,
IN unsigned int PacketLength,
IN unsigned int RecvInterfaceIndex,
IN unsigned int SendInterfaceIndex,
IN IPAddr RecvLinkNextHop,
IN IPAddr SendLinkNextHop
);

При кожному проходженні пакету системний драйвер ІР фільтру передає в цю функцію інформацію про пакет. PacketHeader – вказівник на заголовок пакету
Packet – вказівник на дані пакету (не включаючи заголовок)
PacketLength – розмір в байтах інформації, що передається пакетом, не включає заголовок пакета.
RecvInterfaceIndex – для прийнятого пакета, порядковий номер мережевого контролера (NIC – Network Interface Adapter), через який його прийнято. Для пакетів, що передаються, встановлюється значення INVALID_PF_IF_INDEX.
SendInterfaceIndex – для пакета, що передається, порядковий номер адаптера, який його передасть. Для пакетів, що приймаються, встановлюється значення INVALID_PF_IF_INDEX.
Опрацювавши пакет, функція повертає певне значення в залежності від того, що потрібно з пакетом.
Для встановлення докладної інформації про пакет слід використовувати дані заголовка пакета, їх зручно привести до такої структури:

typedef struct IPHeader {
UCHAR iph_verlen; // Version and length
UCHAR iph_tos; // Type of service
USHORT iph_length; // Total datagram length
USHORT iph_id; // Identification
USHORT iph_offset; // Flags, fragment offset
UCHAR iph_ttl; // Time to live
UCHAR iph_protocol; // Protocol
USHORT iph_xsum; // Header checksum
ULONG iph_src; // Source address
ULONG iph_dest; // Destination address
} IPHeader;

У DriverEntry драйвера повинна відбуватись реєстрація callback функції. А при вивантаженні драйвера – дереєстрація. Для того, щоб зареєструвати чи анулювати callback функцію, драйвер спочатку створює IRP, використовуючи вказівник на пристрій об’єкта ІР фільтру, а також вказівник на callback функцію. Після цього цей IRP відправляється ІР фільтру. Точніше це виглядає так:
• Викликається функція IoGetDeviceObjectPointer, яка повертає вказівник на об’єкт для драйвера ІР фільтру. Наш драйвер повинен передати в цю функцію:
  o Вказівник на буфер, який містить назву драйвера ІР фільтру
  o Значення, які вказують на синхронний доступ на запис і зчитування до драйвера ІР фільтру
  o Вказівники на буфери для збереження повернутих значень вказівників на об’єкт пристрою та відповідний йому об’єкт файла.
• Викликається IoBuildDeviceIoControlRequest, щоб встановити IRP. Цей виклик повертає IRP з готовими параметрами. Функції необхідно передати параметри:
  o Значення IOCTL_PF_SET_EXTENSION_POINTER
  o Вказівник на об’єкт пристрою драйвера ІР фільтру
  o Буфер, який містить PF_SET_EXTENSION_HOOK_INFO. Для того, щоб зареєструвати filter-hook, ця структура повинна містити вказівник на callback функцію. Для очищення фільтра – NULL.
• Викликаємо функцію IoCallDriver для передачі IRP драйверу ІР фільтра, передавши параметрами вказівник на об’єкт пристрою драйвера ІР фільтра та раніше створений IRP.
Після написання всіх вищенаведених функцій драйвер вже може виконувати свої обов’язки, оскільки в callback функції можна описати якийсь критерій для фільтрації пакетів. Але це виходить досить закрита система, без можливості впливу ззовні, а для кожного переконфігурування потрібно би було перекомпільовувати сам драйвер. Тому було вирішено написати програму-оболонку для драйвера, яка б встановлювала та відміняла правила фільтрації пакетів у драйверів. Звичайно для цього драйвер повинен реалізовувати функції обробки звертань до нього (IRP_MJ_DEVICE_CONTROL). Для своєї ідентифікації прикладною програмою драйвер повинен створити віртуальний пристрій, звертаючись до якого прикладна програма зможе працювати з драйвером. Для цього використовується декілька функцій, головною з яких є IoCreateDevice. Особливих причин зупинятись на цьому немає, оскільки це один із стандартних способів організації зв’язку прикладних програм з їхніми kernel-модулями. Для обробки запитів від програм драйвер при ініціалізації реєструє функцію, так би мовити, обробки подій. В ній і відбувається взаємодія драйвера з прикладними програмами, а також і з деякими повідомленнями операційної системи. Функція багато в чому подібна до віконної функції обробки повідомлень. Звіривши код повідомлення, драйвер виконує відповідну роботу, зчитуючи дані з програми чи навпаки. В нашому драйвері реалізовано фільтрацію, яка може залежати від довільної кількості фільтрів, щоправда цю кількість потрібно встановити під час компіляції. Кожен з фільтрів дозволяє проводити фільтрацію за такими параметрами (одночасно або вибірково):
• Адреса та порт відправлення
• Адреса та порт призначення
• Протокол (TCP/UDP)
• Мережевий інтерфейс
Крім цього, було вирішено для більшої наглядності роботи драйвера та інформативності додати у драйвер функцію перегляду пакетів, що передаються в мережі. Ця функціональність сама по собі є достатньо корисною, оскільки дозволяє виявити потенційні проблеми в захисті, бо дозволяє побачити несанкціоновані зв’язки з зовнішніми машинами на нестандартних портах. В драйвері постійно зберігається інформація (адреса та порт відправлення, адреса та порт призначення, протокол, мережевий інтерфейс, розмір) про 50 останніх посланих чи прийнятих пакетів, і в будь-який час ця інформація може бути передана в програму-оболонку.

Програма-оболонка
Програму-оболонку було написано в середовищі Borland C++ Builder 6.0, хоча це зовсім не заважає у інших реалізаціях користуватись будь-яким 32 розрядним компілятором для Windows. Програма пропонує зручний інтерфейс для додавання фільтрів, їхнього вибіркового видалення. Також присутні функції збереження фільтрів у файл та їхнє зчитування. Не слід забувати що драйвер з фільтрами залишається функціонувати і при закритті програми, тому було введено функцію не тільки встановлення фільтрів у драйвер, але й їхнє зчитування. Для перегляду пакетів та результатів роботи фільтрів присутнє вікно, яке виводить інформацію про 50 останніх пакетів, а також, чи вони були заблоковані. Зверху головного вікна програми розташовані кнопки керування драйверами, вони використовують різні системні функції, на яких варто зупинитись докладніше:
OpenSCManager – встановлює зв’язок з локальним менеджером сервісів, за допомогою якого проводиться інсталяція та запуск драйверів.
CreateService – інсталює потрібний нам сервіс (драйвер) з потрібними параметрами автозапуску тощо.
StartService – запускає вже зареєстрований в базі сервіс.
ControlService – служить для передання команд запущеному сервісу чи драйверу, наприклад, зупинитись.
DeleteService – видаляє сервіс із системи.
Слід пам’ятати, що всі ці функції для свого виконання потребують прав адміністратора. Після встановлення та запуску драйвера для зв’язку з ним використовується інший клас функцій. Для отримання хендлера драйвера використовується відома функція CreateFile, правда, можливо з незвичним параметром, оскільки ми все ж таки відкриваємо пристрій драйвера, а не файл. Замість назви файла потрібно прописати назву пристрою, який ми реєструємо у драйвері. Стрічка має мати вигляд “\\.\device_name”. Отримавши таким чином хендлер, ми можемо за допомогою функції DeviceIoControl зв’язуватись з драйвером та записувати чи зчитувати дані. Ця взаємодія відбувається на простому байтовому рівні без конкретизації типів, тому потрібно звертати особливу увагу на кількість переданих чи прийнятих даних, оскільки звертання поза межі переданого/прийнятого масиву особливо на стороні драйвера, де операційна система не проводить додаткового контролю, може привести до складних наслідків. Тому функція DeviceIoControl передбачає встановлення довжини буфера для передавання чи прийому даних.
Дана програма-оболонка дозволяє декількома кліками інсталювати необхідні драйвери та приступити до роботи. Так само, за бажанням користувача, можна повністю видалити з реєстру системи зареєстровану інформацію, таким чином повернувши комп’ютер у вихідний стан.


Щоб завантажити драйвер а також програму для керування ним (разом з кодом) натисніть сюди. Використання дозволяється тільки у навчальних цілях.

невиходить завантажити

незнаю як часто ти це читаєш але мені потрібна дуже ця прога з повним текстом. не екзешка а власне код. А по лінку нескачується. Якось можна її інакше скачати (інший лінк мило...)

деколи читаю :)

деколи читаю :) виправив лінк! То часом не твоє пиво мене чекає?..

те що я шукав, дякую

те що я шукав, дякую

Коментувати:

Ця інформація зберігається приватно і не буде оприлюднена.
  • Адреси веб сторінок та email адреси перетворюються в лінки автоматично.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Рядки та параграфи відокремлюються автоматично.

Детальніше про опції форматування