在EAP-PEAP身份验证下从WiFi客户端提取PMK,以便在Wireshark上进行分析

时间:2017-07-11 14:20:21

标签: linux wifi driver wpa

我正在启动与WiFi相关的研究项目,这需要我在连接设置期间分析WiFi客户端和AP之间的帧交换。

实验设置:我有一台笔记本电脑M,在监控模式下使用Wireshark捕获WiFi流量,通过802.1x身份验证连接到WiFi网络的设备A(运行Linux),特别是使用EAP- PEAP协议。

我只控制笔记本电脑M和设备A,但不控制AP和网络(包括RADIUS服务器)。

目标:我想解码Wireshark在笔记本电脑M上捕获的WiFi数据帧。根据this Wireshark how to,我需要以某种方式提取PMK(Pairwise Master)密钥)在网络和设备A之间交换。

由于我只控制设备A,我需要从中提取PMK。

问题:我不知道如何从设备A中提取PMK(假设是Linux操作系统),特别是考虑到我们正在谈论EAP-PEAP会话,我在网上搜索时找不到任何结论性的提示。

我可以找到this discussion,这意味着PMK直接存储在WiFi NIC或驱动程序中。

问题:

  • 甚至可以提取PMK,例如在Linux系统中,没有对客户端系统进行重大修改(例如修改无线驱动程序的代码等)?考虑到这种安全漏洞的严重性,我认为这是非常困难的。将会。
  • PMK是否以某种方式存储(例如在Linux中)?根据上述情况,我不希望出现这种情况。
  • 我需要修改哪些代码(让我们假设一个Linux操作系统)来提取PMK?

P.S。:我要注意的是,我不认为这是一个黑客攻击'问题(因此与stackoverflow.com的政策不相符),因为我控制客户端设备(不仅仅是监控设备)。

1 个答案:

答案 0 :(得分:0)

我找到了wpa_supplicant输出PMK的两种方法:

  1. 简单方法:使用wpa_supplicant选项调用-K以及一些调试选项(例如-dd)。这将包括调试输出中的密钥(密码等)。
  2. 困难:更改wpa_supplicant的代码以输出密钥。鉴于-K选项存在,这种方式是不必要的,但这是我尝试的第一件事(不要问)。我已经总结了下面我是如何做到这一点的,这对于希望改变wpa_supplicant代码的人来说可能很有意思。
  3. 2)艰难之道:改变wpa_supplicant代码

    我能够通过更改wpa_supplicant的代码找到答案,使其在身份验证期间输出PMK。在我的例子中,客户端设备是Raspberry Pi模型B +,V1 2,运行Raspbian GNU / Linux 7(wheezy),它使用旧版wpa_supplicant,即v1.0, 2012-05-10

    对于任何想知道的人,我已经更改了源文件src/rsn_supp/wpa.c,函数wpa_supplicant_key_neg_complete(),以输出PMK,如下所示:

    static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
                        const u8 *addr, int secure)
    {
        // pass the pmk (pairwise master key) to a hex string.
        int i;
        // hex str to hold pmk. 1024 bit 
        // should be enough (the pmk is supposed to be 256 bit, thus 32 byte, thus 
        // 64 hex chars)
        char pmk_str[1024] = {'\0'};
        char * pmk_ptr = pmk_str;
        // use os_snprintf() (as used by other methods in wpa.c)
        for (i = 0; i < sm->pmk_len; i++) {
            // wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
            //  "WPA: pmk[%d]: %02X", i, sm->pmk[i]);
            pmk_ptr += sprintf(pmk_ptr, "%02X", sm->pmk[i]);
        }
        *(pmk_ptr + 1) = '\0';
    
        wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
            "WPA: Key negotiation completed with "MACSTR": \
            \n\tPMK=%s \
            \n\t[PTK=%s GTK=%s]", 
            MAC2STR(addr),
            pmk_str,
            wpa_cipher_txt(sm->pairwise_cipher),
            wpa_cipher_txt(sm->group_cipher));
    (...)
    
    }
    

    此自定义可用on my github