目的
- 利用原始套接字,在开启了混杂模式的本地网卡上进行嗅探,获取途径本地网卡的IP数据包,并进行解包分析
分析
- socket其实就是操作系统提供给程序员操作网络协议栈的接口,是内核提供的,不是库提供的
- 原始socket可以和内核一样直接对所有层进行操作(除了物理层),可以更改mac更改ip更改端口
- 原始socket可以访问经过网卡的所有数据,普通的socket只能访问发送给自己端口的数据
- 开启混杂模式能让网卡获取流经的所有数据,不只是目的地是自己的数据
- 因此嗅探的关键在于原始套接字+网卡的混杂模式

代码
def sniff(host):
if os.name == 'nt':
socket_protocol = socket.IPPROTO_IP
else:
socket_protocol = socket.IPPROTO_ICMP
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
if os.name == 'nt':
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
try:
while True:
raw_buffer = sniffer.recvfrom(65535)[0]
ip_header = IP(raw_buffer[0:20])
print('Protocol: %s %s -> %s' % (ip_header.protocol, ip_header.src_address, ip_header.dst_address))
except KeyboardInterrupt:
if os.name == 'nt':
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
sys.exit()
- 解析捕获的IP数据包:读取数据包的前20字节的IP头,格式如下所示,可以使用ctypes或struct库将读取到的二进制数据转化为python字符串
- ctypes库:像IP字段定义到一个c结构体里,通过new和init方法,将字段的二进制值转化为python成员变量
- struct库:按照格式化字符串来解析二进制数据,赋值给python对象
- IP头结构:

class IP:
def __init__(self, buff=None):
header = struct.unpack('<BBHHHBBH4s4s', buff)
self.ver = header[0] >> 4
self.ihl = header[0] & 0xF
self.tos = header[1]
self.len = header[2]
self.id = header[3]
self.offset = header[4]
self.ttl = header[5]
self.protocol_num = header[6]
self.sum = header[7]
self.src = header[8]
self.dst = header[9]
self.src_address = ipaddress.ip_address(self.src)
self.dst_address = ipaddress.ip_address(self.dst)
self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}
try:
self.protocol = self.protocol_map[self.protocol_num]
except Exception as e:
print ('%s No protocol for %s' % (e, self.protocol_num))
self.protocol = str(self.protocol_num)
运行结果
- 在windows主机上嗅探流经的数据包,ping百度以后,可以看到成功收到了163.177.151.110的ICMP数据包

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库