Promiscuous Mode
简介
Monitor mode 与 promiscuous mode 比较
这是在网卡上的的两个特殊的模式,简而言之,都是将网卡的过滤器关闭。
- Monitor mode
这是我们常常提到的sniffer mode。它用于无线网络中,无线网卡开启监听模式,监听空气中的所有数据包,其中它还可以切换channel。如果设置得当,可以同时监控所有信道的帧(切换式,或者同时多个网卡监听)。在这个模式下面,STA是没有连接到AP的。除了能够得到数据包之外,还可以得到控制帧和管理帧。对于debug 802.11的问题(omnipeek or wireshark in linux)或者攻击一个802.11的网络(aircrack、reaver),常常会使网卡进入到这个模式。此文重点在于promiscuous mode,802.11的monitor mode不再赘述。
- Promiscuos mode
不处于promiscuous mode的网卡只会收取DA会自身的数据包或者BC/MC的数据包。在promiscuos mode下面,网卡会收到DA不是自身的包,在进入这个模式的时候,常常会开启一个raw socket,来接收网卡传递上来的数据。
打开promiscuous mode
翻阅libpcap的源码,可以整理出这两种方式,可以打开promiscuous mode:
(activate_new) – new way
1.Try to open a packet socket using the new kernel PF_PACKET interface
2.Select promiscuous mode on
struct packet_mreq mr; memset(&mr, 0, sizeof(mr)); mr.mr_ifindex = handlep->ifindex; mr.mr_type = PACKET_MR_PROMISC; sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); setsockopt(sock_fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr))
setsockopt 原型如下:
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
对应于内核的 /include/net/sock.h
(setsockopt)(struct sock sk, int level, int optname, char __user *optval, unsigned int optlen);
net/packet/af_packet.c
里面有对应的操作:
static int packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) {struct sock *sk = sock->sk;struct packet_sock *po = pkt_sk(sk);int ret;if (level != SOL_PACKET)return -ENOPROTOOPT;switch (optname) {case PACKET_ADD_MEMBERSHIP:case PACKET_DROP_MEMBERSHIP:{struct packet_mreq_max mreq;int len = optlen;memset(&mreq, 0, sizeof(mreq));if (len sizeof(mreq))len = sizeof(mreq);if (copy_from_user(&mreq, optval, len))return -EFAULT;if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))return -EINVAL;if (optname == PACKET_ADD_MEMBERSHIP)ret = packet_mc_add(sk, &mreq);elseret = packet_mc_drop(sk, &mreq);return ret;}
调用流程:
packet_mc_add -> packet_dev_mc -> dev_set_promiscuity(net/core/dev.c)
dev_set_promiscuity的定义如下:
int dev_set_promiscuity(struct net_device *dev, int inc) {unsigned int old_flags = dev->flags;int err;err = __dev_set_promiscuity(dev, inc, true);if (err <0 return err if dev->flags != old_flags)dev_set_rx_mode(dev);return err; }
__dev_set_promiscuity => dev->flags |= IFF_PROMISC; dev_change_rx_flags(dev, IFF_PROMISC); ops(net_device_ops)->ndo_change_rx_flags(dev, flags);
dev_set_rx_mode(dev); ==> ops(net_device_ops)->ndo_set_rx_mode(dev);
驱动基本上只实现了ndo_set_rx_mode
选择一个Ethernet驱动作为例子:
const struct net_device_ops ei_netdev_ops = {.....ndo_open = ei_open,.ndo_stop = ei_close,.ndo_start_xmit = ei_start_xmit,.ndo_set_rx_mode = ei_set_multicast_list, };
ei_set_multicast_list -> __ei_set_multicast_list -> do_set_multicast_list
static void do_set_multicast_list(struct net_device *dev) {....if (dev->flags&IFF_PROMISC) {memset(ei_local->mcfilter, 0xFF, 8);ei_outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR);} }
这边可以看到驱动设置了EN0_RXCR,含义猜测是RX config register,将RX的接收状态设置为accept all。所以说,设置设备进入promiscuous mode,实际上是设置硬件寄存器ndo_set_rx_mode
,需要设备的驱动支持。
(activate_old) – old way
struct ifreq ifr; ifr.ifr_flags |= IFF_PROMISC; ioctl(handle->fd, SIOCSIFFLAGS, &ifr)
这种开启方法,多个开启混杂模式的程序可能会干扰,容易出问题,不推荐使用。
在 net/core/dev_ioctl.c
=> dev_ifsioc
=> dev_change_flags
=> __dev_change_flags
=> dev_set_rx_mode
下面的路径就和上一种方法一样了,不再赘述。可以了解到,在底层的操作,两个做法都是一样的,都是关闭了网卡的过滤器。
如何判断一个机器位于promiscuous mode
既然网卡驱动放行了所有的数据包并且将数据包上传TCPIP协议栈,那么这里可以使用一个技巧。将进入promiscuous mode的主机设为A。从同一网段的B主机伪造一个目标MAC地址不是A,但是目标ip地址是A的包。当正常的主机收到这个包的时候,网卡驱动或者网卡的asic就会将它丢弃,当这个主机进入promiscuous mode之后,网卡驱动放行这个包,TCPIP协议栈检查这个包的目标地址是A,所以会产生一个回应到B主机。当然了,如果主机A特意将TCPIP协议栈的收发包路径关掉,那么就无法侦测到了。
另外,如果我伪造了一个不存在的mac地址,那么交换机就不知道这个mac地址是位于哪个端口,它也会帮忙转发到所有端口。
比如我从B主机伪造一个错误MAC地址的ICMP包给A主机,判断A主机是否回应,这样就可以判断出它是否处于promiscuous mode。
MAC | IP | Payload |
---|---|---|
局域网内没有出现过的mac地址 | 192.168.0.5 | xxxxxxxx |
做一个测试
测试环境: ubuntu 12.4 + win10
测试网卡:Ethernet 网卡
测试软件:wireshark,ICMP c语言测试程序
两端的ip:192.168.0.4,192.168.0.5
测试方式:直连,家用路由器LAN口转发
下面是测试的过程。首先我在目标机器上面(win10)开启了wireshark,并且监听本地连接。这时候我伪造了一个错误的MAC DA,但是其他参数,比如对方的ip地址是填写正确的。这时候本机的wireshark可以看到对方的ICMP回应。紧接着我关闭win10上面的wireshark,ICMP回应消失。随后我又开启wireshark,又可以得到ICMP回应了。测试的时候,两台机器使用网线直连或者通过家用路由器的LAN口转发都是成功的,但是使用无线网络的时候是失败的,可能是无线网卡不支持promiscuous mode。注意到,因为是要伪造MAC地址,所以需要使用PF_PACKET
来操作RAW socket
下图是在ubuntu上面的wireshark截取的
另外,如果两个机器直连测试,需要在windows上面设置静态ip地址(192.168.0.5/24),在linux机器上面关闭界面上的网络连接,并且输入测试网络是否连通:
tanhangbo@ThinkPad:~$ sudo ifconfig eth0 up tanhangbo@ThinkPad:~$ sudo ifconfig eth0 192.168.0.4 tanhangbo@ThinkPad:~$ ping 192.168.0.5 PING 192.168.0.5 (192.168.0.5) 56(84) bytes of data. 64 bytes from 192.168.0.5: icmp_req=1 ttl=128 time=0.312 ms 64 bytes from 192.168.0.5: icmp_req=2 ttl=128 time=0.384 ms 64 bytes from 192.168.0.5: icmp_req=3 ttl=128 time=0.408 ms
实际作用
一般来说,进入这个模式,就是为了多收一些包,进行网络诊断。一般开启wireshark的时候就会帮你打开promiscuous mode。底层操作在libpcap里面。
- 参考资料:
- libpcap和linux kernel 源码
- http://stackoverflow.com/questions/6666257/what-is-the-purpose-of-net-device-uc-promisc-field
转载于:https://www.cnblogs.com/tanhangbo/p/5425382.html
Promiscuous Mode相关推荐
- 详解为何在嵌套ESXi环境下要求开启Promiscuous Mode
原文链接:http://bbs.vmanager.cn/forum.php?mod=viewthread&tid=8688&fromuid=35445 在嵌套环境中,有时候网路不通,此 ...
- Wireshark,Scapy等出现failed to set hardware filter to promiscuous mode解决办法
使用pythonproject 安装 Scapy 在终端执行后,发现snif()出现以下报错: Traceback (most recent call last):File "<con ...
- 网卡混杂模式Promiscuous与linux上混杂模式的设置
1 网卡工作模式 (1) 广播模式(Broad Cast Model):它的物理地址(MAC)地址是 0Xffffff 的帧为广播帧,工作在广播模式的网卡接收广播帧. (2) 多播传送(MultiCa ...
- 网卡 promiscuous mode 与 MAC 的一些 filter 功能
基础知识 以太网包可以分为如下三种类型: 单播 广播 多播 一般来说网卡只接收目的地址是网卡的硬件地址或广播地址的以太网帧,这里硬件地址指的是 48-bit 的 MAC 地址. 网卡接收多播包则以下有 ...
- 使用SharpPCap在C#下进行网络抓包
转自http://www.cnblogs.com/billmo/archive/2008/11/09/1329972.html 在做大学最后的毕业设计了,无线局域网络远程安全监控策略 那么抓包是这个系 ...
- 在Ubuntu 14.04 64位上使用libpcap进行抓包和解包
为了开发需要,我决定使用最新libpcap源码包安装.在Unix环境下安装libpcap库,需要 c编译器,flex,bison等,安装Ubuntu系统时,没有这些包.安装flex需要m4编译环境,否 ...
- Linux tcpdump命令详解与Wireshark
简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据包的 ...
- Tcpdump命令的使用与示例——linux下的网络分析
顾名思义,TcpDump可以将网络中传送的数据包的"头"完全截获下来提供分析.它支持针对网络层.协议.主机.网络或端口的过滤,并提供and.or.not等逻辑语句来帮助你去掉无用的 ...
- 《神探tcpdump第一招》-linux命令五分钟系列之三十五
应 @GamerH2o 博友在微博上提的要求,tcpdump专题会写成一个小型系列文章,力求每篇小文中突出重点,讲解清晰,避免长篇累牍,大家必然昏昏欲睡了. 其实tcpdump就好像一个神探,它有着夜 ...
最新文章
- Genymotion配置及使用教程(最新最完整版附各部分下载地址)最快模拟器
- Mybatis-plus常用API全套教程
- 构建嵌入式版本的 ACE TAO 6.5.3
- 1小时搞懂设计模式之代理模式(静态代理)
- fastadmin model关联模型 关联查询问题
- 类库、通用变量、is和as、委托
- java中什么是匿名接口_Java中接口(interface)和匿名类
- 说下自己看源码的一点经验(Python Web 相关)
- 2020教师计算机考试笔试题,2020教师招聘考试《信息技术》练习题之答案解析
- 科学计算机使用的软件,科学计算器软件有哪些?2020好用的科学计算器推荐
- 开心农场违规 恐面临关停危险
- 电动自行车UL认证安全标准UL2849
- 外牌年检车辆在上海办理年检
- [资源]C++ 程序员必收藏
- 在dropdown item中设置退出登录
- 麻省理工大学计算机博士后收入,申请MIT博后回复及后续 - 海外博后 - 小木虫 - 学术 科研 互动社区...
- java枚举类的使用,以及通过枚举类作为对象内部类实现线程安全
- 面试:Art虚拟机和Davlik虚拟机简要对比
- 爬虫的基本原理:爬虫概述及爬取过程
- SuperMap iServer 分布式切图