求教:判断WPA2 EAPOL完整握手帧的正确方法及验证问题
判断WPA2 EAPOL完整握手帧的正确姿势(避坑版)
你的思路已经摸到了核心,但实际抓包场景里确实有不少容易踩的坑——我之前做握手帧分析的时候也栽过几次,给你补充修正一下完整的判断逻辑:
基础判断逻辑(你的思路是对的,但要细化)
- 识别消息类型:注意EAPOL消息1/2是EAP请求/响应,而消息3/4都是
EAPOL-Key类型,得靠Key Info字段区分:- 消息1:EAP Type=Request(AP发起,通常是广播或定向到STA)
- 消息2:EAP Type=Response(STA回复AP)
- 消息3:EAPOL-Key,
Key Info里的Install位为1,Key Type为Pairwise(AP下发密钥) - 消息4:EAPOL-Key,
Key Info里的Ack位为1,Key Type为Pairwise(STA确认密钥)
- Key Nonce匹配:消息1里的ANonce必须和消息3的ANonce完全一致;消息2里的SNonce必须和消息4的SNonce完全一致——这是绑定同一握手序列的核心标识
- 源目地址校验:同一握手的地址逻辑必须是:
- 消息1:源=AP MAC,目的=STA MAC(或广播,部分场景AP会先广播发起)
- 消息2:源=STA MAC,目的=AP MAC
- 消息3:源=AP MAC,目的=STA MAC
- 消息4:源=STA MAC,目的=AP MAC
实际场景的坑与解决方法
1. 重复帧的处理
实际握手时,信号差或丢包会导致重传(比如STA没收到消息3就重发消息2,AP没收到消息4就重发消息3),这时候要:
- 给同一AP-STA对的握手帧加上时间窗口限制:比如同一握手序列的所有帧时间差不能超过5秒(可根据场景调整),超过的就算新的握手尝试
- 同一类型的帧(比如多个消息2),如果Nonce相同,判定为重复帧,只保留时间最早或最新的即可
2. 容易忽略的有效帧标识
- MIC字段非空:消息3和消息4的MIC字段必须是非零值(空MIC的帧是无效的,可能是抓包不完整或测试帧)
- Key Info的细节:必须确认消息3的
Install位和消息4的Ack位都被置位,否则不是完整的握手流程
3. 多STA场景的分组
如果抓包中有多个STA和同一个AP的握手,必须按AP MAC + STA MAC的组合分组,每个组单独判断是否有完整的1/2/3/4帧,不能跨组匹配
简化的判断流程伪代码
# 第一步:按AP和STA的MAC地址分组所有EAPOL帧 frame_groups = {} for frame in eapol_frames: ap_mac = frame.dst if frame.eapol_type in [1,3] else frame.src sta_mac = frame.src if frame.eapol_type in [1,3] else frame.dst key = (ap_mac, sta_mac) if key not in frame_groups: frame_groups[key] = [] frame_groups[key].append(frame) # 第二步:每组内筛选完整握手 for (ap_mac, sta_mac), frames in frame_groups.items(): # 筛选各类型有效帧 msg1_list = [f for f in frames if f.eapol_type == 1 and f.anonce is not None] msg2_list = [f for f in frames if f.eapol_type == 2 and f.snonce is not None] msg3_list = [f for f in frames if f.eapol_type == 3 and f.key_info.install and f.anonce is not None] msg4_list = [f for f in frames if f.eapol_type == 4 and f.key_info.ack and f.snonce is not None] # 匹配Nonce和时间窗口 valid_handshakes = [] for msg1 in msg1_list: # 找同ANonce的msg3 matched_msg3 = next((m3 for m3 in msg3_list if m3.anonce == msg1.anonce), None) if not matched_msg3: continue for msg2 in msg2_list: # 找同SNonce的msg4 matched_msg4 = next((m4 for m4 in msg4_list if m4.snonce == msg2.snonce), None) if not matched_msg4: continue # 检查时间差是否在合理范围(这里设为5秒) timestamps = [msg1.ts, msg2.ts, matched_msg3.ts, matched_msg4.ts] if max(timestamps) - min(timestamps) <= 5: valid_handshakes.append( (msg1, msg2, matched_msg3, matched_msg4) ) # 去重,保留唯一的握手序列 unique_handshakes = list({(h[0].anonce, h[1].snonce) for h in valid_handshakes}) if unique_handshakes: print(f"找到完整WPA2握手:AP={ap_mac}, STA={sta_mac}")
内容的提问来源于stack exchange,提问作者user9022502
相关产品推荐
相关产品推荐

