使用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