python 利用Raw Socket进行以太网帧嗅探

1. Raw Socket基础

  • 提供了一种方法来绕过整个网络堆栈遍历和直接将以太网帧输送到一个应用程序。
  • 有很多种方法来创建raw sockets,例如AF_PACKET,PF_PACKET。这里使用PF_PACKET,它是linux系统上才有的选项,如果是windows或者是mac的系统的话,可以使用AF_PACKET。

1.1 PF_SOCKET

  • 在链路层接收和发送包得应用接口。
  • 所有接收到的包都包含完整的头部和数据部分。
  • 所有发送的包都会由内核无更改的传递到媒介中。
  • 支持使用Berkley Packet 过滤。(更详细信息可参考:http://howtounix.info/man/FreeBSD/man4/bpf.4

2. 创建Raw Socket

2.1 理解Packet Header

  下图为以太网帧头部和IP头部格式示意图:

  以太网帧的头部有14字节,前6字节为目的mac地址,后6字节为源mac地址,之后2字节为内部协议的类型,比如IP协议的类型为0x0800。关于各种协议的类型可在/usr/include/linux/if_ether.h文件中查看(linux系统)。往里一层是IP等网络层协议,IP层内部包含TCP、UDP等传输层协议,再往里就是应用层协议,如HTTP、ssh等。

  图中最下侧是IP的头部格式,最重要的部分是前20字节。

2.2 提取二进制数据到变量中

  • 使用struct模块中的unpack()函数。
  • 返回的时tuple格式。(tuple的更详细内容可参考:廖雪峰讲的python中tuple部分)
  • 第一个字符标明字节序。
    • 网络字节序通常是大端。

举个例子, 终端下输入python,然后进行一下操作:

>>> import struct

>>>

>>>

>>> struct.pack(“B”,1)

‘\x01’

>>> struct.pack(“H”,1)

‘\x01\x00’

>>> struct.pack(“>H”,1)

‘\x00\x01’

>>> struct.pack(“!H”,1)

‘\x00\x01’

>>> struct.pack(“!L”,1)

‘\x00\x00\x00\x01’

>>> exit()

2.3 raw Socket嗅探

主要思路:

  

  • 使用Socket模块。
  • 读取接收到的包。
  • 解释和分析包。
  • 也可以发送应答

linux下打开终端,进入python环境(raw_socket需要root权限,输入命令是要以sudo python命令进入。),依次按一下方式操作:

[email protected]:~/workspace/python$ sudo python

[sudo] password for jeanphorn:

Python 2.7.3 (default, Apr 20 2012, 22:44:07)

[GCC 4.6.3] on linux2

Type “help”, “copyright”, “credits” or “license” for more information.

>>>

>>>

>>>

>>> import socket

>>> import struct

>>> import binascii

>>>

>>>

>>> rawSocket = socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))

>>>

>>> pkt = rawSocket.recvfrom(2048)

>>> pkt

(“\x08\x00’[email protected]\x8f.\xd5\xc4\x08\x00E\x10\x004W\[email protected]\[email protected]\x06_\xf0\xc0\xa8\x01_\xc0\xa8\x01\x0e\xf0u\x00\x16\xa9^i\x03\xe3\xa0V\xb4\x80\x10\x0f\xfeGr\x00\x00\x01\x01\x08\n\x1e\xd3\x0f\xc7\x00\x00/\xb2”, (‘eth0’, 2048, 0, 1, ‘@l\x8f.\xd5\xc4’))

>>> ethernetHeader = pkt[0][0:14]

>>>ethernetHeader

“\x08\x00’[email protected]\x8f.\xd5\xc4\x08\x00”

>>> eth_hdr = struct.unpack(“!6s6s2s”,ethernetHeader)

>>> eth_hdr = struct.unpack(“!6s6s2s”,ethernetHeader)

>>> eth_hdr

(“\x08\x00’5BY”, ‘@l\x8f.\xd5\xc4’, ‘\x08\x00’)

>>> binascii.hexlify(eth_hdr[0])

‘080027354259’

>>> binascii.hexlify(eth_hdr[1])

‘406c8f2ed5c4’

>>> binascii.hexlify(eth_hdr[2])

‘0800’

>>> ipHeader = pkt[0][14:34]

>>> pkt

(“\x08\x00’[email protected]\x8f.\xd5\xc4\x08\x00E\x10\x004W\[email protected]\[email protected]\x06_\xf0\xc0\xa8\x01_\xc0\xa8\x01\x0e\xf0u\x00\x16\xa9^i\x03\xe3\xa0V\xb4\x80\x10\x0f\xfeGr\x00\x00\x01\x01\x08\n\x1e\xd3\x0f\xc7\x00\x00/\xb2”, (‘eth0’, 2048, 0, 1, ‘@l\x8f.\xd5\xc4’))

>>> ip_hdr = struct.unpack(“!12s4s4s”,ipHeader)

>>> ip_hdr

(‘E\x10\x004W\[email protected]\[email protected]\x06_\xf0’, ‘\xc0\xa8\x01_’, ‘\xc0\xa8\x01\x0e’)

>>> socket.inet_ntoa(ip_hdr[1])

‘192.168.1.95’

>>> socket.inet_ntoa(ip_hdr[2])

‘192.168.1.14’

>>> tcpHeader = pkt[0][34:54]

>>> tcp_hdr = struct.unpack(“!HH16s”,tcpHeader)

>>> tcp_hdr

(61557, 22, ‘\xa9^i\x03\xe3\xa0V\xb4\x80\x10\x0f\xfeGr\x00\x00’)


3. 完整的python代码

  将以上代码写在一个packetSniffer.py的文件中,运行时要加上sudo ./packetSniffer.py

#!/usr/bin/env python
# _*_ coding=utf-8 _*_

import socket
import struct
import binascii

rawSocket = socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))

pkt = rawSocket.recvfrom(2048)

ethernetHeader = pkt[0][0:14]   #提取以太网帧头
eth_hdr = struct.unpack("!6s6s2s",ethernetHeader) #6字节目的mac地址,6字节源mac地址,2字节协议类型

binascii.hexlify(eth_hdr[0])
binascii.hexlify(eth_hdr[1])
binascii.hexlify(eth_hdr[2])

ipHeader = pkt[0][14:34]        #提取IP协议头,不包含option和padding字段。
ip_hdr = struct.unpack("!12s4s4s",ipHeader)         # !标示转换网络字节序,前12字节为版本、头部长度、服务类型、总长度、标志等其他选项,后面的两个四字节依次为源IP地址和目的IP地址。

print "source IP address: " + soket.inet_ntoa(ip_hdr[1])

print "destination IP address: " + soket.inet_ntoa(ip_hdr[2])

tcpHeader = pkt[0][34:54]
tcp_hdr = struct.unpack("!HH16s",tcpHeader)

print tcp_hdr
时间: 2024-12-17 15:08:21

python 利用Raw Socket进行以太网帧嗅探的相关文章

python 使用Raw Socket进行以太网帧注入

1. 帧注入 对于以太网帧和Raw Socket的介绍可参考之前的一篇博文利用Raw Socket进行以太网帧嗅探.帧注入的特点: 可以将原数据格式的包注入到网络中. 在模拟网络应答方面很强大. 原始套接字包结构具有不可延展性. 随机注入 如果你可以随机注入数据到网络上的话,你就可以向网络上发送任何数据.^_^ 2. 代码实验 进入python运行环境,需要加上root权限.(sudo python). >>> >>> import socket >>>

python 使用raw socket进行TCP SYN扫描

1. TCP SYN扫描 端口扫描常用于用于探测服务器或主机开放端口情况,被计算机管理员用于确认安全策略,同时被攻击者用于识别目标主机上的可运作的网络服务.端口扫描是向一定范围的服务器端口发送对应请求,以此确认可使用的端口.虽然其本身并不是恶意的网络活动,但也是网络攻击者探测目标主机服务,以利用该服务的已知漏洞的重要手段. TCP SYN扫描是端口扫描众多方式中的一种,其他方式包括TCP扫描,UDP扫描,ACK扫描,窗口扫描和FIN扫描等. TCP SYN扫描是另一种TCP扫描.端口扫描工具不使

无线网络安全之Python使用RAW sockets 嗅探WIFI的SSID

1. 介绍 随着无线网络的广泛普及,人们越来越频繁的使用无线网络,他改变了人们的生活方式.现在很多人走到一个地方,首先要问的第一句就是"这里有没有WIFI?"但随之出现的无线网络安全问题却没有引起人们足够的重视.在一些公众场合,例如机场,火车站,咖啡厅,餐馆等场所都会设置一些免费的无线WIFI供顾客使用,但是他们的安全性是非常不可靠的.WIFI钓鱼,伪造热点,流量劫持常常在这钟场合下被用来攻击大众场所下连接WIFI的人,从而造成可怕的信息泄露事件. 本片文章主要WIFI热点广播信号的B

python raw socket 介绍

因为要使用 python 底层发包模块,也就是 raw socket 发包模式,所以在此深入了解一下 python socket 通信. 涉及到的函数: import socket socket() setsockopt() sendto() recvfrom() 因为使用的是原始套接字,所以我们不使用bind/connect函数,参照<unix 网络编程> bind 函数仅仅设置本地地址.就输出而言,调用bind函数设置的是将用于从这个原始套接字发送的所有数据报的源IP地址.如果不调用bin

以太网帧结构解析

由于需要做一个分析网卡接收的数据包的Project,需要了解以太网帧结构并解析,发现有很多内容从一般网络方面的知识是不够的,因此查阅了相关资料再此做一个记录以备忘. 以太网是目前最流行的有线的局域网技术,特别是上世纪九十年后发展的交换式局域网增加了有效数据速率,同时集线器和交换机等普通且便宜的硬件更助长了其普及程度.以太网的数据帧格式如下图所示: 数据字段:在交换式以太网中,一台主机向局域网中的另一台主机发送一个IP数据报,这个数据报封装在以太网帧结构中作为其有效载荷,以太网的最大传输单元(MT

raw socket 发送数据包

TRawSocket = class(TObject) private buf: array[0..BUFLEN - 1] of char; FdwNotifyWnd: Cardinal; hsocket: Cardinal; str: string; public constructor Create; destructor Destroy; override; function createSocket: Integer; procedure destroySocket; function

C++和python利用struct结构传输二进制数据实现

网络编程中经常会涉及到二进制数据传输的问题,在C++中常用的传输方式有文本字符串和结构体封包.如果能将要发送的数据事先放进连续的内存区,然后让send函数获取这片连续内存区的首地址就可以完成数据的发送了,文本字符串如char型数组,以字节为单位,在内存中是顺序存储的,所以可以直接用send函数发送.但是如果要同时发送多个不同类型的数据时,它们在内存中存储的地址是随机的,不是顺序存储的,而且它们之间的相对位置也无法确定,这样就需要一种数据组织方式来明确各数据之间的相对位置.结构体显然就是一种的数据

python基础之socket与socketserver

---引入 Socket的英文原义是"孔"或"插座",在Unix的进程通信机制中又称为'套接字'.套接字实际上并不复杂,它是由一个ip地址以及一个端口号组成.Socket正如其英文原意那样,像一个多孔插座.一台主机犹如布满各种插座(ip地址)的房间,每个插座有很多插口(端口),通过这些插口接入电线(进程)我们可以烧水,看电视,玩电脑-- 应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 套接字的作用之一就是用来区分不同应用进程,当某个进

【计算机网络】以太网帧,IP,TCP,UDP首部结构

1.以太网帧的格式 以太网封装格式 2.IP报头格式 IP是TCP/IP协议簇中最为重要的协议.所有的TCP,UDP, ICMP和IGMP数据都以IP数据报格式传输.IP提供的是不可靠.无连接的协议. 普通的IP首部长为20个字节,除非含有选项字段. 4位版本:目前协议版本号是4,因此IP有时也称作IPV4. 4位首部长度:首部长度指的是首部占32bit字的数目,包括任何选项.由于它是一个4比特字段,因此首部长度最长为60个字节. 服务类型(TOS):服务类型字段包括一个3bit的优先权字段(现