原始Socket抓包
0x01. 源码:
#include <stdio.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <mstcpip.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"IPHLPAPI.lib")//获取本地网络信息的开发接口
int main ()
{
//初始化
WSADATA wsadata;
SOCKET SnifferSocket;
hostent *pHostent;//指向主机名的指针
SOCKADDR_IN sock;
char Packet[60000];
int retval;
if (WSAStartup (MAKEWORD (2, 2), &wsadata) != 0) {
printf ("WSAStartup failed!\n");
system ("pause");
return 1;
}
//创建原始socket
SnifferSocket = socket (AF_INET, SOCK_RAW, IPPROTO_IP);
if (SnifferSocket == INVALID_SOCKET) {
printf ("Socket failed with error %d\n", WSAGetLastError ());//这里要必须用管理员身份运行,不然创建不了socket
system ("pause");
return 0;
}
//绑定到一个本地IP地址
pHostent = gethostbyname ("SPWPUN");//这里填自己的主机名
printf ("本机可用的IP地址:\n");
for (int i = 0; pHostent->h_addr_list[i]; i++)
{
printf ("IP address %d:%s\n", i + 1, inet_ntoa (*(struct in_addr*)pHostent->h_addr_list[i]));
}
system ("pause");
sock.sin_family = AF_INET;
sock.sin_port = htons (80);
memcpy (&sock.sin_addr.S_un.S_addr, pHostent->h_addr_list[3], pHostent->h_length);//选择第4个IP,有效
retval = bind (SnifferSocket, (const sockaddr *)&sock, sizeof (sock));
if (retval == SOCKET_ERROR) {
printf ("Bind error!\n");
system ("pause");
return 0;
}
//设置网卡为混杂模式
u_long InOutParam = 1;
retval = ioctlsocket (SnifferSocket, SIO_RCVALL, &InOutParam);
//开始循环接受数据
while (true)
{
ZeroMemory (Packet, sizeof (Packet));
retval = recv (SnifferSocket, Packet, sizeof (Packet), 0);//retval是接受数据的返回的字节数
if (retval == 0 || retval == SOCKET_ERROR) {
printf ("发生错误!\n");
break;
}
else {
printf ("抓包成功,抓到的数据包的大小为%d个字节。\n", retval);
}
}
//关闭socket
closesocket (SnifferSocket);
WSACleanup ();
system ("pause");
return 0;
}
0x02. 说明:
- 这段代码只是简单实现了原始socket的抓包而已,并未涉及到具体的包的数据的分析,只是简单显示出抓到的包的大小而已。
- 调试运行的时候,必须要使用管理员权限运行,这是原始socket的一个缺点。
- 原始socket也不能获取链路层信息,不能获取arp包(在Linux下可以);也没有内核级的过滤机制,只能由程序员自己来过滤,既复杂又很慢,在千兆网上很容易丢包。
- 在选择网络接口的时候需要根据自己的电脑的实际情况来确定,因为有一些IP的网络地址是虚拟机等的地址,实际上是不可用的,在虚拟机为开启的情况下。
0x03. 代码结构:
1.创建原始socket
2.获取一个需要监听网络接口的ip地址,并绑定(必须要显示绑定)
3.设置网卡为混杂模式
4.开始循环接受数据
5.关闭socket
0x04. 后感:
- 这一次,我体会到了按着思路走写代码的好处,有种一气呵成的感觉,再加油吧!