
信号中bpf数据链路层(Data Link Layer)是OSI参考模型第二层,位于物理层与网络层之间。
在广播式多路访问链路中(局域网),由于可能存在介质争用,它还可以细分成介质访问控制(MAC)子层和逻辑链路控制(LLC)子层,介质访问控制(MAC)子层专职处理介质访问的争用与冲突问题。
不管是在传统的有线局域网(LAN)中还是在流行的无线局域网(WLAN)中,MAC协议都被广泛地应用。在传统局域网中,各种传输介质的物理层对应到相应的MAC层,普遍使用的网络采用的是IEEE802.3的MAC层标准,采用CSMA/CD访问控制方式;而在无线局域网中,MAC所对应的标准为IEEE802.11,其工作方式采用DCF(分布控制)和PCF(中心控制)。
介质访问子技术:
介质访问子层的中心论题是相互竞争的用户之间如何分配一个单独的广播信道。
1、静态分配:只要一个用户得到了信道就不会和别的用户冲突。(用户数据流量具有突发性和间歇性) 。
2、动态分配:称为多路访问或多点接入,指多个用户共用一条线路,而信道并非是在用户通信时固定分配给用户,这样的系统又称为竞争系统。
3、信道动态分配中的5个关键假设。
站模型:站独立,以恒定速率产生帧,每个站只有一个程序。
冲突假设:两个帧同时传送,就会冲突,所有站点能检测到,冲突帧需重发。
以上内容参考 百度百科-bpf
以上内容参考 百度百科-OSI参考模型
包0. 前言
来源:《Computer Security》A Hands-on Approach — Wenliang Du
所有的代码/文档见github:https://github.com/da1234cao/computer_security
chapter 12 Packet sniffing and spoffing.
这一章有点硬核。知识点不难,但对socket编程有点要求。
我看过《unix网络编程》第一卷 前五章 ,背景知识还是相当欠缺。这章内容虽然看完,基本明白,但距离实际动手完成一个简单的有线/无线嗅探工具还挺远。本文,暂时仅仅看看书上的嗅探实现。
1. 摘要与总结
首先介绍了网卡的工作原理,嗅探需要网卡的工作模式(杂乱模式/监控模式)。
为了提早过滤过滤不需要的数据包,介绍了BPF。
接着用三种方式:普通套接字,原生套接字,pcap API,递进的讲述了包的嗅探过程。
2. 包(Packet)的接收
2.1 网卡
参考文章:网卡工作原理详解 、关于网络的混杂模式 、实战无线网络分析(篇一)无线监听
简单了解下:
网卡(Network Interface Card,NIC)是一块被设计用来允许计算机在计算机网络上进行通讯的计算机硬件。每块网卡有一个硬件地址,被称为MAC地址;网卡接入网络,使得用户可以通过电缆或无线相互连接;用户A要发送信息给B,通过电缆或者无线进行广播;每一块网卡都将广播的内容拷贝到自己的网卡内存中,检查头部信息中的MAC地址,判断是否是发送给自己的。如果是则将其拷贝进入内存,否则丢弃;因为MAC唯一,所以最后只有B接受了用户A的信息。
维基百科:混杂模式(promiscuous mode)。一般计算机网卡都工作在非混杂模式下,此时网卡只接受来自网络端口的目的地址指向自己的数据。当网卡工作在混杂模式下时,网卡将来自接口的所有数据都捕获并交给相应的驱动程序。网卡的混杂模式一般在网络管理员分析网络数据作为网络故障诊断手段时用到,同时这个模式也被网络黑客利用来作为网络数据窃听的入口。在Linux *** 作系统中设置网卡混杂模式时需要管理员权限。在Windows *** 作系统和Linux *** 作系统中都有使用混杂模式的抓包工具,比如著名的开源软件Wireshark。
监控模式(monitor mode)。 类似于有线网络的混杂模式。 无线网卡在监视模式下运行时支持嗅探。 与以太网不同,无线设备面临附近其他设备的干扰。 这将严重阻碍网络连接的性能。 为解决此问题,WIFI设备在不同的信道上传输数据。接入点将附近的设备连接到不同的信道,以减少它们之间的干扰影响。 Wifi网卡还设计为在整个可用带宽和通道的片上进行通信。 将这些卡置于监视模式时,它们将捕获802. 1I帧,这些帧在它们正在侦听的通道上传输。 这意味着,与以太网不同,无线网卡可能会丢失同一网络上的信息,因为它位于不同的信道上。 大多数无线网卡不支持监视器模式或制造商禁用了该模式。
2.2 (BSD Packet Filter)BPF
参考文章:BPF与eBPF
这个参考文章我没懂。目前大概知道怎么回事就好。后面使用pcap API会用到这里的概念。
嗅探网络流量时,嗅探器只对某些类型的数据包感兴趣,例如TCP数据包或DNS查询数据包,这是很常见的。系统可以将所有捕获的数据包提供给嗅探器程序,后者可以丢弃不需要的数据包。这是非常低效的,因为处理这些不需要的数据包并将其从内核传送到嗅探器应用程序需要花费时间。当有很多不需要的数据包时,浪费的时间相当可观。最好尽早过滤这些不需要的数据包。
随着对数据包捕获的需求的增加,Unix *** 作系统定义了BSD数据包过滤器(BSD Packet Filter,BPF)以支持较低级别的过滤。 BPF允许用户空间程序将过滤器附加到套接字,这实际上是告诉内核尽早丢弃不需要的数据包。过滤器通常使用布尔运算符以人类可读的格式编写,并被编译为伪代码并传递给BPF驱动程序。然后由BPF伪机(一个专门为数据包过滤设计的内核级状态机)解释该低级代码。
3. 包的嗅探
3.1 通常套接字编程接收包
/**
* 作用:将进入服务器所有IP的9090端口的UDP内容,输出。
*
* 准备:
* 一个套接字描述符:scoket函数,指定期望的通信协议类型
* 一个监听套接字:指定协议族,ip,端口
* bind:将一个本地协议地址赋予一个套接字(描述符)
* recvfrom:接受经指定的socket 传来的数据,放入buf --》准备个buffer,一个客户端套接字,套接字长度
*
* 头文件:
* netinet/in.h 定义了ip地址结构 struct sockaddr_in (struct in_addr作为sockaddr_in 的成员)
* 还有函数 htons等,以及一些宏。
* sys/socket.h 定义了一些列的socket API函数 如
* socket(),bind() listen() , send() ,sendmsg(),setsockopt(),等等。
* unistd.h close函数
*
* 验证:echo "Hello World\!" | nc -4u 127.0.0.1 9090
*/
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
int main(void){
int sock
struct sockaddr_in server
int client_len
struct sockaddr_in client
char buf[1000]
// IPV4,数据包套接字,UDP传输协议
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)
if(sock <= 0){
perror("error in socket")
return -1
}
// 用这个初始化为零,比memset函数少一个参数
// sockaddr_in结构体中sin_zero,还没用;整个结构体用之前,我们全部初始化为零
// IPv4协议族,监听该服务器上所有IP的9090端口
// 按照网络标准转化字节序
bzero(&server,sizeof(server))
server.sin_family = AF_INET
server.sin_addr.s_addr = htonl(INADDR_ANY)
server.sin_port = htons(9090)
// 将一个本地协议地址赋予一个套接字(描述符)
if( bind(sock,(struct sockaddr *)&server,sizeof(server)) <0){
perror("error in bind")
return -1
}
while (1){
bzero(buf,sizeof(buf))
// 进入一个慢系统调用;
recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr *)&client,&client_len)
printf("%s",buf)
}
close(sock)
return 0
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
3.2 使用原生套接字接收包
络数据截获方法网络数据包截获机制是网络入侵检测系统的基础组件。一般指通过截获整个网络的所有信息流量,根据信息源主机,目标主机,服务协议端口等信息简单过滤掉不关心的数据,再将用户感兴趣的数据发送给更高层的应用程序进行分析。流程图如下:
图5.1 网络数据截获流程
一方面要,网络截取模块要能保证截取到所有网络上的数据包,尤其是检测到被分片的数据包(这可能蕴涵着攻击)。
另方面,数据截取模块截取数据包的效率也是很重要的。
它直接影响整个入侵检测系统的运行速度。
5.2各种数据流截获方法
5.2.1 利用广播截取网络数据流
数据包的截取技术是依赖网卡的。而网卡可以通过广播监听到以太网络上的数据包,这就是数据包截取技术的基础。
要想截获不是给自己数据流,就必须绕开系统正常工作的机制,直接通过网卡的混杂模式,使之可以接受目标地址不是自己的MAC地址的数据包,直接访问数据链路层,取数据。
5.2.2各系统截取数据包机制
Linux系统为用户提供一种在理论上是数据链路层的,基于网卡驱动程序的,可以不用 *** 作系统自身协议栈的接口(也称套接字)-SockPacket. 这种套接字可以从数据链路层(就是网线)上直接截取所有链路层数据包。而Unix则是通过Libpcap库直接与内核交互,实现网络截取。如:Libpcap,Tcpdump等。如图:
Unix系统监听机制
BSD Packet Filter(BPF)机制来截取数据包。BPF可以说是各系统中最棒的截获方式。很多开源嗅探工具就是基于它而开发的。Windows系统也有类似情况,如:win系列上有*.vxd (VxD,VirtualDeviceDrive)(packet*.vxd) 和 网卡.sys(为网卡芯片所开发)来驱动网卡截取数据包。
图5.3 Windows系统监听机制
5.2.3 BPF过滤
Unix&Linux系统有两种数据链路层截取机制,分别是BSD系列系统(NetBSD,OpenBSD,FreeBSD等)的BPF和Linux的SOCKET_PACKET。
BPF过滤
BPF主要由两大部分组成:
网络头接口
数据包过滤器。
网络头接口从网络设备驱动程序处收集数据包复制(在提交给系统协议栈之前),并传递给正在截获数据包的应用程序。而过滤器决定某一数据包是被接受或者拒绝以及如果被接受,数据包的那些部分会被复制给应用程序。BPF结构图如下:
图5.4 BPF结构示意图
如:TCPDump注:(1), Libpcap, Sniffer, eeye,等。一般情况,网卡驱动通过网卡把网络上的电平信号转化成数据包,再把截取到的数据传给系统自带的协议栈,然后在交由系统处理。这种方式与Unix下的BPF不同,它使得网卡驱动在把从网络截取的数据提交给系统之前,先拷贝一份给BPF,再由BPF 决定是否符合规则,不符合则丢弃,符合则存放到内存指定区,等待处理。
当然,BPF对网卡驱动交给系统协议栈的数据包不做任何干涉。
注1:TCPDump是伯克利实验室的Van Jacobson,Craig Leres和Stenven McCanne为分析TCP性能问题而写的跨平台的监听程序。
5.3基于Libpcap库的通用数据截获技术
Libpcap是用户态的数据包截获API函数接口,有独立和可移植行。最初,Libpcap是为了强大的,健壮TCPDump而编写的。它支持BPF过滤机制。Snort就是依赖于libpcap库进行数据包截取的程序之一(还有Ethereal,eeye等)。 它的优点是可以从任何Unix内核平台上截取数据包,而不考虑什么芯片类型的网卡和驱动程序。更重要的是,它可以使开发人员编写自己的解码,显示,记录等程序。
5.2.2.1 Libpcap库主要函数
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)