无线网络渗透2:WPA/WPA2-PSK AP-Station 关联和认证过程

前言

WiFi Protected Access 有WPA WPA2两个认证标准 是一种保护无线电脑的网络安全系统
需要用到的设备:路由器TP_Link (AP) 一个接入设备(Station) 一台电脑
初始时需要设置路由器 使用WPA/WPA2-PSK认证类型
设置加密算法 AES
设置密码 passphrase

目前网络上一些讲解和书籍过于苦涩难懂或者有错误,这里我总结并讲述我的理解

总的来讲分为两个流程:一个是AP-Station关联 另一个是认证过程

关联过程

AP发送 Beacon 广播包,指示其SSID
接下来是AP和客户端关联发送的四个 Authentication 的管理帧
(1)客户端收到 Becon包后,发送认证请求
(2)AP响应认证请求
(3)客户端发送关联请求包
(4)AP响应关联请求
至此,客户端和AP建立了关联。 接下来是四次握手过程以建立连接
这里使用的是的协议是EAPOL

基于EAPOL协议的报文

下图显示了数据包的各个字段

下图来自于《Kali Linux 无线网络渗透详解》- 李亚伟
讲解了各个字段的含义

其中在四次握手过程中比较重要的字段有:

MIC(Message Integrity Code):消息完整性代码
校验数据是否被篡改,以及PSK是否正确 通过MIC Key 等字段计算出来

Replay Counter:前两次握手 请求和响应配对值为1 后两次为2

WPA Key Nonce:客户端(Station)产生的随机数 SNonce AP产生的随机数ANonce

比较重要的密钥

PSK(Pairwise Shared Key):预共享密钥,是用于验证 L2TP/IPSec 连接的 Unicode 字符串。在需要使用之前,通过使用某一安全通道在双方之间共享。预先分配的密钥仅仅用于认证过程,而不会用于数据加密过程

PMK(Pairwise Master Key):成对主密钥 是申请者和认证者之间所有密钥数据的最终来源。 PMK由预先共享密钥(PSK)直接得到,或由主会话密钥(MSK)推导得出。如果PMK有MSK推导得出,PMK的计算使用函数L(psk, 0, 256),即MSK的前256位。

它可以衍生自身份验证过程中的EAP method,或者由PSK直接提供。认证者用来生成组临时密钥(GTK)的密钥,通常是认证者生成的一组随机数

在WPA-PSK中 PMK = PSK 是整个WPA认证过程中非常核心的一个密钥

PTK(Pairwise Transient Key): 从PMK中产生的密钥,其中包括加密与完整性协议所使用的密钥, 传递动态密钥所需要的密钥 以及 最终用于加密单播数据流的加密密钥
如果WPA采用TKIP加密,则PTK是512 bits = 64 bytes = 128 hex string (比较常用)
如果WPA采用CCMP加密,则PTK是384 bits
下图显示了PTK的组成结构

采用TKIP协议

在这里插入图片描述
这三个字段也非常重要
KCK (Key Confirmation Key): 128 bits 用于计算WPA EAPOL密钥消息的MIC 本质上就是MIC_KEY
KEK (Key Encryption Key): 128 bits 用于加密发送到客户端的附加数据(WPA Key Data 字段中)
TK(Temporal Key):256 bits 用于后续通信数据加密

采用CCMP协议(这里不细说)
在这里插入图片描述
GMK (Group Master Key):组主密钥
GTK (Group Temporal Key):组临时密钥,由组主密钥(GMK)通过哈希运算生成,是用于加密广播和组播数据流的加密密钥
**

认证之前的初始化工作 - 计算PSK/PMK

使用 Wi-Fi的 SSIDpassphrase(即 Wi-Fi密码)
以及算法Password-Based Key Derivation Function 2 (PBKDF2)

PSK = PMK = PBKDF2(passphrase, SSID, SSID length, 4096)

python中计算需导入

from pbkdf2 import PBKDF2

计算过程如下

def calculate_WPA_PMK(psk, ssid):
    pmk = PBKDF2(psk, ssid, 4096).read(32)
    return pmk

认证过程 - 四次握手

目的
1)Wi-Fi密码的验证
2)后续通信加密的密码的计算

流程

第一次握手 AP --> 客户端 Station

AP 广播自己的数据包 以及随机数ANonce
————————————————————————————————

第二次握手 客户端Station --> AP

客户端(STATION)接收到AP第一个握手包后 得到 SSID AP_MAC(AA) ANonce

开始计算其自己的PTK,用一下方法:
1)产生自己的随机数SNonce

2)使用PRF512算法
PTK = SHA1_PRF(PMK, Len(PMK), “Pairwise key expansion”, Min(AA, SA) || Max(AA, SA) || Min(ANonce, SNonce) || Max(ANonce, SNonce))

3)计算MIC
从PTK中提取前16个字节组成一个MIC Key(32个16进制位) 即PTK中的KCK

使用第一次握手包中的整个802.1X报文体 (需要将WPA Key MIC 字段部分替换成0) 和 MIC Key 以及HMAC_MD5算法计算MIC 值

使用求MD5哈希值的方法:
MIC = HMAC_MD5(MIC_KEY, 16, 802.1X data)

最后客户端发送的握手包中包含以下关键值

  1. 产生的随机数SNonce
  2. MIC

————————————————————————————————

第三次握手 AP --> 客户端 Station

AP 接收到客户端的第二次握手包之后
得到客户端的 STATION_MAC(SA) SNonce MIC 802.11X data

(1)用以前得到的PMK(初始设置), ANonce 按照同样的算法产生PTK

(2)按照上述同样的方法产生MIC值

最后发送的握手包中包含以下关键值:

  1. 加密后的GTK 加密的密钥为KEK

  2. MIC(消息完整性校验码)

  3. 第一次产生的随机数ANonce给客户端(Station)

————————————————————————————————

第四次握手 客户端Station --> AP

客户端接收到第三次握手包 包含 MIC ANonce

如果自己的MIC 等于 AP发送过来的 MIC ,则第四次握手成功 否则失败

会将计算出来的TK(PTK的最后一段)安装到系统,作为后续的通信加密密钥

最后一次握手向AP发送确认信息,表示密钥已经安装完毕,

————————————————————————————————
AP收到该通信包之后,会进行密钥安装。

至此,双方的密钥安装全部结束,后续通信中按照前面步骤中的密钥进行通信。

测试代码

计算PTK

def customPRF512(key, A, B):
    blen = 64
    i = 0
    R = ''
    while i <= ((blen * 8 + 159) / 160):
        msg = A + chr(0x00) + str(B) + chr(i)
        hmacsha1 = hmac.new(key, bytes(msg, encoding='utf-8'), hashlib.sha1)
        i += 1
        R = R + str(hmacsha1.digest())
    return bytes(R[:blen], encoding='utf-8')


# return PTK in bytes
def calculate_WPA_PTK(pmk, ap_mac, station_mac, anonce, snonce):
    pke = "Pairwise key expansion"
    mac_ap_value = binascii.unhexlify(ap_mac)
    mac_station_value = binascii.unhexlify(station_mac)

    anonce_value = binascii.unhexlify(anonce)
    snonce_value = binascii.unhexlify(snonce)
    key_data = min(mac_ap_value, mac_station_value) + max(mac_ap_value, mac_station_value) + min(anonce_value, snonce_value) + max(anonce_value, snonce_value)
    PTK = customPRF512(pmk, pke, key_data)
    return PTK

计算 MIC 值

# return MIC in hex string
def calculate_WPA_MIC(ptk, payload):
    MCI_Key = ptk[:16]
    payload_bytes = bytes(payload, encoding='utf-8')
    MIC = hmac.new(MCI_Key, payload_bytes, hashlib.sha1).hexdigest()[:32]
    return MIC

常见错误

  • TypeError: Unicode-objects must be encoded before hashing
  • TypeError: can only concatenate str (not “bytes”) to str

在《Understanding WPA/WPA2 Hash (MIC) Cracking Process In Python》中给出了计算PTK的方法

def customPRF512(key, A, B):
    blen = 64
    i = 0
    R = ''
    while i <= ((blen * 8 + 159) / 160):
        hmacsha1 = hmac.new(key, A + chr(0x00) + B + chr(i), hashlib.sha1)
        i += 1
        R = R + hmacsha1.digest()
    return R[:blen]

然而python3 版本以上会出现以上两个问题

原因
第一个:A + chr(0x00) + B + chr(i) 是字符串str 需要转换成字节 bytes
第二个:hmacsha1.digest() 得到的是bytes 需要转换成str 才能进行字符串的拼接

解决方案
Python中字符串与字节之间相互转换
字符串转字节 bytes --> str

b = "Hello, world!"    # str object
str.encode(b)
bytes(b, encoding="utf8")

字节转字符串 str --> bytes

a = b"Hello, world!" 
bytes.decode(a)
str(a, encoding="utf-8")
a.decode()

同时附上bytes和hex字符串之间的相互转换的方法

data_bytes = b'\x820\xb100\x03\xc3\xb4'
strr = '8230b1303003c3b4'

tmp = data_bytes.hex()
num = bytes.fromhex(strr)

引用

引用1 引用2 引用3 引用4

猜你喜欢

转载自blog.csdn.net/weixin_43632374/article/details/121527554