首先,我们来看看是什么数据,NL80211_BSS_CAPABILITY
要了解这个,我先提请大家注意 propertyNL80211_BSS_BEACON_IES
这个字段的描述如下:
/**
* @NL80211_BSS_BEACON_IES: binary attribute containing the raw
* information
*/
来源
但是我认为这样的描述太少了,为了更详细的描述,我们转向这里。
首先,我们感兴趣的是:
- 能力信息(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)
这些将是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 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:
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 编辑:
我还不能说什么。我的搜索从这个页面开始,并继续通过有链接的页面。
nmcli
可能不支持WPA 3
自上次提交以来,从存储库来看,是 9 年前(如果我没记错的话,它是从两年前出现的标准WPA 3
中引入的)。
如果您有一个带加密的接入点,可以使用命令轻松检查。与 不同的是,repo 中的最后一次提交是相对较新的,因此,它可能已经在处理我们的案例。
另外,我不能说来自with的数据包的内容802.11ax
WPA 3
nmcli dev wifi
nmcli
iw
wireshark
WPA 3
加密,因为我没有必要的访问点,因此我没有测试它。