2

我正在使用 netlink 库 nl80211.h 扫描 wifi 网络并成功获取 ssid、mac 地址、状态、频率和信号。我想使用相同的库添加每个网络的安全类型。我使用 NL80211_BSS_CAPABILITY 作为枚举之一,它给出了一个整数,我将其硬编码到我的代码中以确保安全。这似乎很乏味,并且必须使用这种方法提供大量数据(整数值)。获得 WPA/WPA2 很好,但是当开放网络出现时代码会失败。以下是我迄今为止使用的值。一个更好的逻辑可以让我打开网络(ESS 或 WEP),最好类似于 wpa_supplicant 和 netlink 库。

int keynum;
char *keytype;
keynum = nla_get_u32(bss[NL80211_BSS_CAPABILITY]);

if(keynum==5153 || keynum == 34)
    keytype="NONE";

else if(keynum==5169 || keynum == 1297 || keynum==1073|| keynum == 5393)
    keytype="WPA2";

else if (keynum == 1041)
    keytype="WPA WPA2";

else
    keytype="WPA WPA2";
4

1 回答 1

1

首先,我们来看看是什么数据,NL80211_BSS_CAPABILITY
要了解这个,我先提请大家注意 propertyNL80211_BSS_BEACON_IES
这个字段的描述如下:

/**
* @NL80211_BSS_BEACON_IES: binary attribute containing the raw
* information
*/

来源
但是我认为这样的描述太少了,为了更详细的描述,我们转向这里
首先,我们感兴趣的是:

  1. 能力信息(2 字节) 该字段包含用于指示请求或通告的可选能力的子字段的数量。

以使用wireshark及其Сapabilities Information字段捕获的数据包之一为例(有关如何执行此操作的好文章是here):

С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)这些将是WPA2WPA1分别

第二:

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 kernel 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;
    }
}

最后一点是“group”“attr”的属性。与“组”属性“bss”不同,它们适用于 wiphy结构相关信息。这里还有一个如何使用它们的示例:repo source file Enum values for security keys:
linblnetlink


/**
 * 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 编辑:
我还不能说什么。我的搜索从这个页面开始,并继续通过有链接的页面。
nmcli可能不支持WPA 3自上次提交以来,从存储库来看,是 9 年前(如果我没记错的话,它是从两年前出现的标准WPA 3中引入的)。 如果您有一个带加密的接入点,可以使用命令轻松检查。与 不同的是,repo 中的最后一次提交是相对较新的,因此,它可能已经在处理我们的案例。 另外,我不能说来自with的数据包的内容802.11ax
WPA 3nmcli dev wifinmcliiw
wiresharkWPA 3加密,因为我没有必要的访问点,因此我没有测试它。

于 2021-03-25T15:38:36.863 回答