![]() |
||
============ Как только у меня в руках появился компьютер с беспроводным сетевым адаптером меня сразу заинтересовал этот тип сетей - однако в рунете к сожалению очень мало информации на эту тему (большинство статей - откровенная вода о стандартах, ничего не конкретизирующая). Беспроводные сети пока ещё не вошли в нашу жизнь так прочно, как на капиталистическом западе, однако wardriving(этим термином обозначают поездки по округе в поисках незащищённых беспроводных сетей) у нас становится всё более распространённым. Данный туториал предстваляет собой перевод статьи Scanning for Wireless Networks By GriYo/29A, оригинал которой можно найти в 8 выпуске журнала 29A. Данная статья расчитанна на немного подготовленного читалтеля, поэтому я решил написать небольшое вступление - что бы всем была понятна терминология и сокращения, применяемые в статье. Кроме того в дополнение к статье приложенна маленькая заметка о сканировании инфракрасных сетей через функции winsock. То что сейчас принято называть термином Wi-Fi (wireless fidelity) - это семейство спецификаций IEEE 802.11, разработанные в конце 90-х годов. В стандартах 802.11 определены принципы взаимодействия устройств в беспроводной сети. Беспроводные сети состоят из ячеек (сот). Кажадя такая сота управляется станцией, называемой точкой доступа (AccessPoint, AP). Точка доступа и находящиеся в пределах радиуса ее действия рабочие станции с беспроводными адаптерами образуют базовую зону обслуживания (Basic Service Set, BSS). Точки доступа многосотовой сети взаимодействуют между собой через распределительную систему (Distribution System, DS). А всё это вместе (точки доступа и распределительная система) образует расширенную зону обслуживания (Extended Service Set). Так же для обеспечения перехода между сотами предусмотренны механизмы сканирования (активного и пассивного прослушивания эфира) и присоединения (Association). Кроме этого вам потребуются некоторые начальные знания о том как организованна поддержка сетей в Windows. Как все наверное догадываются, все сетевые протоколы реализуются через драйвера. Например драйвер TCP/IP (tcpip.sys) реализует стек протоколов TCP/IP (TCP, UDP, IP, ARP, ICMP и IGMP). Что бы каждый драйвер протокола не использовал отдельный интерфейс был придуман интерфейс TDI (Transport Driver Interface). Таким образом транспортный протокол, реализованный ввиде драйвера, называется транспортом TDI. Однако когда драйверу протокола необходимо отправить данные в сеть - ему надо их переслать непосредственно сетевому адаптеру. Для общения драйверов протокола и драйверов адаптеров была разработанна спецификация NDIS (Network Driver Interface Specification). Таким образом драйверы сетевых адаптеров, соответвующие NDIS называют драйверами NDIS или минипорт драйверами NDIS. Что ж на этом пожалуй всё, перейдём непосредственно к сканированию сетей: ============================================================= В настоящий момент беспроводные сети получаю всё более и более широкое распространение... Пройдя от работы до дома с включённым Kismet'ом я нашёл 235 различных сетей, большинство из которых открыто для всех. Я хочу рассказать как вы можете добавить сканирование беспроводных сетей в вашу программу без необходимости писать драйвер. Меня не волнует пишети ли вы червя, который будет распространяется через сети или просто приложение которое будет следить за вашей собственной сетью. Это ваша проблема и я не несу ответсвенности за то как вы используете эти идеи и код. Основные преимущества этого метода:
The device SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCardsТут вы найдёте информацию о каждой карте, установленной в вашей системе: Description – REG_SZСледующий код показывает как вы можете воспроизвести список адаптеров, установленных в системе: ---------------------------------------------------------------------- BOOL get_device_info( int Index, char *key_name, char *device_info, char *device_description) { HKEY hkey ; DWORD size ; DWORD type ; BOOL retval ; retval = FALSE ; memset( device_info, 0, SIZEOF_DEVICE_NAME) ; if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &hkey) == ERROR_SUCCESS) { type = REG_SZ ; size = SIZEOF_DEVICE_NAME ; if( RegQueryValueEx( hkey, "ServiceName", NULL, &type, ( BYTE *) device_info, &size) == ERROR_SUCCESS) { type = REG_SZ ; size = SIZEOF_DEVICE_NAME ; if( RegQueryValueEx( hkey, "Description", NULL, &type, ( BYTE *) device_description, &size) == ERROR_SUCCESS) { retval = TRUE ; } } RegCloseKey( hkey) ; } return retval ; } BOOL list_devices( void) { char key_name[ SIZEOF_DEVICE_NAME] ; char full_name[ SIZEOF_DEVICE_NAME] ; char device_info[ SIZEOF_DEVICE_NAME] ; char device_description[ SIZEOF_DEVICE_NAME] ; FILETIME file_time ; HKEY hkey ; int index ; DWORD size ; index = 0 ; if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards", 0, KEY_READ, &hkey) == ERROR_SUCCESS) { size = SIZEOF_DEVICE_NAME ; while( RegEnumKeyEx( hkey, index, key_name, &size, NULL, NULL, NULL, &file_time) == ERROR_SUCCESS) { sprintf( full_name, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\%s", key_name) ; get_device_info( index, full_name, device_info, device_description) ; printf( "Index= %d\nName= %s\nDesc=%s\nKey=%s\n\n", index + 1, device_info, device_description, full_name) ; index++ ; size = SIZEOF_DEVICE_NAME ; } RegCloseKey( hkey) ; } if( index == 0) { printf( "No devices found\n\n") ; } return TRUE ; } ---------------------------------------------------------------------- Open the device Используя значение ServiceName необходимо вызвать CreateFile что бы открыть адаптер для доступа к его возможностям. Следующая функция на входе принимет значение ServiceName и открывает устройство: ---------------------------------------------------------------------- void scan( char *device_name) { HANDLE hdevice ; char device_file[ SIZEOF_DEVICE_NAME] ; sprintf( device_file, "\\\\.\\%s", device_name) ; hdevice = CreateFile( device_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL) ; if( hdevice == INVALID_HANDLE_VALUE) { printf( "Error: Device not available\n\n") ; } else { ... } CloseHandle( hdevice) ; } ----------------------------------------------------------------------Учтите что мы должны сделать имя устройства пригодным для CreateFile и преобразовать его в такой формат: \\.\deviceThe IOCTL and its OID’s ======================= А вот и главный трюк. Мы будем использовать DeviceIoControl что бы заставить наш адаптер искать доступные сети. После, используя второй вызов DeviceIoControl, мы получим буффер с результатами сканирования. Для достижения нашей цели будем использовать IOCTL_NDIS_QUERY_GLOBAL_STATS. IOCTL(I/O control code) изначально предназначался для того, что бы Win32 программы имели ограниченный доступ к NDIS драйверу, без необходимости поддержки протокола NDIS драйвера. Windows NT 4.0 DDK включает пример - MACADDR - в котором продемонстрированно использование IOCTL. Этот пример показывает, как используя DeviceIoControl можно получить доступ к NDIS MAC драйверу, через IOCTL_NDIS_QUERY_GLOBAL_STATS. Для этого IOCTL имеются различные OID (object identifiers), которые могут быть нам интересны. Следующий список извлечён из файла NtDDNdis.h, входящего в DDK: ---------------------------------------------------------------------- // // IEEE 802.11 OIDs // #define OID_802_11_BSSID 0x0D010101 #define OID_802_11_SSID 0x0D010102 #define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0D010203 #define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 #define OID_802_11_TX_POWER_LEVEL 0x0D010205 #define OID_802_11_RSSI 0x0D010206 #define OID_802_11_RSSI_TRIGGER 0x0D010207 #define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 #define OID_802_11_FRAGMENTATION_THRESHOLD 0x0D010209 #define OID_802_11_RTS_THRESHOLD 0x0D01020A #define OID_802_11_NUMBER_OF_ANTENNAS 0x0D01020B #define OID_802_11_RX_ANTENNA_SELECTED 0x0D01020C #define OID_802_11_TX_ANTENNA_SELECTED 0x0D01020D #define OID_802_11_SUPPORTED_RATES 0x0D01020E #define OID_802_11_DESIRED_RATES 0x0D010210 #define OID_802_11_CONFIGURATION 0x0D010211 #define OID_802_11_STATISTICS 0x0D020212 #define OID_802_11_ADD_WEP 0x0D010113 #define OID_802_11_REMOVE_WEP 0x0D010114 #define OID_802_11_DISASSOCIATE 0x0D010115 #define OID_802_11_POWER_MODE 0x0D010216 #define OID_802_11_BSSID_LIST 0x0D010217 #define OID_802_11_AUTHENTICATION_MODE 0x0D010118 #define OID_802_11_PRIVACY_FILTER 0x0D010119 #define OID_802_11_BSSID_LIST_SCAN 0x0D01011A #define OID_802_11_WEP_STATUS 0x0D01011B #define OID_802_11_RELOAD_DEFAULTS 0x0D01011C ----------------------------------------------------------------------Как можно заметить - эти OID всё что нужно, что бы написать программы, способные искать беспроводные сети и отображать информацию о них. Код ниже показывает как использовать IOCTL_NDIS_QUERY_GLOBAL_STATS совместно с OID_802_11_BSSID_LIST_SCAN и OID_802_11_BSSID_LIST, что бы получить список активных беспроводных сетей: ---------------------------------------------------------------------- ULONG oidcode ; ULONG bytesreturned ; NDIS_802_11_BSSID_LIST *pBSSIDList ; pBSSIDList = ( NDIS_802_11_BSSID_LIST *) VirtualAlloc( NULL, sizeof( NDIS_802_11_BSSID_LIST) * NUMBEROF_BSSIDS, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) ; if( pBSSIDList == NULL) { // Error: Unable to allocate memory for the list } else { memset( pBSSIDList, 0, sizeof( NDIS_802_11_BSSID_LIST) * NUMBEROF_BSSIDS) ; oidcode = OID_802_11_BSSID_LIST_SCAN ; DeviceIoControl( hdevice, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oidcode, sizeof( oidcode), ( ULONG *) NULL, 0, &bytesreturned, NULL) ; Sleep( 2000) ; memset( pBSSIDList, 0, sizeof( NDIS_802_11_BSSID_LIST) * NUMBEROF_BSSIDS) ; oidcode = OID_802_11_BSSID_LIST ; if( DeviceIoControl( hdevice, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oidcode, sizeof( oidcode), ( ULONG *) pBSSIDList, sizeof( NDIS_802_11_BSSID_LIST) * NUMBEROF_BSSIDS, &bytesreturned, NULL) == 0) { // List failed } else { ... } ---------------------------------------------------------------------->Из документации OID_802_11_BSSID_LIST_SCAN (взято из DDK): Для OID_802_11_BSSID_LIST_SCAN OID необходим минипорт драйвер для 802.11 NIC для обзора BSS. С этим OID не связываются никакие данные. NIC использует следующие параметры, установленные в спецификации 802.11, в своих запросах:
NIC должен минимизировать время ответа для OID. Активный тип сканирования является предпочитаемым, когда это возможно. База данных NIC включает BSSID для всех BSS отвечающих на частоте, которая выделенна для данного региона. Учтите что если NIC проассоциирован с индивидуальными BSSID и SSID, которые не содержаться в списке BSSID после сканирования, описание BSSID и SSID должны быть добавленны в список BSSID в базе данных NIC. Учтите что этот OID может вызываться очень часто (например каждые 5 секунд). Драйвер минипорта должен минимизировать время на обслуживания этого OID. Запрос этого OID не должен стать причиной, по которой NIC проассоциируется с другой точкой доступа. И ещё из документации на OID_802_11_BSSID_LIST (опять же вырезки из DDK): OID_802_11_BSSID_LIST OID запрашивает у драйвера минипорта список, содержащий все BSSID и их аттрибуты из 801.11 NIC базыданных. Этот список содержит все BSS, которые NIC определила в течении исследования(осмотра) BSS. На этот OID драйвер минипорта должен отвечать немедленно. Учтите, что если этот OID вызывается когда NIC активен, без запроса OID_802_11_BSSID_LIST_SCAN, он может вернуть список BSSID, ограниченный только ID включенными в текущую конфигурацию NIC. Однако, если этот OID вызывается по крайней мере через 6 секунд после OID_802_11_BSSID_LIST_SCAN, список BSSID должен содержать все BSSID, найденные во время OID_802_11_BSSID_LIST_SCAN. Этот OID использует структуру NDIS_802_11_BSSID_LIST, которая определяется таким образом: ---------------------------------------------------------------------- typedef_struct _NDIS_802_11_BSSID_LIST { ULONG NumberOfItems; NDIS_WLAN_BSSID Bssid[1]; } NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST; ----------------------------------------------------------------------Члены этой структуры содержат следующую информацию:
Возможно вам захочется поэкспериментировать, используя другие OID... Кроме описанных сущестувую не менее полезные, указывающие статистическую информацию, данные о шифровании и многое, многое другое ... Using wireless networks for viral attacks Этот тип вирусов должен распространяться быстро для того что бы иметь шанс. Этот вирус должен поразить большинство целей в короткий период времени, прежде чем против него предпринят какие-либо меры противодействия (обновят программы или исправят уязвимости) С другой стороны это может вызвать замедление сети, кучу подозрительной активности и прочее.. А теперь только представьте себе вирус, который распространяется, используя ошибки в середе менее защищённой чем интеренет: через локальные сети. Такой вирус может путешествовать от сети к сети при помощи ноутбуков например. Такой вирус может медленно переползать из одного LAN'a в другой, без каких либо заметных эффектов. ============================================================= В сетях, состоящих из устройств инфракрасной связи (их называют IrDA устройствами - Infrared Data Association), большинство компьютеров мобильны - и могут перетекать из зоны видимости одного устройства в зону другого. Поэттому традиционные механизмы здесь не уместны. Так что для интеграции IrDA в WinSock ввели специальную структуры, аналогичную sockaddr:
Поле irdaAddressFamily - всегда должно принимать значение AF_IRDA, irdaDeviceID
- эта строка уникально идентифицирующая устройство и irdaServiceName - это
имя службы, которую вы регистрируете или к которой пытаетесь подкдлючиться.
По аналогии с TCP/IP - irdaDeviceID и irdaServiceName - можно сопоставить
с парой IP адресс:порт.
Теперь рассмотрим реализацию метода перечисления всех устройств в зоне видимости адаптера (здесь и появляется разница - заголовочный файл Af_irda.h для WinCE и "нормальных" Win содержит разные определения структур). Для нумерации всех устройств используется функция - getsockopt с параметром optname=IRLMP_ENUM_DEVICES и структурой DEVICELIST как optval. Данная структура определяется так:
Следующий код перечислит все IrDA устройства, находящиеся в зоне видимости:
SOCKADDR_IRDA irAddr = {AF_IRDA, 0, 0, 0, 0, "\0"}; WINDOWS_DEVICELIST devList; SOCKET sock; DWORD dwRetries = 0, dwListLen = sizeof(WINDOWS_DEVICELIST); DWORD i; // Создаём IrDA сокет: sock = WSASocket(AF_IRDA, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); // Получаем список устройств в зоне видимости: devList.numDevice = 0; while ((devList.numDevice == 0) && (dwRetries <= MAX_RETRIES)){ dwRet = getsockopt(sock, SOL_IRLMP, IRLMP_ENUMDEVICES, (char *)&devList, &dwListLen); dwRetries++; Sleep(1000); } // Распечатываем полученную инфу: for (i = 0; i < devList.numDevice; i++){ printf("Device: %d\n", i); printf("\tDevice ID: %x%x%x%x\n", devList.Device[i].irdaDeviceID[0], devList.Device[i].irdaDeviceID[1], devList.Device[i].irdaDeviceID[2], devList.Device[i].irdaDeviceID[3]); printf("\tDevice Name: %s\n", devList.Device[i].irdaDeviceName); } closesocket(sock);Перед вызовом getsockopt необходимо присвоить numDevice значение равное 0, после вызова в этом поле будет содержаться число структур IRDA_DEVICE_INFO в поле Device. Outro
|
||
![]() ![]() ![]() ![]() |
||
Автор:
said /7.02.05/ © Mazafaka.Ru - E-Zine - 2005 © |