数据包的捕获与分析
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
9
以太网卡的工作模式
网卡的MAC地址(48位)
通过ARP来解析MAC与IP地址的转换 用ipconfig/ifconfig可以查看MAC地址
MAC地址与自己相匹配的数据帧 广播包 混杂模式:不管数据帧中的目的地址是否与自己的地址匹配, 都接收下来 非混杂模式:只接收目的地址相匹配的数据帧,以及广播数 据包(和组播数据包)
不能发送tcp包 不能使用伪造的原ip地址
6
关键代码2:绑定到一个本地IP地址
Result = gethostname(Name, 255); 想 想 看 这 里 端 口 号 有没有意义,这个 pHostent = (struct hostent*)malloc(sizeof(struct 值合不合适 hostent)); pHostent = gethostbyname(Name); SOCKADDR_IN sock; sock.sin_family = AF_INET; 一定是第一个接口 sock.sin_port = htons(5555); 吗? memcpy(&sock.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent>h_length); Result = bind(SnifferSocket, (PSOCKADDR) &sock, sizeof(sock));
SrcPort; DstPort; Length; Checksum;
26
3 Winpcap概述
Winpcap是libpcap在Win32平台上移植,是一个 用于抓包和网络分析的架构,且开源。 捕获原始数据包 ,包括链路层信息。 有内核级的过滤机制,用户设置非常简单 独立于主机协议(如TCP-IP)而发送和接收原始数 据报。也就是说,winpcap不能阻塞,过滤或控 制其他应用程序数据报的收 发。 很多软件必须安装WinPcap才能用的。比如 wireshark,网络执法管、P2P终结者、QQ第六感 等嗅探和监控软件 。
正常情况下,网卡应该只接收这样的包
网卡完成收发数据包的工作,两种接收模式
为了监听网络上的流量,必须设置为混杂模式
10
共享网络和交换网络
共享式网络
通过网络的所有数据包发往每一个主机 最常见的是通过HUB连接起来的子网
交换式网络
通过交换机连接网络 由交换机构造一个“MAC地址-端口”映射表 发送包的时候,只发到特定的端口上
17
IP数据报格式
0 15 16 服务类型 头部长度 版本 总长度(字节数) (TOS) 3位 段偏移 标识符 标志 生存时间 协议 头部校验和 (TTL) 34 78 31
20字节
源IP地址 目的IP地址 选项(如果有)
数据
18
IP头
struct IPHeader { unsigned char Version_HLen; unsigned char TOS; unsigned short Length; unsigned short Ident; unsigned short Flags_Offset; unsigned char TTL; unsigned char Protocol; unsigned short Checksum; unsigned int SourceAddr; unsigned int DestinationAddr; };
11
关键代码4:读取数据
char Packet[60000]; Result = recv (SnifferSocket, Packet, sizeof(Packet), 0); 还有没有更好的处理? struct sockaddr_in from; int fromlen ; Result = recvfrom (SnifferSocket, Packet, sizeof(Packet), 0, (struct sockaddr*)&from,&fromlen);
假设已获取一个ip头部的 指针ip,如何获取版本信 息呢?
ip->Version_HLen >> 4
如何获取头部长度呢? (ip->Version_HLen &0x0f) *4
如何更好的定义版本 和头部长度字段?
19
IP协议分析
获取一个ip包Packet 强制类型转换 struct IPHeader *ip = (struct IPHeader*)Packet; 现在就可根据数据结构IPHeader和ip头的标 准,来获取ip头部各个字段的值 参见p233-p234的相关代码,应该写成子函 数的形式。
2
主要内容
用原始Socket抓包 进行协议分析 使用开发工具包WinPcap抓包
3
1. 用原始Socket抓包流程
1. 2.
3. 4. 5.
创建原始Socket 获取一个需要监听网络接口的ip地址,并 绑定(必须要显示绑定) 设置网卡为混杂模式 开始循环接收数据 关闭Socket
4
关键代码1:创建原始Socket
20
如何判断传输层的协议
#define TCP_PROTOCAL #define UDP_PROTOCAL 6 17
unsigned char Prot=ip->Protocol;
21
TCP包首部数据格式
源端口号
( 16位)
目的端口号
( 16位)
A P R S F 首部长 保留 U R C S S Y I 度(4位) (6位) G K H T N N 校验和(16位)
序号(32位) 确认序号(32位)
窗口大小
(16位)
紧急指针(16位) 填充
选项(任选,若有)
紧急数据
数据
22
TCP头
struct TcpHeader { unsigned short SrcPort; unsigned short DstPort; unsigned int SequenceNum; unsigned int Acknowledgment; unsigned char HdrLen; unsigned char Flags; unsigned short AdvertisedWindow; unsigned short Checksum; unsigned short UrgPtr; };
SnifferSocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (Result == SOCKET_ERROR) { printf("socket failed with error %d\n", WSAGetLastError()); return 0; }
7
获取本地接口的更好方法
SOCKADDR_IN char short char input; remoteip[]="8.8.8.8";//可以是任意地址 remoteport=80; buf[1024];
input.sin_family = AF_INET; input.sin_addr.s_addr = inet_addr(remoteip); input.sin_port = htons(remoteport); Result = WSAIoctl (SnifferSocket, SIO_ROUTING_INTERFACE_QUERY, &input, sizeof(input), buf, 1024, &dwBytesRet, NULL, NULL); SOCKADDR_IN *lpIf = (SOCKADDR_IN *)buf; sock.sin_addr=lpIf->sin_addr;
12
阅读p227-229的代码 课后请上机测试,并运行 注意:编译时可能报错,找不到头文件 mstcpip.h,请自己上网查找资料来解决。
13
使用原始socket抓包的缺点
要求管理员权限; 在windows 7之前,该方法只能抓到进来的 包; 没有内核级的过滤机制,只能有程序员自 己来过滤,既复杂又很慢,在千兆网上很 容易丢包; 不能获取链路层信息; 不能获取arp包。
14
2. 进行协议分析
目的:对抓获的包进行分析,是不是ip包, ip的头部各个字段是什么,是不是tcp或udp 报文等待? 故首先我们需要对ip,tcp和udp等协议有所 了解,特别是它们的头部字段。
15
2.1 TCP/IP协议族中的协议
用户进程 用户进程 用户进程 用户进程 应用层
TCP
UDP
假设已获取一个 tcp 头部 的指针 tcp ,如何获取源 端口?
ntohs(tcp->SrcPort)
如何判断是不是 SYN 包?
(tcp->Flags &0x02) >0?1:0
23
TCP协议分析
已有一个IP头指针ip 强制类型转换 struct TcpHeader *tcp = (struct TcpHeader*)(ip + 20); struct TcpHeader *tcp = (struct TcpHeader*)((char *)ip + IpHeaderLength); 现在就可根据数据结构TcpHeader和tcp头的标准, 来获取tcp头部各个字段的值 参见p234-p235的相关代码,应该写成子函数的 形式。
传输层
那我们发送和接收 的数据包的大致格式 是什么样的?请以一 ICMP 个网页包为例来说明。
ARP
IP
IGMP
网络层
硬件接口
RARP
网络接口层
媒体
16
2.2 协议分析的难点
在前面抓包程序的基础上,增加简单的协 议分析。 协议分析的实质就是识别各个协议头,及 其头部各个字段的含义。 故为了程序的处理,必须定义协议头的数 据结构。
29
3.1 网络设备的发现
int pcap_findalldevs( pcap_if_t **alldev, char *errbuf);
网络安全编程技术
第3讲:数据包的捕获与分析
任德斌
本讲编程训练目标
编程实现一个协议分析器。该协议分析器将包 含以下几部分功能 :
1. 2. 3. 4.
数据采集——捕捉Ethernet网络数据包; 解析Ethernet网数据帧头部的全部信息; 解析IP数据包的头部信息; 解析TCP和UDP包的头部信息;
5
原始socket的特点
应用程序可以收到目标是其它主机的包 应用程序会收到ip包 如果设置IP_HDRINCL 选项,可以手动设置 发送的ip包的头部 不能拦截数据,因为系统采用的是拷贝的方 式 由于安全原因,在xp-sp2,windows 7中原 始socket的使用有限制:
27
Winpcap的安装
下载winpcap的驱动程序和相应版本的 wpdpack开发包 安装驱动 把wpdpack开发包解压到自己选定的目录 在vc中(tools->option->directories)设定 include目录和library目录 连接wpcap.lib
28
数据包捕获流程图
8
关键代码3:设置为混杂模式
u_long InOutParam=1; Result =ioctlsocket(SnifferSocket, SIO_RCVALL, &InOutParam);
参数InOutParam表示命令SIO_RCVALL 的输 入参数 WSAIoctl是相应的Winows扩展函数,更复杂, 更强大。
24
Biblioteka Baidu
UDP报文格式
端口号:表示发送进程和接收进程 UDP长度:包括UDP头和UDP数据 UDP报文校验和:可选,为0表示不做校验
25
UDP头
struct UdpHeader { unsigned short unsigned short unsigned short unsigned short }; 简单得多
pcap_findalldevs() 获取 网络设备列表 pcap_open_live() 打开设备, 设为混杂模式 pcap_compile() 编译过滤器
pcap_setfilter() 设置过滤器
pcap_next_ex() 循环捕获数据包
PacketHandler() 处理数据包
pcap_freealldevs() 关闭网络设备
以太网卡的工作模式
网卡的MAC地址(48位)
通过ARP来解析MAC与IP地址的转换 用ipconfig/ifconfig可以查看MAC地址
MAC地址与自己相匹配的数据帧 广播包 混杂模式:不管数据帧中的目的地址是否与自己的地址匹配, 都接收下来 非混杂模式:只接收目的地址相匹配的数据帧,以及广播数 据包(和组播数据包)
不能发送tcp包 不能使用伪造的原ip地址
6
关键代码2:绑定到一个本地IP地址
Result = gethostname(Name, 255); 想 想 看 这 里 端 口 号 有没有意义,这个 pHostent = (struct hostent*)malloc(sizeof(struct 值合不合适 hostent)); pHostent = gethostbyname(Name); SOCKADDR_IN sock; sock.sin_family = AF_INET; 一定是第一个接口 sock.sin_port = htons(5555); 吗? memcpy(&sock.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent>h_length); Result = bind(SnifferSocket, (PSOCKADDR) &sock, sizeof(sock));
SrcPort; DstPort; Length; Checksum;
26
3 Winpcap概述
Winpcap是libpcap在Win32平台上移植,是一个 用于抓包和网络分析的架构,且开源。 捕获原始数据包 ,包括链路层信息。 有内核级的过滤机制,用户设置非常简单 独立于主机协议(如TCP-IP)而发送和接收原始数 据报。也就是说,winpcap不能阻塞,过滤或控 制其他应用程序数据报的收 发。 很多软件必须安装WinPcap才能用的。比如 wireshark,网络执法管、P2P终结者、QQ第六感 等嗅探和监控软件 。
正常情况下,网卡应该只接收这样的包
网卡完成收发数据包的工作,两种接收模式
为了监听网络上的流量,必须设置为混杂模式
10
共享网络和交换网络
共享式网络
通过网络的所有数据包发往每一个主机 最常见的是通过HUB连接起来的子网
交换式网络
通过交换机连接网络 由交换机构造一个“MAC地址-端口”映射表 发送包的时候,只发到特定的端口上
17
IP数据报格式
0 15 16 服务类型 头部长度 版本 总长度(字节数) (TOS) 3位 段偏移 标识符 标志 生存时间 协议 头部校验和 (TTL) 34 78 31
20字节
源IP地址 目的IP地址 选项(如果有)
数据
18
IP头
struct IPHeader { unsigned char Version_HLen; unsigned char TOS; unsigned short Length; unsigned short Ident; unsigned short Flags_Offset; unsigned char TTL; unsigned char Protocol; unsigned short Checksum; unsigned int SourceAddr; unsigned int DestinationAddr; };
11
关键代码4:读取数据
char Packet[60000]; Result = recv (SnifferSocket, Packet, sizeof(Packet), 0); 还有没有更好的处理? struct sockaddr_in from; int fromlen ; Result = recvfrom (SnifferSocket, Packet, sizeof(Packet), 0, (struct sockaddr*)&from,&fromlen);
假设已获取一个ip头部的 指针ip,如何获取版本信 息呢?
ip->Version_HLen >> 4
如何获取头部长度呢? (ip->Version_HLen &0x0f) *4
如何更好的定义版本 和头部长度字段?
19
IP协议分析
获取一个ip包Packet 强制类型转换 struct IPHeader *ip = (struct IPHeader*)Packet; 现在就可根据数据结构IPHeader和ip头的标 准,来获取ip头部各个字段的值 参见p233-p234的相关代码,应该写成子函 数的形式。
2
主要内容
用原始Socket抓包 进行协议分析 使用开发工具包WinPcap抓包
3
1. 用原始Socket抓包流程
1. 2.
3. 4. 5.
创建原始Socket 获取一个需要监听网络接口的ip地址,并 绑定(必须要显示绑定) 设置网卡为混杂模式 开始循环接收数据 关闭Socket
4
关键代码1:创建原始Socket
20
如何判断传输层的协议
#define TCP_PROTOCAL #define UDP_PROTOCAL 6 17
unsigned char Prot=ip->Protocol;
21
TCP包首部数据格式
源端口号
( 16位)
目的端口号
( 16位)
A P R S F 首部长 保留 U R C S S Y I 度(4位) (6位) G K H T N N 校验和(16位)
序号(32位) 确认序号(32位)
窗口大小
(16位)
紧急指针(16位) 填充
选项(任选,若有)
紧急数据
数据
22
TCP头
struct TcpHeader { unsigned short SrcPort; unsigned short DstPort; unsigned int SequenceNum; unsigned int Acknowledgment; unsigned char HdrLen; unsigned char Flags; unsigned short AdvertisedWindow; unsigned short Checksum; unsigned short UrgPtr; };
SnifferSocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (Result == SOCKET_ERROR) { printf("socket failed with error %d\n", WSAGetLastError()); return 0; }
7
获取本地接口的更好方法
SOCKADDR_IN char short char input; remoteip[]="8.8.8.8";//可以是任意地址 remoteport=80; buf[1024];
input.sin_family = AF_INET; input.sin_addr.s_addr = inet_addr(remoteip); input.sin_port = htons(remoteport); Result = WSAIoctl (SnifferSocket, SIO_ROUTING_INTERFACE_QUERY, &input, sizeof(input), buf, 1024, &dwBytesRet, NULL, NULL); SOCKADDR_IN *lpIf = (SOCKADDR_IN *)buf; sock.sin_addr=lpIf->sin_addr;
12
阅读p227-229的代码 课后请上机测试,并运行 注意:编译时可能报错,找不到头文件 mstcpip.h,请自己上网查找资料来解决。
13
使用原始socket抓包的缺点
要求管理员权限; 在windows 7之前,该方法只能抓到进来的 包; 没有内核级的过滤机制,只能有程序员自 己来过滤,既复杂又很慢,在千兆网上很 容易丢包; 不能获取链路层信息; 不能获取arp包。
14
2. 进行协议分析
目的:对抓获的包进行分析,是不是ip包, ip的头部各个字段是什么,是不是tcp或udp 报文等待? 故首先我们需要对ip,tcp和udp等协议有所 了解,特别是它们的头部字段。
15
2.1 TCP/IP协议族中的协议
用户进程 用户进程 用户进程 用户进程 应用层
TCP
UDP
假设已获取一个 tcp 头部 的指针 tcp ,如何获取源 端口?
ntohs(tcp->SrcPort)
如何判断是不是 SYN 包?
(tcp->Flags &0x02) >0?1:0
23
TCP协议分析
已有一个IP头指针ip 强制类型转换 struct TcpHeader *tcp = (struct TcpHeader*)(ip + 20); struct TcpHeader *tcp = (struct TcpHeader*)((char *)ip + IpHeaderLength); 现在就可根据数据结构TcpHeader和tcp头的标准, 来获取tcp头部各个字段的值 参见p234-p235的相关代码,应该写成子函数的 形式。
传输层
那我们发送和接收 的数据包的大致格式 是什么样的?请以一 ICMP 个网页包为例来说明。
ARP
IP
IGMP
网络层
硬件接口
RARP
网络接口层
媒体
16
2.2 协议分析的难点
在前面抓包程序的基础上,增加简单的协 议分析。 协议分析的实质就是识别各个协议头,及 其头部各个字段的含义。 故为了程序的处理,必须定义协议头的数 据结构。
29
3.1 网络设备的发现
int pcap_findalldevs( pcap_if_t **alldev, char *errbuf);
网络安全编程技术
第3讲:数据包的捕获与分析
任德斌
本讲编程训练目标
编程实现一个协议分析器。该协议分析器将包 含以下几部分功能 :
1. 2. 3. 4.
数据采集——捕捉Ethernet网络数据包; 解析Ethernet网数据帧头部的全部信息; 解析IP数据包的头部信息; 解析TCP和UDP包的头部信息;
5
原始socket的特点
应用程序可以收到目标是其它主机的包 应用程序会收到ip包 如果设置IP_HDRINCL 选项,可以手动设置 发送的ip包的头部 不能拦截数据,因为系统采用的是拷贝的方 式 由于安全原因,在xp-sp2,windows 7中原 始socket的使用有限制:
27
Winpcap的安装
下载winpcap的驱动程序和相应版本的 wpdpack开发包 安装驱动 把wpdpack开发包解压到自己选定的目录 在vc中(tools->option->directories)设定 include目录和library目录 连接wpcap.lib
28
数据包捕获流程图
8
关键代码3:设置为混杂模式
u_long InOutParam=1; Result =ioctlsocket(SnifferSocket, SIO_RCVALL, &InOutParam);
参数InOutParam表示命令SIO_RCVALL 的输 入参数 WSAIoctl是相应的Winows扩展函数,更复杂, 更强大。
24
Biblioteka Baidu
UDP报文格式
端口号:表示发送进程和接收进程 UDP长度:包括UDP头和UDP数据 UDP报文校验和:可选,为0表示不做校验
25
UDP头
struct UdpHeader { unsigned short unsigned short unsigned short unsigned short }; 简单得多
pcap_findalldevs() 获取 网络设备列表 pcap_open_live() 打开设备, 设为混杂模式 pcap_compile() 编译过滤器
pcap_setfilter() 设置过滤器
pcap_next_ex() 循环捕获数据包
PacketHandler() 处理数据包
pcap_freealldevs() 关闭网络设备