[补] winpcap编程——EAPSOCKET实现校园网锐捷登录(mentohust)

EAP SOCKET Implement Mentohust

时间20161115

对于EAP协议不了解,可参考上一篇随笔。

通过抓包分析校园网的锐捷登录流程,我在上一篇随笔中实现了EAPSOCKET这个类,

准备

原因

  • 周末尝试了一下windows(自带?)的虚拟机Hyper-V(它的虚拟机好像必须通过虚拟机的网卡才能上网),多次尝试后蛋疼的锐捷疯狂断网,于是我很气啊!!!!!!

  • 但是那天觉得破解锐捷不如自实现锐捷认证,于是有了以下内容。

实现

  • wires hark

  • 能看出锐捷的验证方式是802.1x的EAP协议,其实校园网所采用的认证方式大部分都是802.1x认证的eap协议。

  • 根据mentohust源码了解锐捷登录具体细节

代码

只是个例子
原先的代码因为一些原因丢失了,最近用go重写了一个过几天发

思考

Mentohust Security

写代码时看了mentohust的源码,因而引发了一些对于安全的思考,在mentohust中由于pcap_handle函数没有对EAP包做过多判断,因而攻击者可在内网中伪造数据包精确地让目标断网。

mentohust : https://github.com/hyrathb/mentohust/tree/master/src
mentohust.c

static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf)
{
    static unsigned failCount = 0;
#ifndef NO_ARP
    if (buf[0x0c]==0x88 && buf[0x0d]==0x8e) {
#endif
        if (memcmp(destMAC, buf+6, 6)!=0 && startMode>2)    /* 服务器MAC地址不符 */
            return;
        capBuf = buf;
        if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x01) {    /* 验证用户名 */
            if (startMode < 3) {
                memcpy(destMAC, buf+6, 6);
                printf(_("** 认证MAC:\t%s\n"), formatHex(destMAC, 6));
                startMode += 3; /* 标记为已获取 */
            }
            switchState(ID_IDENTITY);
        }
        else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x04) /* 验证密码 */
            switchState(ID_CHALLENGE);
        else if (buf[0x0F]==0x00 && buf[0x12]==0x03) {  /* 认证成功 */
            printf(_(">> 认证成功!\n"));
            failCount = 0;
            if (!(startMode%3 == 2)) {
                getEchoKey(buf);
                showRuijieMsg(buf, h->caplen);
            }
            if (dhcpMode==1 || dhcpMode==2) /* 二次认证第一次或者认证后 */
                switchState(ID_DHCP);
            else if (startMode%3 == 2)
                switchState(ID_WAITECHO);
            else
                switchState(ID_ECHO);
        }
        else if (buf[0x0F]==0x00 && buf[0x12]==0x04) {  /* 认证失败或被踢下线 */
            if (state==ID_WAITECHO || state==ID_ECHO) {
                printf(_(">> 认证掉线,开始重连!\n"));
                switchState(ID_START);
            }
            else if (buf[0x1b]!=0 || startMode%3==2) {
                printf(_(">> 认证失败!\n"));
                if (startMode%3 != 2)
                    showRuijieMsg(buf, h->caplen);
                if (maxFail && ++failCount>=maxFail) {
                    printf(_(">> 连续认证失败%u次,退出认证。\n"), maxFail);
                    exit(EXIT_SUCCESS);
                }
                restart();
            }
            else
                switchState(ID_START);
        }
}

mystate.c

static int sendChallengePacket()
{
    int nameLen = strlen(userName);
    if (startMode%3 == 2)   /* 赛尔 */
    {
        if (sendCount == 0)
        {
            printf(_(">> 发送密码...\n"));
            *(u_int16_t *)(sendPacket+0x0E) = htons(0x0100);
            *(u_int16_t *)(sendPacket+0x10) = *(u_int16_t *)(sendPacket+0x14) = htons(nameLen+22);
            sendPacket[0x12] = 0x02;
            sendPacket[0x13] = capBuf[0x13];
            sendPacket[0x16] = 0x04;
            sendPacket[0x17] = 16;
            memcpy(sendPacket+0x18, checkPass(capBuf[0x13], capBuf+0x18, capBuf[0x17]), 16);
            memcpy(sendPacket+0x28, userName, nameLen);
            setTimer(timeout);
        }
        return pcap_sendpacket(hPcap, sendPacket, nameLen+40);
    }
    if (sendCount == 0)
    {
        printf(_(">> 发送密码...\n"));
        //fillMd5Packet(capBuf+0x18);
        fillEtherAddr(0x888E0100);
        *(u_int16_t *)(sendPacket+0x14) = *(u_int16_t *)(sendPacket+0x10) = htons(nameLen+22);
        sendPacket[0x12] = 0x02;
        sendPacket[0x13] = capBuf[0x13];
        sendPacket[0x16] = 0x04;
        sendPacket[0x17] = 16;
        memcpy(sendPacket+0x18, checkPass(capBuf[0x13], capBuf+0x18, capBuf[0x17]), 16);
        memcpy(sendPacket+0x28, userName, nameLen);

        memcpy(sendPacket+0x28+nameLen, pkt_md5, sizeof(pkt3));
        memcpy(sendPacket + 0x90 + nameLen, computePwd(capBuf+0x18), 0x10);
        //memcpy(sendPacket + 0xa0 +nameLen, fillBuf + 0x68, fillSize-0x68);
        memcpy(sendPacket + 0x108 + nameLen, computeV4(capBuf+0x18, capBuf[0x17]), 0x80);
        //sendPacket[0x77] = 0xc7;
        setTimer(timeout);
    }
    return pcap_sendpacket(hPcap, sendPacket, 569);
}

END

转载于:https://www.cnblogs.com/tr3e/p/6850249.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值