隨著Python越來越流行,在安全領域的用途也越來越多。比如可以用requests 模塊撰寫進行Web請求工具;用sockets編寫TCP網絡通訊程序;解析和生成字節流可以使用struct模塊。而要解析和處理網絡包在網絡安全領域更加普遍,時常
我們會使用tcpdump和wireshark(tshark)。但是如果要自己寫程序進行處理,則需要更靈活的語言包(庫),這就是本文要介紹的Scapy。
Scapy 是一個用來解析底層網絡數據包的Python模塊和交互式程序,該程序對底層包處理進行了抽象打包,使得對網絡數據包的處理非常簡便。該類庫可以在在網絡安全領域有非常廣泛用例,可用於漏洞利用開發、數據洩露、網絡監聽、入侵檢測和流量的分析捕獲的。Scapy與數據可視化和報告生成集成,可以方便展示起結果和數據。
Scapy的基本理念是提出一個基於領域特定語言,從而輕松快速地進行有線格式(Wire Format)管理。
Scapy可以通過pip安裝:
pip install scapy
也可以通過發行版的包管理器安裝,比如yum,但是其版本可能太老已經過時。
也可以通過直接從官方倉庫clone源碼安裝:
git clone github /secdev/scapy
然後,可以可以簡單地運行:
cd scapy
./run_scapy
用Scapy做的最簡單的事情就是讀取PCAP文件。讓我們下載Wireshark的sip-rtp-opus-hybrid.pcap 示例PCAP數據包為例子:
用rdpcap()函數引入PCAP文件,讀取其內容的函數:
>>> pkts = rdpcap("sip-rtp-opus-hybrid.pcap")
>>> pkts
<sip-rtp-opus-hybrid.pcap: TCP:0 UDP:7 ICMP:0 Other:0>
為了更詳細讀取PCAP文件中的數據,可以使用PcapReader從打開的文件句柄中迭代地讀取數據包,一次一個包,bing實例化的對象:
>>> fd = open("sip-rtp-opus-hybrid.pcap", "rb")
>>> reader = PcapReader(fd)
>>> reader
<scapy.utils.PcapReader at 0x7f913c7c24e0>
>>> for CC in reader:
...: print(CC)
...:
>>> fd.close()
如上面所示,每個數據包都以有線格式提供。Scapy 將每個數據包以網絡層的堆棧。Scapy層對象對應於網絡協議及其有線格式。
獲取第一個數據包並檢查IP層是否可用:
>>> first= CC[0]
>>> first.haslayer(IP)
True
>>> IP in first
True
要解析來自特定層的數據包,可按想要的層對其進行索引,並讓Scapy打印所有字段:
要以十六進制打印數據包,可以使用hexdump()功能:
>>> hexdump(first)
為了完全解析和完美地輸出一個數據包,需要調用show()方法:
>>> first.show()
可以看到,上面未能有效地解析SI負載。這是因為Scapy主要處理二進制協議 網絡堆棧的較低部分,而SIP不是。但是可以引入第三方模塊來解析一些應用層協議,比如HTTP協議。
比如可以讀取帶有預先捕獲的數據包的PCAP文件,如果要做一些數據包嗅探,如果系統准備好在混雜模式下使用網絡接口,可以調用sniff()從網卡獲取一些數據包的函數:
>>> for CC in sniff(count=5):
...: CC.show()
...:
Scapy中也可以使用和Wireshark(tshark)、tcpdump 相同BPF語法來過濾嗅探到的數據包和許多其他工具支持:
>>> for CC in sniff(filter="udp", count=5):
...: CC.show()
...:
要將捕獲的數據包保存到 PCAP 文件中以供進一步分析,可以使用wrpcap()函數來導出到文件:
>>> capture = sniff(filter="udp", count=5)
>>> capture
<Sniffed: TCP:0 UDP:5 ICMP:0 Other:0>
>>> wrpcap("udp.pcap", capture)
除了可以嗅探(捕獲和解析)網絡數據包,但Scapy也支持生成數據包進行各種主動欺騙:網絡掃描、服務器探測、通過發送攻擊系統格式錯誤的請求等等。
下面嘗試ping一個服務器,涉及到要給服務發送一個ICMP數據包:
>>> CC = IP(dst="XXX") / ICMP()
>>> CC.show()
然後調用sr1()函數,可以發送一個ICMP數據包(即ping),等待返回數據包返回:
>>> rr=sr1(CC)
Begin emission:
Finished sending 1 packets.
...*
Received 4 packets, got 1 answers, remaining 0 packets
>>> rr
上面得到了正確的ICMP回複。
為了發送多個數據包和接收響應(例如實現ping掃描),可以用sr()功能。發送多個數據包,但等待單個響應。還可以用sr1_flood()功能。
Scapy通過重載了Python“/”運算符來實現層堆疊,不再不強制按照網絡層順序執行,以達到以預期人為順序執行(這在某些測試和應用中很有用)。
>>> CC=ICMP() / UDP() / IP() / IP()
>>> CC
<ICMP |<UDP |<IP frag=0 proto=ipencap |<IP |>>>>
>>> CC.show()
###[ ICMP ]###
type= echo-request
code= 0
chksum= None
id= 0x0
seq= 0x0
###[ UDP ]###
sport= domain
dport= domain
len= None
chksum= None
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= ipv4
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= hopopt
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
>>> hexdump(CC)
WARNING: No IP underlayer to compute checksum. Leaving null.
0000 08 00 F7 65 00 00 00 00 00 35 00 35 00 30 00 00 ...e.....5.5.0..
0010 45 00 00 28 00 01 00 00 40 04 7C CF 7F 00 00 01 E..([email protected]|.....
0020 7F 00 00 01 45 00 00 14 00 01 00 00 40 00 7C E7 [email protected]|.
0030 7F 00 00 01 7F 00 00 01
設計成這樣,主要是為了可以生成任意的網絡數據包(故意損壞的),用來進行漏洞測試研究或利用。當然對於對這一塊不熟悉的用戶,強烈建議不要輕易嘗試,以免造成問題。
Scapy也支持通過PyX(需要預先安裝模塊)對數據進行可視化。可以輸出為一個數據包或數據包列錶的圖形(PostScript/PDF格式):
>>> xxCC[404].pdfdump(layer_shift=1)
>>> xxCC[404].psdump("/tmp/xxCC.eps",layer_shift=1)
利用函數fuzz()可以利用快速構建生成隨機測試值利用模糊模板並循環發送進行測試。以下示例中,IP層正常,UDP和NTP層被fuzz。UDP 校驗和將正確,UDP 目標端口將被 NTP重載為123,並且NTP版本將被強制為4,所有其他端口將被隨機化:
send(IP(dst="target")/fuzz(UDP()/NTP(version=4)),loop=1)
................^C
Sent 16 packets.
拋磚引玉,我們在此介紹了一些基本的Scapy用途,當然這只是scapy龐大功能中的冰山一角,更多的用法請參考官方文檔。
據蟲蟲所知目前有些工具已經使用了scapy包:
Trackerjacker: WiFi網絡映射器
Wifiphisher: Wifi接入點創建工具
Sshame:SSH 公鑰暴力破解器
ISF:工業系統的利用框架。
還有一些更特殊的用途則需要各比特hacker來進一步發掘。