網絡嗅探器又稱網絡監聽器,簡稱Sniffer子系統,放置於網絡節點上,對網絡中的數據幀進行捕獲的一種被動監聽手段,是一種經常使用的收集有用信息的方法。python
原理上來講,在一個實際的系統中,數據的收發是由網卡來完成的,網卡接收到傳輸來的數據,網卡內的單片程序接收數據幀的目的MAC地址,根據計算機上的網卡驅動程序設置的接收模式判斷該不應接收,認爲該接收就接收後產生中斷信號通知CPU,認爲不應接收就丟掉無論,因此不應接收的數據網卡就截斷了,計算機根本就不知道。對於網卡來講通常有四種接收模式:
a)廣播方式:該模式下的網卡可以接收網絡中的廣播信息。
b)組播方式:設置在該模式下的網卡可以接收組播數據。
c)直接方式:在這種模式下,只有目的網卡才能接收該數據。
d)混雜模式:在這種模式下的網卡可以接收一切經過它的數據,而無論該數據是不是傳給它的。
首先,在以太網中是基於廣播方式傳送數據的,也就是說,全部的物理信號都要通過個人機器。其次,網卡能夠置於一種模式叫混雜模式(promiscuous),在這種模式下工做的網卡可以接收到一切經過它的數據,而無論實際上數據的目的地址是否是他。
這就是SNIFF工做的基本原理:讓網卡接收一切他所能接收的數據。web
sniff(count=0, store=1, offline=None, prn=None, lfilter=None, L2socket=None, timeout=None, opened_socket=None, stop_filter=None, iface=None, *arg, **karg)算法
返回PacketList類型的數據包對象;數組
count: 要捕獲數據包的總數. 0 表示無限制;
store: 是否要保存捕獲的數據包;
prn: 回調函數,會做用於每一個數據包
ex: prn = lambda x: x.summary()
lfilter: 過濾函數,不知足條件的數據包會被丟棄;
ex: lfilter = lambda x: x.haslayer(Padding)
offline: 從pcap文件中讀取數據包;
timeout: 捕獲指定時間內的數據包;L2socket: 經過給定的 L2socket 進行數據捕獲;
opened_socket: 經過給定的 socket 進行數據捕獲;
stop_filter: 過濾函數,知足條件後將結束數據捕獲;
ex: stop_filter = lambda x: x.haslayer(TCP)
iface: 指定端口或端口數組網絡
本軟件使用的主要模塊及其功能
1.抓包界面模塊
2.抓包模塊
3.數據包分析模塊
4.界面控制模塊
app
分析算法:第一:獲得數據包,先將其轉存到內存裏,以備之後再用。
第二:分析當前的數據包。
1.抓取數據包並保存。
2.處理抓到的數據包。
3.將抓到的數據包保存爲pcap格式的文件。
4.繪製GUI界面。
第三:結束分析。socket
def capture_packet(): # 設置過濾條件 filters = fitler_entry.get() print("抓包條件:"+filters) # 設置中止抓包的條件stop_filter stop_sending.clear() global packet_list # 清空列表 packet_list.clear() # 抓取數據包並將抓到的包存在列表中 sniff(prn=(lambda x: process_packet(x)), filter=filters, stop_filter=(lambda x: stop_sending.is_set()))
分析:抓取數據包並對抓到的數據包進行相應處理。tcp
ef process_packet(packet): if pause_flag == False: global packet_list # 將抓到的包存在列表中 packet_list.append(packet) #packet.show() # 抓包的時間 packet_time= timestamp2time(packet.time) src = packet[Ether].src dst = packet[Ether].dst type = packet[Ether].type types = {0x0800:'IPv4',0x0806:'ARP',0x86dd:'IPv6',0x88cc:'LLDP',0x891D:'TTE'} if type in types: proto = types[type] else: proto = 'LOOP' # 協議 # IP if proto == 'IPv4': # 創建協議查詢字典 protos = {1: 'ICMP', 2: 'IGMP', 4: 'IP', 6: 'TCP', 8: 'EGP', 9: 'IGP', 17: 'UDP', 41: 'IPv6', 50: 'ESP', 89:'OSPF'} src = packet[IP].src dst = packet[IP].dst proto=packet[IP].proto if proto in protos: proto=protos[proto] # tcp if TCP in packet: protos_tcp = {80: 'Http', 443: 'Https', 23: 'Telnet', 21: 'Ftp', 20: 'ftp_data', 22: 'SSH', 25: 'SMTP'} sport = packet[TCP].sport dport = packet[TCP].dport if sport in protos_tcp: proto = protos_tcp[sport] elif dport in protos_tcp: proto = protos_tcp[dport] elif UDP in packet: if packet[UDP].sport == 53 or packet[UDP].dport == 53: proto = 'DNS' length = len(packet) # 長度 info = packet.summary() # 信息 global packet_id # 數據包的編號 packet_list_tree.insert("", 'end', packet_id, text=packet_id, values=(packet_id, packet_time, src, dst, proto, length, info)) packet_list_tree.update_idletasks() # 更新列表,不須要修改 packet_id = packet_id + 1
分析:處理函數,依據protocols進行分層提取信息,將參數傳入樹狀數據(packet_list_tree)中,在Frame中顯示。svg