使用python抓取经过本机网卡流量


背景:

经过流量劫持后,我们的本机IP就成为了其他设备的网关地址。想查看别人发了什么信息、从哪里来、到哪去,势必要进行流量分析。

又或者我实在是闲的蛋疼无聊,想看下我网卡都经过了什么流量

第一步:

  获取本机IP地址:

1 # 监听主机(获取本机ip)
2 host = socket.gethostbyname(socket.getfqdn(socket.gethostname()))  

第二步:

  创建原始套接字, 然后绑定在公开接口上。

  os.name=="nt"代表windows系统,==“posix”代表linux系统

1 # 创建原始套接字, 然后绑定在公开接口上
2 if os.name == "nt":
3     socket_protocol = socket.IPPROTO_IP
4 else:
5     socket_protocol = socket.IPPROTO_ICMP
6     
7 sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
8 sniffer.bind((host, 0))

第三步:

  捕获数据并设置混杂模式

1 # 设置在捕获的数据包中包含的IP头
2 sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
3     
4 # 在windows平台上, 我们需要设置IOCTL以启用混杂模式
5 if os.name == "nt":
6     sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

第四步:

  使用ip解析报文

 1 class IP(Structure):
 2     _fields_ = [
 3             ("ihl",            c_ubyte, 4),
 4             ("version",        c_ubyte, 4),
 5             ("tos",            c_ubyte),
 6             ("len",            c_ushort),
 7             ("id",             c_ushort),
 8             ("offset",         c_ushort),
 9             ("ttl",            c_ubyte),
10             ("protocol_num",   c_ubyte),
11             ("sum",            c_ushort),
12             ("src",             c_ulong),
13             ("dst",             c_ulong)
14         ]
15     
16     def __new__(self, socket_buffer=None):
17         return self.from_buffer_copy(socket_buffer)
18     
19     
20     def __init__(self, socket_buff=None):
21         # 协议字段与协议名称对应
22         self.protocol_map = {1:'ICMP', 2:'IGMP', 3:'GGP', 4:'IP', 6:'TCP', 17:'UDP', 41:'IPV6'}
23         
24         # 可读性更强的ip地址
25         self.src_address = socket.inet_ntoa(struct.pack("<L", self.src))
26         self.dst_address = socket.inet_ntoa(struct.pack("<L", self.dst))
27         
28         # 协议类型
29         try:
30             self.protocol = self.protocol_map[self.protocol_num]
31         except:
32             self.protocol = str(self.protocol_num)

 

完整代码:

 1 #-*- encoding:utf-8 -*-
 2 '''
 3 Created on 2018年12月8日
 4 
 5 @author: perilong
 6 '''
 7 
 8 from ctypes import *
 9 import os
10 import socket
11 import struct
12 from scapy.sendrecv import sniff
13 
14 
15 # IP头定义
16 class IP(Structure):
17     _fields_ = [
18             ("ihl",            c_ubyte, 4),
19             ("version",        c_ubyte, 4),
20             ("tos",            c_ubyte),
21             ("len",            c_ushort),
22             ("id",             c_ushort),
23             ("offset",         c_ushort),
24             ("ttl",            c_ubyte),
25             ("protocol_num",   c_ubyte),
26             ("sum",            c_ushort),
27             ("src",             c_ulong),
28             ("dst",             c_ulong)
29         ]
30     
31     def __new__(self, socket_buffer=None):
32         return self.from_buffer_copy(socket_buffer)
33     
34     
35     def __init__(self, socket_buff=None):
36         # 协议字段与协议名称对应
37         self.protocol_map = {1:'ICMP', 2:'IGMP', 3:'GGP', 4:'IP', 6:'TCP', 17:'UDP', 41:'IPV6'}
38         
39         # 可读性更强的ip地址
40         self.src_address = socket.inet_ntoa(struct.pack("<L", self.src))
41         self.dst_address = socket.inet_ntoa(struct.pack("<L", self.dst))
42         
43         # 协议类型
44         try:
45             self.protocol = self.protocol_map[self.protocol_num]
46         except:
47             self.protocol = str(self.protocol_num)
48             
49 if __name__ == "__main__":
50     # 监听主机(获取本机ip)
51     host = socket.gethostbyname(socket.getfqdn(socket.gethostname()))
52     
53     # 创建原始套接字, 然后绑定在公开接口上
54     if os.name == "nt":
55         socket_protocol = socket.IPPROTO_IP
56     else:
57         socket_protocol = socket.IPPROTO_ICMP
58     
59     sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
60     sniffer.bind((host, 0))
61     
62     # 设置在捕获的数据包中包含的IP头
63     sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
64     
65     # 在windows平台上, 我们需要设置IOCTL以启用混杂模式
66     if os.name == "nt":
67         sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
68         
69     try:
70         while True:
71             # 读取数据包
72             raw_buffer = sniffer.recvfrom(65565)[0]
73             
74             # 将缓冲区前的20个字段按IP头进行解析
75             ip_header = IP(raw_buffer[0:20])
76             
77             # 输出协议和通信双方ip地址
78             print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)
79     
80     # 出来CTRL-C
81     except KeyboardInterrupt:
82         # 如果运行在windows上,关闭混杂模式
83         if os.name == "nt":
84             sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

 

输出结果:

注:家用电脑包比较单一。如果是公共场合或者公司电脑,你会发现各种各样的协议和IP地址

 

参考资料: python黑帽子

     协议字段---https://blog.csdn.net/zhou1021jian/article/details/80337308

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM