Nadzorowanie ruchu sieciowego w systemach Windows z
Transkrypt
Nadzorowanie ruchu sieciowego w systemach Windows z
Nadzorowanie ruchu sieciowego w systemach Windows z wykorzystaniem interfejsu WinSock 2 Miłosz Kubański Wydział Inżynierii Mechanicznej i Informatyki Kierunek Informatyka, Rok IV [email protected] Streszczenie W poniższej pracy pokazano sposób przechwytywania oraz modyfikowania danych przesyłanych przy użyciu "gniazd" w systemie Windows. Jako przykład zastosowania omawianej technologii podczas prezentacji przedstawiony zostanie system filtrujacy ˛ dane przesyłane za pośrednictwem protokołu HTTP (strony WWW). Program posiada również funkcj˛e blokujac ˛ a˛ niepożadane ˛ połaczenia ˛ sieciowe (firewall). 1 Wst˛ep W dzisiejszych czasach szybki i bezproblemowy przepływ informacji odgrywa kluczowe znaczenie. Codziennie komputery wymieniaja˛ mi˛edzy soba˛ ogromne porcje informacji poprzez różnego rodzaju media transmisyjne. W sieci kraż ˛ a˛ liczne wirusy obciażaj ˛ ace ˛ ła˛ cza oraz umożliwiajace ˛ wykradane tak cennych w dzisiejszych czasach informacji. Dlatego tak istotne staje si˛e zagwarantowanie jakości usług oraz niezawodności połaczeń. ˛ Aby chronić si˛e przed utrata˛ informacji, oraz licznymi wirusami komputerowymi instalowane sa˛ liczne programy filtrujace ˛ połaczenia ˛ sieciowe. W poniższej pracy zostanie przedstawiona technologia pozwalajaca ˛ na tworzenie aplikacji nadzorujacych ˛ ruch sieciowy danego komputera. Do takich programów możemy zaliczyć zapory sieciowe, oraz różnego rodzaju filtry treści. 2 Wprowadzenie do sieci komputerowych 2.1 Model ISO-OSI Aby połaczenie ˛ pomi˛edzy dwoma programami aplikacyjnymi znajdujacymi ˛ si˛e na różnych komputerach o odmiennej konfiguracji sprz˛etowej było możliwe zaistniała potrzeba stworzenia standardu opisujacego ˛ przepływ informacji. Ogólnie przyj˛etym modelem sieci jest model warstwowy ISO-OSI. W modelu tym wyodr˛ebnia si˛e pewne niezależne zadania, które moga˛ być rozwiazywane ˛ przez wydzielone układy sprz˛etowe lub pakiety oprogramowania zwane obiektami. Klasa˛ obiektów rozwiazuj ˛ acych ˛ dane zagadnienie nazywa si˛e warstwa.˛ Poj˛ecie warstwy nie jest jednoznaczne z poj˛eciem protokołu – funkcje 1 Rys. 1: Siedmio–warstwowy model sieci ISO–OSI danej warstwy moga˛ być wykonywane przez kilka różnych protokołów. Każdy protokół komunikuje si˛e ze swoim odpowiednikiem, b˛edacym ˛ implementacja˛ tego samego protokołu w równorz˛ednej warstwie komunikacyjnej systemu odległego. Warstwy (a dokładnie konkretne protokoły zawarte w tej warstwie) komunikuja˛ si˛e bezpośrednio z odpowiadaja˛ cymi im warstwami w odległym hoście. Należy wi˛ec też zapewnić reguły przekazywania informacji w dół do kolejnych warstw pracujacych ˛ na danym komputerze. Dane przekazywane sa˛ od wierzchołka stosu, poprzez kolejne warstwy, aż do warstwy fizycznej, która przesyła je poprzez sieć do odległego hosta. Na szczycie stosu znajduja˛ si˛e usługi świadczone bezpośrednio użytkownikowi przez aplikacje sieciowe, na spodzie – sprz˛et realizujacy ˛ transmisj˛e sygnałów niosacych ˛ informacje[8]. Rysunek 1 przedstawia ogólny schemat modelu ISO-OSI. 2.2 Model protokołu TCP/IP Protokół tworzacy ˛ Internet – TCP/IP – również możemy opisać za pomoca˛ siedmio–warstwowego modelu ISO/OSI. Lepiej jednak oddaje funkcje i właściwości protokołu TCP/IP uproszczony model cztero–warstwowy. Jak można zauważyć na rysunku 2, w modelu tym najważniejsze sa˛ warstwy sieciowa i transportowa, pozostałe sa˛ połaczone ˛ i tworza˛ dwie warstwy zwane warstwa˛ dost˛epu do sieci oraz warstwa˛ aplikacji. Funkcje tych warstw pokrywaja˛ si˛e z zadaniami odpowiadajacych ˛ im warstw w modelu ISO/OSI. [5] Podobnie jak w modelu OSI kolejne warstwy dołaczaj ˛ a˛ (badź ˛ usuwaja,˛ w zależności w która˛ stron˛e przesuwaja˛ si˛e dane na stosie protokołów) własne nagłówki. Taki proces nazywa si˛e enkapsulacja˛ danych (Rys. 3). 2 Rys. 2: Czterowarstwowy model przedstawiajacy ˛ rodzin˛e protokołów TCP/IP Rys. 3: Przykład enkapsulacji danych protokołów rodziny TCP/IP 3 "Gniazda" Oprogramowanie protokołów TCP/IP w wi˛ekszości implementacji jest wbudowane w system operacyjny danego komputera. Tak wi˛ec, aby skorzystać z usług tych protokołów, program aplikacyjny musi wywoływać funkcje systemowe. Protokoły TCP/IP zaprojektowano tak, aby mogły działać na różnych systemach komputerowych, pochodzacych ˛ od różnych producentów. Tak wi˛ec, opis interfejsu pośredniczacego ˛ pomi˛edzy protokołami TCP/IP, a korzystajacymi ˛ z nich programami aplikacyjnymi ma postać tzw. specyfikacji luźnej (ang. loosely specyfied interface). W praktyce powstało tylko kilka realizacji interfejsu do oprogramowania TCP/IP. W Uniwersytecie Kalifornijskim w Berkeley opracowano definicj˛e interfejsu przeznaczonego do systemu Berkeley Unix. Jest on znany jako interfejs gniazd lub interfejs gniazdowy (ang. sockets interface lub sockets). Z kolei firma AT&T zdefiniowała interfejs dla Systemu V Unixa. Jest on określany skrótem TLI (ang. Transport Layer Interface - interfejs warstwy transportowej). Powstało jeszcze kilka innych definicji interfejsu, ale jak dotych- 3 czas żadna z nich nie uzyskała szerszej akceptacji. 3.1 Gniazda "berkleyowskie" Na poczatku ˛ lat osiemdziesiatych ˛ Advanced Research Project Agency (ARPA) sponsorowała prac˛e zespołu specjalistów na Uniwersytecie Kalifornijskim w Berkeley, który to zespół podjał ˛ si˛e zadania wbudowania oprogramowania TCP/IP w środowisko systemu UNIX, z założeniem udost˛epnienia opracowanego oprogramowania innym ośrodkom. Cz˛eścia˛ tej pracy było zaprojektowanie interfejsu komunikacyjnego dla programów użytkowych. Projektanci zdecydowali si˛e użyć istniejacych ˛ uniksowych funkcji wsz˛edzie tam, gdzie było to możliwe. Nowe funkcje wprowadzono tylko dla tych operacji wykonywanych przez TCP/IP, których wywołania trudno byłoby zrealizować w ramach istniejacego ˛ repertuaru. W rezultacie powstał interfejs gniazd (ang. socket interface), natomiast system operacyjny stał si˛e znany pod nazwa˛ Berkeley Unix lub BSD UNIX. Berkeley UNIX przyj˛eto jako system operacyjny w wielu komputerach, zwłaszcza dla stacji roboczych produkowanych przez takie firmy jak Sun Microsystems Incorporated, Tektronix Incorporated czy Digital Equipment Corporation. Przyczyniło si˛e to do rozpowszechnienia interfejsu gniazdkowego. Jest on tak szeroko stosowany, że stał si˛e de facto standardem.[4]. 4 WinSock Opracowany w Berkeley interfejs gniazd został zaadaptowany do systemu Windows pod nazwa˛ WinSock (Windows Socket). Obejmuje on zestaw funkcji ogólnego zastosowania, umożliwiajacych ˛ korzystanie z wielu różnych protokołów komunikacyjnych, przy czym interfejs, z którego korzystaja˛ aplikacje nie jest zależny od protokołu, którym chca˛ si˛e porozumiewać. Protokoły dostarczane sa˛ na zasadzie usług, udost˛epniajacych ˛ ujednolicony interfejs. W wywołaniach funkcji programista podaje jedynie typ usługi, z której chce skorzystać (nie podaje dokładnej nazwy protokołu). Dzi˛eki takiemu podejściu wszystkie mechanizmy warstw poniżej warstwy aplikacji (model OSI) sa˛ maskowane przed aplikacja,˛ która korzysta z gniazd w podobny sposób jak ze strumieni danych. Ogólna˛ hierarchi˛e warstw biblioteki WinSock 2.0 przedstawia Rys. 4 4.1 Powstanie WinSock W 1993 roku powstała biblioteka WinSock (wersja 1.1). Bardzo szybko stała si˛e ona standardem aplikacji działajacych ˛ w systemach operacyjnych firmy Microsoft, wypierajac ˛ inne nieustandaryzowane rozwiazania. ˛ Niestety miała ona sporo ograniczeń. Jednym z nich była możliwość obsługi tylko jednej rodziny protokołów: "TCP/IP". W momencie pojawienia si˛e wersji oznaczonej jako 2.0 sytuacja uległa znacznej poprawie. Umożliwiono bowiem korzystanie z protokołów innych rodzin niż TCP/IP, gniazd w trybie nie blokujacym. ˛ Wprowadzono również kontrol˛e jakości połaczenia ˛ (ang. Quality of Service), współdzielenia "socketów" i wiele innych możliwości. Interfejs dostarczony w tej wersji był już bardzo zbliżony do ideologii interfejsu gniazd z systemu BSD UNIX. 4 4.2 SPI (Service Provider Interface) Jedna˛ z najwi˛ekszych wad WinSock 1.1 było ograniczenie możliwości korzystania z protokołów tylko do rodziny TCP/IP. Twórcy tego interfejsu poszli o duży krok do przodu przygotowujac ˛ WinSock 2.0. Udost˛epniono bowiem obsług˛e protokołów innych rodzin niż TCP/IP, dołaczaj ˛ ac ˛ nowy interfejs zarzadzaj ˛ acy ˛ usługami zainstalowanymi w systemie Windows nazwany SPI (Service Provider Interface). 4.3 LSP (Layered Service Provider) WinSock 2 pozwala tworzyć dwa typy usług: transportowe (ang. transport service providers), do której zaliczamy protokoły transportowe np. TCP/IP oraz przestrzeni nazw (ang. namespace resolution service providers) czyli usługi zwiazane ˛ z tłumaczeniem adresów sieciowych na nazwy przyjazne dla człowieka np. DNS). W ramach usług transportowych można wyróżnić dwie grupy dostawców: podstawowe zaliczane do warstwy transportowej i sieciowej (ang. Base Service Provider) oraz rozszerzajace ˛ (ang. Layered Service Provider) znajdujacy ˛ si˛e w warstwie sesji. Usługi typu podstawowego zawieraja˛ szczegóły protokołu komunikacyjnego takie jak ustanawianie połaczenia, ˛ transfer danych, czy też obsługa bł˛edów. Drugi typ usługi transportowej zawiera tylko wybrane funkcje komunikacyjne i opiera si˛e na istniejacej ˛ już w systemie usłudze komunikacyjnej typu podstawowego (odpowiedzialnej za obsług˛e połaczenia) ˛ lub innej istniejacej ˛ usłudze typu rozszerzonego. Przykładem usługi typu rozszerzonego może być usługa jakości połaczeń ˛ (QOS) w Windows 98 oraz 2000, która korzysta z protokołu TCP/IP (typ podstawowy).[1] Dostawcy usług typu przestrzeni nazw w chwili obecnej (WinSock 2.2.x) nie posiadaja˛ typu rozszerzalnego. 4.4 Stos dostawców usług Ponieważ usługi typu rozszerzonego korzystaja˛ z typów podstawowych ("leża" ˛ na usługach transportowych), musza˛ udost˛epniać interfejs identyczny dla usług podstawowych i posiadać takie same parametry co warstwa, która˛ przykrywaja.˛ W systemie operacyjnym moga˛ powstać dwie lub wi˛ecej usługi o podobnych parametrach, co powoduje problem wybrania odpowiedniego dostawcy przez aplikacj˛e. Problem ten udało si˛e rozwiazać ˛ dzi˛eki wykorzystaniu stosu dostawców usług. W wi˛ekszości przypadków podczas wybierania odpowiedniego dostawcy, aplikacja zgłasza do interfejsu WinSock żadanie ˛ udost˛epnienia gniazda usługi charakteryzujacej ˛ si˛e pewnymi cechami (np. żadanie ˛ udost˛epnienia protokołów rodziny TCP/IP). Warstwa SPI biblioteki WinSock sprawdza dost˛epne usługi przegladaj ˛ ac ˛ stos dostawców poczaw˛ szy od jego wierzchołka. Po napotkaniu usługi zgodnej z żadanymi ˛ parametrami zwraca do aplikacji deskryptor gniazda wykorzystujacego ˛ dana˛ usług˛e. Jak łatwo zauważyć w wypadku istnienia wi˛ecej niż jednej usługi o tych samych parametrach, o wyborze jednej z nich najcz˛eściej decyduje ich położenie na stosie, przy czym pierwszeństwo wyboru maja˛ usługi położone bliżej wierzchołka. 5 Rys. 4: Hierarchia warstw w bibliotece WinSock 2.0 5 Wykorzystanie LSP do nadzorowania ruchu sieciowego To właśnie dzi˛eki usługom LSP możliwe jest pisanie programów nadzorujacych ˛ ruch sieciowy na wszystkich systemach Windows, które zawieraja˛ bibliotek˛e WinSock w wersji 2.x. Jak wspomniano wcześniej usługi tego typu nie wymagaja˛ ponownej implementacji warstw sieciowych. Tak naprawd˛e usługi LSP udost˛epniaja˛ tylko interfejs zgodny ze standardowym interfejsem dostawcy usług, przekazujac ˛ obsług˛e połaczenia ˛ do dostawcy usługi którego przykrywaja.˛ [3]. Dzi˛eki wykorzystaniu ujednoliconego interfejsu funkcji aplikacja korzysta ze wszystkich usług, wykorzystujac ˛ ten sam interfejs. Usługi rozszerzajace ˛ protokoły transportowe sa˛ "przezroczyste" dla aplikacji, które z nich korzystaja,˛ dzi˛eki czemu można wymusić na aplikacji korzystanie z danego rozszerzenia usługi. W momencie wybrania przez SPI usługi rozszerzonej, wszystkie wywołania funkcji operujacych ˛ na gniazdach przekazywane sa˛ do LSP. Rozszerzony dostawca interpretuje przekazane parametry i może je przekazać dalej do dostawcy znajdujacego ˛ si˛e niżej, lub zwrócić bład. ˛ To właśnie rozwiazanie ˛ pozwala nam na pełna˛ kontrol˛e nad danymi przesyłanymi z wykorzystaniem gniazd WinSock, gdyż wszystkie funkcje oraz parametry musza˛ być zaakceptowane przez warstw˛e usługi rozszerzonej. Funkcje udost˛epniane przez API WinSock sa˛ mapowane do funkcji interfejsu SPI. Np. funkcja API "socket ()" odpowiadaja˛ ca za tworzenie gniazda w interfejsie SPI posiada nazw˛e WSPSocket(), funkcja accept() WSPAccept () itd. Jak łatwo si˛e domyśleć wszystkie funkcje udost˛epnione przez API WinSock sa˛ w podobny sposób przeciażane ˛ przez funkcje SPI. 6 Znajac ˛ interfejs API winsock możemy łatwo zaplanować implementacj˛e funkcji naszego dostawcy. Np. chcac ˛ wyposażyć nasza˛ usług˛e w funkcje zapory ogniowej (ang. firewall) interesować nas b˛eda˛ szczególnie funkcje: WSPStartup (), WSPSocket(), WSPAccept(), WSPConnect(), WSPBind () Dla programów filtrujacych ˛ funkcjami którymi powinniśmy obdarzyć dodatkowymi możliwościami moga˛ być np.: WSPSend (), WSPSendTo (), WSPRecv (), WSPRecvFrom () W funkcjach tych zawieramy szczegółowa˛ implementacj˛e nowych właściwości usługi. W wi˛ekszości pozostałych zaś metod możemy ograniczyć si˛e jedynie do przekazania funkcjonalności do dostawcy znajdujacego ˛ si˛e warstw˛e niżej. Jednakże ograniczenie si˛e wyłacznie ˛ do takich modyfikacji naszego dostawcy nie jest wystarczajace, ˛ ponieważ biblioteka WinSock w wersji 2.0 została znacznie bardziej rozszerzona w stosunku do swojego poprzednika. Aplikacje korzystajace ˛ z funkcjonalności WinSock 1.x b˛eda˛ działały poprawnie, lecz inne korzystajace ˛ w wi˛ekszym stopniu z nowych możliwości WinSock, moga˛ działać niepoprawnie, w najgorszym przypadku moga˛ si˛e "zawiesić". Jest to szczególnie ważne, gdyż wiele warstw oraz procesów systemu operacyjnego również korzysta z komunikacji wykorzystujac ˛ do tego gniazda. Jak łatwo si˛e domyśleć w łatwy sposób można doprowadzić do awarii systemu operacyjnego. 5.1 Obsługa zdarzeń Dużym udogodnieniem dla programistów jest możliwość obsługi zdarzeń sieciowych, przez programy aplikacyjne. Podczas procesu komunikacji z wykorzystaniem gniazd aplikacja może sprawdzić czy pojawiły si˛e jakieś nowe zdarzenia wywołujac ˛ funkcj˛e WSPEnumNetworkEvents() [3]. Obsługa zdarzeń w systemach Windows oparta jest na systemie komunikatów miedzy oknami. Aby nasza usługa mogła otrzymywać komunikaty od dostawcy warstwy niższej i przesyłać je do aplikacji, należy stworzyć nowe okno w kontekście wykonywanego procesu. Okno to różni si˛e od standardowych formatek używanych przez aplikacje tym, że jest ono przez cały czas ukryte i służy naszej usłudze wyłacznie ˛ w celu przechwytywania pojawiajacych ˛ si˛e zdarzeń sieciowych, które moga˛ zostać zinterpretowane i przesłane do aplikacji korzystajacej ˛ z danego gniazda. 6 Podsumowanie Zaadaptowanie rozwiazania ˛ powstałego na Uniwersytecie w Berkeley do systemów rodziny Windows bardzo uprościło proces tworzenia aplikacji sieciowych. Istotnymi właściwościami tego interfejsu sa: ˛ • wykorzystanie tych samych funkcji obsługujacych ˛ gniazda niezależnie od wykorzystywanego protokołu transportowego, 7 • swoboda dodawania, oraz rozszerzania usług, "przezroczystość" (ang. transparency) usług rozszerzajacych ˛ podstawowe • funkcje protokołów transportowych, • obsługa zdarzeń sieciowych. Najistotniejsza˛ właściwościa˛ z punktu widzenia naszej pracy jest możliwość dodawania nowych rozszerzeń na istniejace ˛ już usługi transportowe. Mechanizm ten daje nam prawie nieograniczone możliwości nadzorowania ruchu sieciowego. Dzi˛eki temu rozwia˛ zaniu można w łatwy sposób tworzyć "przezroczyste" zapory sieciowe, programy filtrujace, ˛ usługi QOS, kryptograficzne i wiele innych. Niestety jak wiele innych technologii, również ta może być wykorzystana do celów przest˛epczych. Bardzo cz˛esto programy podsłuchujace ˛ (ang. sniffer), oraz konie trojańskie wykorzystuja˛ ta˛ technik˛e do podsłuchiwania ruchu sieciowego komputera w celu przechwycenia poufnych danych. Do wad mechanizmu LSP można również dodać zwi˛ekszenie wykorzystania mocy obliczeniowej procesora, oraz pami˛eci operacyjnej przez system operacyjny. Niemniej jednak w czasach komputerów dysponujacych ˛ tak dużymi mocami obliczeniowymi, oraz ogromnymi ilościami pami˛eci RAM, wady te w porównaniu z możliwościami jakie udost˛epnia ten mechanizm wydaja˛ si˛e nie mieć wi˛ekszego znaczenia. Literatura [1] Wei Hua, Jim Ohlund, Barry Butterklee, Unraveling the Mysteries of Writing a Winsock 2 Layered Service Provider. http://www.microsoft.com/msj/0599/layeredservice/layeredservice.aspx [2] Microsoft Developer Network (MSDN). http://msdn.microsoft.com/http://msdn.microsoft.com/ [3] Windows* Sockets 2 Service Provider Interface. http://www.ictp.trieste.it/ radionet/nuc1996/ref/winsock/wsspi22.htm [4] Douglas E. Comer, David L. Stevens, Sieci komputerowe TCP/IP tom 3 – Programowanie w trybie klient-serwer. Wersja BSD. [5] W. Richards Stevens, Gary R. Wright, Biblia TCP/IP tom 2 – Implementacje. [6] W. Richards Stevens, UNIX programowanie usług sieciowych tom 1 – API: gniazda i XTI. [7] Ian McLean, Windows 2000 TCP/IP. Czarna ksi˛ega. [8] Karol Krysiak, Sieci komputerowe. Kompendium. 8