Schoolleave的文章

  • 使用原始套接字Raw Socket实现数据包嗅探

    背景网络上随时都流通了大量的数据包,我们要想实现抓包并分析,实现思路思路大概是:在合适的时候捕获数据包,保存到缓冲区,作为备用;然后,按照一定的结构和格式去读取缓冲区的内容。由于各种公开的网络协议是已知的,所以对于数据包的分析就比较简单。
    通常我们都是使用类似WireShark的抓包软件嗅探数据包,这些抓包工具大部分都是基于WinPcap库实现的数据包嗅探功能。而现在,本文讲解下使用原始套接字的RawSocket方式实现数据包的嗅探。当然,和WinPcap相比,Raw Socket有很大的局限性。,它只能抓到IP层及以上的数据包,抓不到MAC层的数据包。
    但是,Raw Socket开发的程序使用起来比较方便,不需要额外安装什么。本文就把实现的过程原理写成文档,分享给大家。
    程序分析要实现基于Raw Socket嗅探数据包,关键是创建Raw Socket。那么创建步骤就如下所示:
    1. 初始化 Winsock 服务环境在使用 Socket 函数之前,必须要经过初始化 Winsock 库才能成功调用。我们使用 WSAStartup 函数来帮助我们实现初始化工作,指定使用 Socket 的版本。
    // 初始化Winsock服务环境, 设置版本 WSADATA wsaData = {0}; if(0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) { ShowError("WSAStartup"); return FALSE; }
    2. 创建原始套接字我们调用 socket 函数来创建套接字,其中,函数中的第 1 个参数为 AF_INET ,表示IPv4地址族格式;第 2 个参数为 SOCK_RAW ,表示要创建原始套接字,注意:只有管理员权限用户才能创建原始套接字;第 3 个参数为 IPPROTO_IP,表示的是IP协议。
    // 创建原始套接字 // !!!Windows上没办法用Raw Socket抓MAC层的数据包,只能抓到IP层及以上的数据包!!! g_RawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (INVALID_SOCKET == g_RawSocket) { WSACleanup(); ShowError("socket"); return FALSE; }
    3. 绑定嗅探的IP地址帮使用 bind 函数来绑定IP地址,这样原始套接字就会使用绑定IP地址对应的网卡进行数据包的嗅探。其中,端口要设为 0 。
    // 构造地址结构 sockaddr_in SockAddr = {0}; RtlZeroMemory(&SockAddr, sizeof(sockaddr_in)); SockAddr.sin_addr.S_un.S_addr = inet_addr(lpszHostIP); SockAddr.sin_family = AF_INET; SockAddr.sin_port = htons(0); // 绑定 if (SOCKET_ERROR == ::bind(g_RawSocket, (sockaddr *)(&SockAddr), sizeof(sockaddr_in))) { closesocket(g_RawSocket); WSACleanup(); ShowError("bind"); return FALSE; }
    4. 设置混杂模式要想捕获到其它目的地非本机的数据包,就需要将网卡设置为混杂模式。ioctlsocket 函数中的 SIO_RCVALL 控制代码使套接字能够接收通过网络接口的所有IPv4或IPv6数据包。
    // 设置混杂模式,这样才能捕获所有的数据包 DWORD dwSetVal = 1; if (SOCKET_ERROR == ioctlsocket(g_RawSocket, SIO_RCVALL, &dwSetVal)) { closesocket(g_RawSocket); WSACleanup(); ShowError("ioctlsocket"); return FALSE; }
    5. 捕获数据包直接创建多线程,在多线程中不断循环调用 recvfrom 函数接收数据包。
    iRecvBytes = recvfrom(g_RawSocket, (char *)lpRecvBuf, dwBufSize, 0, (sockaddr *)(&RecvAddr), &iRecvAddrLen);
    经过上面 5 个步骤的操作,就可以使用Raw Socket成功捕获数据包了。我们可以将捕获到的数据包保存到缓冲区,并按照一定的结构和格式去读取缓冲区的内容,对数据包进行分析。
    至于数据包的分析部分,本文在此就不详细讲解了。由于各种公开的网络协议是已知的,所以对于数据包的分析就只需要对照着协议格式仔细进行分析即可。
    程序测试我们以管理员身份运行程序,选择其中一个IP地址对应的网卡进行数据包嗅探,成功嗅探到数据包。

    总结对于上面的程序,我们之分析关键部分的代码,对于IP的显示和选择,以及数据包的分析我们在本文上并没有给出分析过程,大家可以对照代码进行理解即可。
    其中,需要注意的是,需要管理员权限才能成功创建原始套接字。所以,测试程序的时候,要记得以管理员权限运行程序。
    参考参考自《Windows黑客编程技术详解》一书
    2  留言 2018-12-20 12:25:50

发送私信

人生就像马拉松,获胜的关键不在于瞬间的爆发

8
文章数
20
评论数
eject