Во-первых, давайте посмотрим, какие данные находятся в NL80211_BSS_CAPABILITY
Чтобы понять это, я сначала обращу ваше внимание на свойство NL80211_BSS_BEACON_IES
Описание этого поля выглядит следующим образом:
/**
* @NL80211_BSS_BEACON_IES: binary attribute containing the raw
* information
*/
источник
Но я считаем такое описание слишком скудным, за более подробным описанием переходим здесь.
Для начала нас интересует:
- Информация о возможностях (2 байта) Это поле содержит количество подполей, которые используются для указания запрошенных или объявленных дополнительных возможностей.
Возьмем, к примеру, один из пакетов, захваченных с помощью wireshark, и его поле Сapabilities Information
(хорошая статья о том, как это сделать, — здесь):
Сapabilities Information: 0x0431
.... .... .... ...1 = ESS capabilities: Transmitter is an AP
.... .... .... ..0. = IBSS status: Transmitter belongs to a BSS
.... ..0. .... 00.. = CFP participation capabilities: No point coordinator at AP (0x00)
.... .... ...1 .... = Privacy: AP/STA can support WEP
.... .... ..1. .... = Short Preamble: Allowed
.... .... .0.. .... = PBCC: Not Allowed
.... .... 0... .... = Channel Agility: Not in use
.... ...0 .... .... = Spectrum Management: Not Implemented
.... .1.. .... .... = Short Slot Time: In use
.... 0... .... .... = Automatic Power Save Delivery: Not Implemented
...0 .... .... .... = Radio Measurement: Not Implemented
..0. .... .... .... = DSSS-OFDM: Not Allowed
.0.. .... .... .... = Delayed Block Ack: Not Implemented
0... .... .... .... = Immediate Block Ack: Not Implemented
Как мы видим, один из флагов (под общим именем security
или Privacy: AP/STA can support WEP
, как в данном случае). Этот флаг, как написано, говорит нам, что эта сеть поддерживает шифрование wep. Но другие флаги этого тега не несут информации о других алгоритмах кодирования, используемых в сети. Поэтому впоследствии этот анализ этого поля превратится в:
if (bss[NL80211_BSS_CAPABILITY] != NULL) {
wlan_info.bss_capability = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
}
if (!(wlan_info.bss_wpa1_wpa2 | wlan_info.bss_wpa2 | wlan_info.bss_wpa1)) {
wlan_info.bss_wep = wlan_info.bss_capability & 16;
}
Но это еще не конец. Нам еще нужно найти информацию о других алгоритмах шифрования.
Для этого возвращаемся к NL80211_BSS_BEACON_IES
.
1.Проверяем, не пусто ли оно.
if (NULL != bss[NL80211_BSS_BEACON_IES] && NULL != nla_data(bss[NL80211_BSS_BEACON_IES]))
2. Проходим по каждому тегу, читаем первые два байта, и, как видно из статьи выше, таким образом узнаем тип тега и длину данных, которые в нем содержатся.
for (int i = 0;;) {
bool first = i;
uint8_t header_type =
*(uint8_t *)((nla_data(bss[NL80211_BSS_BEACON_IES])) + i++);
uint8_t header_len =
*(uint8_t *)((nla_data(bss[NL80211_BSS_BEACON_IES])) + i++);
i += header_len;
3.Среди всех тегов ищем 2 конкретных: # 48 (0x30)
или # 221 (0xDD)
.Они могут выглядеть так:
Первый:
Tag: RSN Information
Tag Number: RSN Information (48)
Tag length: 20
RSN Version: 1
Group Cipher Suite: 00:0f:ac (Ieee 802.11) AES (CCM)
Group Cipher Suite OUI: 00:0f:ac (Ieee 802.11)
Group Cipher Suite type: AES (CCM) (4)
Pairwise Cipher Suite Count: 1
Pairwise Cipher Suite List 00:0f:ac (Ieee 802.11) AES (CCM)
Pairwise Cipher Suite: 00:0f:ac (Ieee 802.11) AES (CCM)
Pairwise Cipher Suite OUI: 00:0f:ac (Ieee 802.11)
Pairwise Cipher Suite type: AES (CCM) (4)
Auth Key Management (AKM) Suite Count: 1
Auth Key Management (AKM) List 00:0f:ac (Ieee 802.11) PSK
Auth Key Management (AKM) Suite: 00:0f:ac (Ieee 802.11) PSK
Auth Key Management (AKM) OUI: 00:0f:ac (Ieee 802.11)
Auth Key Management (AKM) type: PSK (2)
RSN Capabilities: 0x0000
в информационном теге RSN нас интересуют 2 поля (будущие 4 байта): Auth Key Management (AKM) OUI: 00: 0f: ac (Ieee 802.11)
и Auth Key Management (AKM) type: PSK (2)
.
в зависимости от (AKM) type: PSK (2)
или (AKM) type: WPA (1)
это будет WPA2
или WPA1
соответственно
Второй:
Tag: Vendor Specific: Microsoft Corp.: WPA Information Element
Tag Number: Vendor Specific (221)
Tag length: 22
OUI: 00:50:f2 (Microsoft Corp.)
Vendor Specific OUI Type: 1
Type: WPA Information Element (0x01)
WPA Version: 1
Multicast Cipher Suite: 00:50:f2 (Microsoft Corp.) AES (CCM)
Multicast Cipher Suite OUI: 00:50:f2 (Microsoft Corp.)
Multicast Cipher Suite type: AES (CCM) (4)
Unicast Cipher Suite Count: 1
Unicast Cipher Suite List 00:50:f2 (Microsoft Corp.) AES (CCM)
Unicast Cipher Suite: 00:50:f2 (Microsoft Corp.) AES (CCM)
Unicast Cipher Suite OUI: 00:50:f2 (Microsoft Corp.)
Unicast Cipher Suite type: AES (CCM) (4)
Auth Key Management (AKM) Suite Count: 1
Auth Key Management (AKM) List 00:50:f2 (Microsoft Corp.) PSK
Auth Key Management (AKM) Suite: 00:50:f2 (Microsoft Corp.) PSK
Auth Key Management (AKM) OUI: 00:50:f2 (Microsoft Corp.)
Auth Key Management (AKM) type: PSK (2)
Этот указывает нам на WPA1 WPA2
. Вот фрагмент, как мы можем справиться с этим.
if (header_type == VENDOR_TAG_ID) {
long long int oui = 0;
memcpy(&oui,
(uint8_t *)((nla_data(bss[NL80211_BSS_BEACON_IES])) -
header_len + i),
6);
if (oui == WPA1_WPA2_BEACON) wlan_info.bss_wpa1_wpa2 = 1;
} else if (header_type == RSN_TAG_ID) {
int32_t oui = 0;
memcpy(&oui,
(uint8_t *)((nla_data(bss[NL80211_BSS_BEACON_IES])) - 6 + i), 4);
if ((oui == WPA2_BEACON_1) || (oui == WPA2_BEACON_2))
wlan_info.bss_wpa2 = 1;
else if (oui == WPA1_BEACON)
wlan_info.bss_wpa1 = 1;
}
И используемый здесь определяет:
#define RSN_TAG_ID 0x30
#define VENDOR_TAG_ID 0xdd
#define BEACON_DATA_LEN 0x100
#define BSS_SSID_LEN BEACON_DATA_LEN
#define WPA1_BEACON 0x1AC0F00
#define WPA2_BEACON_1 0x2AC0F00
#define WPA2_BEACON_2 0x4AC0F00
#define WPA1_WPA2_BEACON 0x101F25000
Еще одним интересным моментом является ядро iw. impl
Посмотрите здесь Это уже готовая функция, но я не изучал, как она работает.
void print_ies(unsigned char *ie, int ielen, bool unknown,
enum print_ie_type ptype)
{
struct print_ies_data ie_buffer = {
.ie = ie,
.ielen = ielen };
if (ie == NULL || ielen < 0)
return;
while (ielen >= 2 && ielen - 2 >= ie[1]) {
if (ie[0] < ARRAY_SIZE(ieprinters) &&
ieprinters[ie[0]].name &&
ieprinters[ie[0]].flags & BIT(ptype)) {
print_ie(&ieprinters[ie[0]],
ie[0], ie[1], ie + 2, &ie_buffer);
} else if (ie[0] == 221 /* vendor */) {
print_vendor(ie[1], ie + 2, unknown, ptype);
} else if (ie[0] == 255 /* extension */) {
print_extension(ie[1], ie + 2, unknown, ptype);
} else if (unknown) {
int i;
printf("\tUnknown IE (%d):", ie[0]);
for (i=0; i<ie[1]; i++)
printf(" %.2x", ie[2+i]);
printf("\n");
}
ielen -= ie[1] + 2;
ie += ie[1] + 2;
}
}
И последний пункт — это атрибуты группы attr. В отличие от групповых атрибутов bss, они применяются к wiphy структурам
Я не достаточно изучил это, чтобы понять, как сетевой менеджер извлекает из него необходимую информацию о сетях, но вы можете попробовать посмотреть linbl
и netlink
источники, и, вероятно, информация об этом будет. Также вот один пример их использования:
репозиторий
исходный файл
Значения перечисления для ключей безопасности:
/**
* NMDeviceWifiCapabilities:
* @NM_WIFI_DEVICE_CAP_NONE: device has no encryption/authentication capabilities
* @NM_WIFI_DEVICE_CAP_CIPHER_WEP40: device supports 40/64-bit WEP encryption
* @NM_WIFI_DEVICE_CAP_CIPHER_WEP104: device supports 104/128-bit WEP encryption
* @NM_WIFI_DEVICE_CAP_CIPHER_TKIP: device supports TKIP encryption
* @NM_WIFI_DEVICE_CAP_CIPHER_CCMP: device supports AES/CCMP encryption
* @NM_WIFI_DEVICE_CAP_WPA: device supports WPA1 authentication
* @NM_WIFI_DEVICE_CAP_RSN: device supports WPA2/RSN authentication
* @NM_WIFI_DEVICE_CAP_AP: device supports Access Point mode
*
* 802.11 specific device encryption and authentication capabilities.
**/
typedef enum {
NM_WIFI_DEVICE_CAP_NONE = 0x00000000,
NM_WIFI_DEVICE_CAP_CIPHER_WEP40 = 0x00000001,
NM_WIFI_DEVICE_CAP_CIPHER_WEP104 = 0x00000002,
NM_WIFI_DEVICE_CAP_CIPHER_TKIP = 0x00000004,
NM_WIFI_DEVICE_CAP_CIPHER_CCMP = 0x00000008,
NM_WIFI_DEVICE_CAP_WPA = 0x00000010,
NM_WIFI_DEVICE_CAP_RSN = 0x00000020,
NM_WIFI_DEVICE_CAP_AP = 0x00000040
} NMDeviceWifiCapabilities;
И способы его использования:
источник файл
if (tb[NL80211_ATTR_CIPHER_SUITES]) {
int num;
int i;
__u32 *ciphers = nla_data (tb[NL80211_ATTR_CIPHER_SUITES]);
num = nla_len (tb[NL80211_ATTR_CIPHER_SUITES]) / sizeof(__u32);
for (i = 0; i < num; i++) {
switch (ciphers[i]) {
case 0x000fac01:
info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP40;
break;
case 0x000fac05:
info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP104;
break;
case 0x000fac02:
info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_TKIP |
NM_WIFI_DEVICE_CAP_WPA;
break;
case 0x000fac04:
info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_CCMP |
NM_WIFI_DEVICE_CAP_RSN;
break;
default:
nm_log_err (LOGD_HW | LOGD_WIFI, "Don't know the meaning of NL80211_ATTR_CIPHER_SUITES %#8.8x.", ciphers[i]);
break;
}
}
}
и используемая там цепочка вызовов и обратных вызовов:
wifi_utils_init (const char *iface, int ifindex, gboolean check_scan)
^
||
wifi_nl80211_init (const char *iface, int ifindex)
^
||
static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
WPA 3 EDIT:
Пока ничего не могу сказать. Мои поиски начались с эта страница и далее по страницам, на которые есть ссылка.
nmcli
Вероятно, не поддерживает WPA 3
, так как последний коммит, судя по репозиторию, был 9 лет назад (А WPA 3
был введен from 802.11ax
стандарт, который вышел, если не ошибаюсь, всего два года назад ).
Если у вас есть точка доступа с шифрованием WPA 3
, это легко проверить с помощью команды nmcli dev wifi
. В отличие от nmcli
, последний коммит в репозитории iw
был относительно недавним и, соответственно, он может уже обрабатывать наш случай.
Также ничего не могу сказать о содержании пакетов из репозитория wireshark
с шифрованием WPA 3
, т.к. нет нужной точки доступа и соответственно не проверял.
person
plzvtl
schedule
25.03.2021