wpa2 psk 破解原理实战研究
高手们早已视无线密码破解如探囊取物,但是喜欢钻牛角尖的我喜欢渔而不是鱼。没有人告诉我,那就自己动手丰衣足食吧!废话少说,这两天小菜我研究了一下这个破解原理,略知一点皮毛,本文仅供大家参考,如有误导概不负责!
条件:BT5、一个wpa2握手包、EWSA 5,0,252,0 天易love完美破解英文版、OllyICE v1.10
原理概述:
由字典中的一个密码,加上salt(路由器ssid)计算出pmk;而后由pmk配合握手包中的数据算出一个ptk,取出其中的第一个成员ptk->mic再对握手包中的数据进行hmac重新计算得到一个mic;由于握手包中保存着真实的mic,两者一比较,如果一致说明最初字典中取出的密码是真的wpa2 key。
实践证明:
1、运行BT5,而后在开始菜单中找到Wireshark运行之。打开准备好的握手包,输入Filter:eapoly后,点击Apply,定位到具体的握手包。
握手包中与破解相关的数据有:AP路由器的MAC和ANonce、无线网卡的MAC和SNonce、802.1x Authentication data,本例中为0x79字节数据:
00000000 01 03 00 75 02 01 0A 00 00 00 00 00 00 00 00 00
00000010 01 27 62 BF 06 1A E0 D0 2B 71 60 4A 85 40 A1 5E
00000020 11 D9 4F 26 67 A6 E8 73 B9 E1 F2 79 70 8E 9F 35
00000030 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000050 00 B4 F8 8B 25 1A CB EC 10 89 A2 10 5B C0 62 59
00000060 CC 00 16 30 14 01 00 00 0F AC 04 01 00 00 0F AC
00000070 04 01 00 00 0F AC 02 00 00
2、OD打开EWSA载入握手包,加上字典。
我的字典就是个txt文件,里面只有一行,演示方便我就直接放了个真的wpa2 密钥。
(1) 计算出pmk和ptk->mic
pmk = PBKDF2(psk, ssid, 4096, 256)
ssid: TP-LINK_xxxxxx
psk: xxxxxxxx
pmk: 60a2c2536651b8958b2cc3dc9119841438ae6760127f5ee13677b04827648646
附件是一个pmk计算脚本,此处略过。
利用握手包中的AP路由器的MAC和ANonce、无线网卡的MAC和SNonce数据、pmk得到ptk;
wpa_pmk_to_ptk(pmk, own_addr,sta->addr, ANonce, SNonce,(u8 *) &PTK, sizeof(PTK));
//PRF-512(PMK, "Pairwise key expansion", MAC1||MAC2||Nonce1||Nonce2)
004C3993 8B5424 10 mov edx, dword ptr [esp+10]
004C3997 6A 10 push 10
004C3999 52 push edx
004C399A 8B5424 20 mov edx, dword ptr [esp+20]
004C399E 6A 4C push 4C
004C39A0 8D4424 2C lea eax, dword ptr [esp+2C]
004C39A4 50 push eax //02BAFC70
004C39A5 6A 16 push 16
004C39A7 B9 08000000 mov ecx, 8
004C39AC 8D7C24 60 lea edi, dword ptr [esp+60]
004C39B0 F3:A5 rep movs dword ptr es:[edi], dword ptr [esi]
004C39B2 8B8C24 9C000000 mov ecx, dword ptr [esp+9C]
004C39B9 68 E0395B00 push 005B39E0
004C39BE 51 push ecx
004C39BF 52 push edx //02BAFCF8
004C39C0 E8 ABE6FFFF call 004C2070 //PRF-512()
stack:
02BAFC30 02BAFCF8 edx PMK
02BAFC34 00000020
02BAFC38 005B39E0 ASCII "Pairwise key expansion"
02BAFC3C 00000016
02BAFC40 02BAFC70 eax MAC1||MAC2||Nonce1||Nonce2
02BAFC44 0000004C
02BAFC48 02BAFD20 //返回的ptk起始地址 只计算了第一个成员ptk->mic,提高破解效率
02BAFC4C 00000010
参数情况
02BAFCF8 60 A2 C2 53 66 51 B8 95 8B 2C C3 DC 91 19 84 14 //PMK
02BAFD08 38 AE 67 60 12 7F 5E E1 36 77 B0 48 27 64 86 46
02BAFC70 54 E6 xx xx xx xx 90 21 xx xx xx xx 27 62 BF 06 //MAC1||MAC2||Nonce1||Nonce2
02BAFC80 1A E0 D0 2B 71 60 4A 85 40 A1 5E 11 D9 4F 26 67
02BAFC90 A6 E8 73 B9 E1 F2 79 70 8E 9F 35 3C 53 68 62 BA
02BAFCA0 84 41 84 D0 07 B0 41 7A 46 3D 6D A4 4E 46 8C 2A
02BAFCB0 65 79 9C 87 85 09 FF 4B B4 DF 28 F8
MAC1和MAC2做了处理
Nonce1:
27 62 bf 06 1a e0 d0 2b 71 60 4a 85 40 a1 5e 11
d9 4f 26 67 a6 e8 73 b9 e1 f2 79 70 8e 9f 35 3c
Nonce2:
53 68 62 ba 84 41 84 d0 07 b0 41 7a 46 3d 6d a4
4e 46 8c 2a 65 79 9c 87 85 09 ff 4b b4 df 28 f8
//计算得到ptk->mic
02BAFD20 8F 4B C2 A4 52 16 59 73 B5 22 72 82 E6 60 DA B0
(2)现在可以由ptk->mic和握手数据包中的802.1x Authentication data重新算出mic
wpa_verify_key_mic(ptk->mic, data, data_len)
004C874A 52 push edx
004C874B 51 push ecx
004C874C 8D50 78 lea edx, dword ptr [eax+78]
004C874F 52 push edx
004C8750 05 78010000 add eax, 178
004C8755 50 push eax
004C8756 8D4424 6C lea eax, dword ptr [esp+6C]
004C875A 50 push eax
004C875B E8 D0B2FFFF call 004C3A30 //关键call
stack:
02BAFCB0 02BAFD20 ptk->mic 由pmk算出的ptk中的第一个成员
02BAFCB4 014792AC key->mic 数据包中提取的真实mic
02BAFCB8 014791AC data
02BAFCBC 00000079 len
02BAFCC0 00000002 ver 决定是hmac_md5还是hmac_sha1
其中数据包中提取的mic为:
014792AC B4 F8 8B 25 1A CB EC 10 89 A2 10 5B C0 62 59 CC
//f7 进入call 004C3A30
004C3A30 83EC 18 sub esp, 18
004C3A33 A1 CCFD7200 mov eax, dword ptr [72FDCC]
004C3A38 33C4 xor eax, esp
004C3A3A 894424 14 mov dword ptr [esp+14], eax
004C3A3E 8B5424 2C mov edx, dword ptr [esp+2C]
004C3A42 8B4424 1C mov eax, dword ptr [esp+1C]
004C3A46 8B4C24 24 mov ecx, dword ptr [esp+24]
004C3A4A 83FA 01 cmp edx, 1 //ver 是否是hmac_md5
004C3A4D 75 14 jnz short 004C3A63
004C3A4F 8D1424 lea edx, dword ptr [esp]
004C3A52 52 push edx
004C3A53 8B5424 2C mov edx, dword ptr [esp+2C]
004C3A57 52 push edx
004C3A58 51 push ecx
004C3A59 6A 10 push 10
004C3A5B 50 push eax
004C3A5C E8 9FE7FFFF call 004C2200 ; hmac_md5
004C3A61 EB 17 jmp short 004C3A7A
004C3A63 83FA 02 cmp edx, 2 //是否是hmac_sha1
004C3A66 75 15 jnz short 004C3A7D
004C3A68 8D1424 lea edx, dword ptr [esp]
004C3A6B 52 push edx
004C3A6C 8B5424 2C mov edx, dword ptr [esp+2C]
004C3A70 52 push edx
004C3A71 51 push ecx
004C3A72 6A 10 push 10
004C3A74 50 push eax
004C3A75 E8 C6E7FFFF call 004C2240 ; hmac_sha1 //f7
004C3A7A 83C4 14 add esp, 14
004C3A7D 8B4424 20 mov eax, dword ptr [esp+20]
004C3A81 8D1424 lea edx, dword ptr [esp]
004C3A84 B9 10000000 mov ecx, 10 ; 计算出的mic与包中的mic比较,16字节
004C3A89 2BD0 sub edx, eax
004C3A8B 56 push esi
004C3A8C 8D6424 00 lea esp, dword ptr [esp]
004C3A90 8B3402 mov esi, dword ptr [edx+eax]
004C3A93 3B30 cmp esi, dword ptr [eax]
004C3A95 75 20 jnz short 004C3AB7
004C3A97 83E9 04 sub ecx, 4
004C3A9A 83C0 04 add eax, 4
004C3A9D 83F9 04 cmp ecx, 4
004C3AA0 ^ 73 EE jnb short 004C3A90
004C3AA2 B8 01000000 mov eax, 1 ; 完全相同返回成功 eax=1
004C3AA7 5E pop esi
004C3AA8 8B4C24 14 mov ecx, dword ptr [esp+14]
004C3AAC 33CC xor ecx, esp
004C3AAE E8 8C610900 call 00559C3F
004C3AB3 83C4 18 add esp, 18
004C3AB6 C3 retn
//call 004C2240的调用堆栈及返回数据情况
004C3A6B 52 push edx
004C3A6C 8B5424 2C mov edx, dword ptr [esp+2C]
004C3A70 52 push edx
004C3A71 51 push ecx
004C3A72 6A 10 push 10
004C3A74 50 push eax
004C3A75 E8 C6E7FFFF call 004C2240 //hmac_sha1
stack:
02BAFC80 02BAFD20 ptk->mic
02BAFC84 00000010
02BAFC88 014791AC data
02BAFC8C 00000079 len
02BAFC90 02BAFC94 calced_mic_hach
02BAFC94 B4 F8 8B 25 1A CB EC 10 89 A2 10 5B C0 62 59 CC //calced_mic_hach为20字节
02BAFCA4 81 0E 1E 45
将前16字节也就是计算出的mic与数据包中的真实mic比较即可判断最初假设的psk是否正确
02BAFC94 B4 F8 8B 25 1A CB EC 10 89 A2 10 5B C0 62 59 CC //calced_mic取前16字节
而数据包中提取的mic为:
014792AC B4 F8 8B 25 1A CB EC 10 89 A2 10 5B C0 62 59 CC
这里显然相等,即证明我的字典中的那个是真实密钥,与事实相符。
(3)一些定义提供参考
#define WPA_KEY_INFO_TYPE_MASK (BIT(0) | BIT(1) | BIT(2))
struct ieee802_1x_hdr {
u8 version;
u8 type;
u16 length;
/* followed by length octets of data */
} __attribute__ ((packed));
struct wpa_ptk {
u8 mic_key[16]; /* EAPOL-Key MIC Key (MK) */
u8 encr_key[16]; /* EAPOL-Key Encryption Key (EK) */
u8 tk1[16]; /* Temporal Key 1 (TK1) */
union {
u8 tk2[16]; /* Temporal Key 2 (TK2) */
struct {
u8 tx_mic_key[8];
u8 rx_mic_key[8];
} auth;
} u;
} __attribute__ ((packed));
struct wpa_eapol_key {
u8 type;
u16 key_info;
u16 key_length;
u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
u8 key_nonce[WPA_NONCE_LEN];
u8 key_iv[16];
u8 key_rsc[WPA_KEY_RSC_LEN];
u8 key_id[8]; /* Reserved */
u8 key_mic[16];
u16 key_data_length;
/* followed by key_data_length bytes of key_data */
} __attribute__ ((packed));
static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len)
{
struct ieee802_1x_hdr *hdr;
struct wpa_eapol_key *key;
u16 key_info;
int type, ret = 0;
u8 mic[16];
if (data_len < sizeof(*hdr) + sizeof(*key))
return -1;
hdr = (struct ieee802_1x_hdr *) data;
key = (struct wpa_eapol_key *) (hdr + 1);
key_info = ntohs(key->key_info);
type = key_info & WPA_KEY_INFO_TYPE_MASK;
memcpy(mic, key->key_mic, 16);
memset(key->key_mic, 0, 16);
if (wpa_calc_eapol_key_mic(key_info & WPA_KEY_INFO_TYPE_MASK,PTK->mic_key, data, data_len, key->key_mic)
|| memcmp(mic, key->key_mic, 16) != 0)
ret = -1;
memcpy(key->key_mic, mic, 16);
return ret;
}
static int wpa_calc_eapol_key_mic(int ver, u8 *key, u8 *data, size_t len,u8 *mic)
{
u8 hash[SHA1_MAC_LEN];
switch (ver) {
case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
hmac_md5(key, 16, data, len, mic);
break;
case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
hmac_sha1(key, 16, data, len, hash);
memcpy(mic, hash, MD5_MAC_LEN);
break;
default:
return -1;
}
return 0;
}
尾声:
在此8.1建军节之际,特向所有奋战在对敌斗争最前沿的人民子弟兵道一声:“同志们,你们辛苦了!你们才是最可爱的人!”.
天易love
2012-08-01
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)