盤點一款 Python 發包收包利器 - scapy

大家好,我是安果!

今天跟大家講的是 Python 用於發送接受網絡數據包的模塊:scapy

前言

衆所周知,我們每天上網都會有很多數據包需要發送,然後處理在接受在發送,這樣一個循環往復的過程

這裏就顯示了很多數據包的發送接收數據,那什麼是包呢?下面一起看看

包( packet )是網絡通信傳輸中的數據單位,一般稱之爲數據包,其主要由源地址,目標地址,淨載數據組成

它包括包頭和包體,包頭是固定長度,包體長度不變

簡單瞭解下包的定義,下面我們來看看發包利器 scapy 的用法吧

一、常用命令

1、ls():顯示所有支持的數據包對象,可帶參數也可不帶,參數可以是任意具體的包

可以看出,它包含了全部的內容,如果我們想詳細查看某個模塊中的內容,比如說我想查看 ARP ,tcp 的話了,可以這樣:

在這裏要告訴大家的是,我們必須要注意大小寫,ls(ARP) 這樣纔可以得出正確結果,ls(arp) 是錯誤的。

2、lsc():列出所有函數

滿屏的英文,我頭都是大的,不知道大家此時此刻是什麼樣的心情,哈哈哈哈

3、hide_defaults():用來刪除一些用戶提供的那些和 default value 相同的項目

4.display():可以簡單查看當前 packet 的各個參數的取值情況,

a=IP()
a.display()
  1. 更多命令
命令                                  作用
show_interfaces()                  顯示網卡信息
str(pkt)                            組裝數據包
hexdump(pkt)                        十六進制轉儲
ls(pkt)                          顯示出字段值的列表
pkt.summary()                        一行摘要
pkt.show()                      針對數據包的展開視圖
pkt.show2()             顯示聚合的數據包(例如,計算好了的校驗和)
pkt.sprintf()                   用數據包字段填充格式字符串
pkt.decode_payload_as()         改變payload的decode方式
pkt.psdump()                繪製一個解釋說明的PostScript圖表
pkt.pdfdump()                   繪製一個解釋說明的PDF
pkt.command()               返回可以生成數據包的Scapy命令
nsummary()                      同上,但規定了數據包數量
conversations()                     顯示一個會話圖表
filter()                    返回一個lambda過濾後的數據包列表
hexdump()                       返回所有數據包的一個hexdump
import_hexcap()                 將hexdump重新導入到Scapy中
hexraw()                    返回所有數據包Raw layer的hexdump
padding()                   返回一個帶填充的數據包的hexdump
nzpadding()                 返回一個具有非零填充的數據包的hexdump
plot()                      規劃一個應用到數據包列表的lambda函數
make table()                    根據lambda函數來顯示錶格
traceroute("baidu.com")     查看IP路徑的traceroute功能
export_object()             數據包轉換成base64編碼的Python數據結構
import_object()                     可以將輸出重新導入
save_session()                  保存所有的session變量
load_session()                  讀取保存的session
fuzz()      更改一些默認的不被計算的值(比如校驗和checksums),更改的值是隨機的,但是是符合字段的值的。

二、嗅探數據包

from scapy.all import *
pkt = sniff(iface = "Realtek PCIe GBE Family Controller",count = 3 ,filter='tcp',prn = lambda x: x.sprintf('{IP:%IP.src%->%IP.dst%\n}{Raw:%Raw.load%\n}'))
filter:過濾條件
iface:網卡接口名稱
count:數據包數量
prn:回調函數,通常與lambda搭配使用
sprintf()函數控制輸入信息
抓取源地址爲192.168.3.3的端口爲80的tcp報文:
sniff(filter="ip src 192.168.3.3 and tcp and tcp port 80", prn=lambda x:x.summary())
抓取目的地址網段爲192.168.3.3/24的報文:
sniff(filter="dst net 192.168", prn=lambda x:x.summary())
抓取非ICMP的報文:
sniff(filter="not icmp", prn=lambda x:x.summary())
將抓取到的報文的summary打印出來:
sniff(filter="icmp", prn=lambda x:x.summary(), count=10)
將所有IP報文的源地址打印出來:
sniff(filter="icmp", prn=lambda x:x[IP].src, count=10)

三、構造數據包

pkt= Ether()/IP(dst='192.168.1.2')/TCP(dport=80)

提到數據包,不得不說各個協議了,提到協議,又自然而然想到了 osi 七層模型

2wg9dB

以上便是各個網絡協議對應的 osi 模型,那麼各個協議的用法是怎樣的了,下面我們一起來看下

四、各個協議用法

1、構造一個 IP 包,並傳入一些參數

#構造一個 IP 包,並傳入一些參數
pkt = IP(dst="192.168.1.2",ttl=10)
ls(pkt)  
version:版本號
ihl:頭長度
tos:服務類型
len:IP數據包總長
id:標識符
flags:標記
flag:片偏移
ttl:生存時間
proto:協議類型
chksum:頭部校驗
src:源IP地址
dst:目的IP地址
options:可選項

2、構造 ARP 包

#構造ARP包
ARP(op=1, hwdst="ff:ff:ff:ff:ff:ff", pdst=ip_address)
#arp類的構造函數列表:
ls(ARP)
hwtype     : XShortField          = (1)  值爲1表示以太網地址,其它還可能表示令牌環地址
ptype      : XShortEnumField      = (2048)  0x0800表示IP地址,其它還可能是ICMP/IGMP
hwlen      : ByteField            = (6)   ARP報文中,它的值爲6
plen       : ByteField            = (4)  ARP報文中,它的值爲4
op         : ShortEnumField       = (1) 取值爲1或者2,代表ARP請求或者響應包。1.ARP請求,2.ARP應答,3.RARP請求,4.RARP應答
hwsrc      : ARPSourceMACField    = (None) 發送方Mac地址。
psrc       : SourceIPField        = (None) 發送方IP地址。
hwdst      : MACField             = ('00:00:00:00:00:00') 目標Mac地址。
pdst       : IPField              = ('0.0.0.0') 目標IP地址。

3、構造 Ether

#構造Ether
Ether(dst="ff:ff:ff:ff:ff:ff")
ls(Ether)
dst        : DestMACField         = (None) 目的MAC
src        : SourceMACField       = (None) 源MAC
type       : XShortEnumField      = (36864)
構造一個以太網數據包通常需要指定目標和源MAC地址,如果不指定,默認發出的就是廣播包ff:ff:ff:ff:ff:ff

4、構造 TCP 包

#構造TCP包
sport      : ShortEnumField                      = 20              (20) 目標端口
dport      : ShortEnumField                      = 80              (80)  源端口
seq        : IntField                            = 0               (0)
ack        : IntField                            = 0               (0)
dataofs    : BitField (4 bits)                   = None            (None)
reserved   : BitField (3 bits)                   = 0               (0)
flags      : FlagsField (9 bits)                 = <Flag 2 (S)>    (<Flag 2 (S)>)
window     : ShortField                          = 8192            (8192)
chksum     : XShortField                         = None            (None)
urgptr     : ShortField                          = 0               (0)
options    : TCPOptionsField                     = []              (b'')

五、發包,收包

可分爲兩種情況,用法如下:

1、只發不收

send(pkt, inter=0, loop=0, count=1, iface=N) 
pkt:數據包
inter:發包間隔時間
count:發包數量
iface:網卡接口名稱
send(),在第三層發包,沒有接收功能;send(IP(dst="www.baidu.com",ttl=2)/ICMP())
sendp(),在第二層發包,沒有接收功能。sr(Ether()/IP(dst="www.baidu.com"))

2、發包且收包


sr()和sr1()都是在第三層發包,sr1表示只接收第一個回覆。
sr(IP(dst="www.baidu.com",ttl=(1,4))/TCP(dport=[21,23,80],flags="S")) 返回兩個值
sr1(IP(dst="www.baidu.com",ttl=(1,4))/ICMP()) 
srloop(IP(dst="www.baidu.com",ttl=1)/ICMP()) #不停的ping百度
srloop(IP(dst="www.baidu.com",ttl=1)/ICMP(),inter=3,count=2) #每隔3秒ping一次,一共執行兩次
#inter表示間隔,count記錄次數
srp()和srp1()都是根據第二層發包,srp1表示只接收第一個回覆
srp(Ether()/IP(dst="www.baidu.com"))
srp1(Ether()/IP(dst="www.baidu.com"))

六、SYN 半開式掃描

sr1(IP(dst="192.168.1.2")/TCP(dport=80,flags="S"))

七、數據包序列化,反序列化

反序列化:讀取 pcap 文件中的內容

pkt= Ether()/IP(dst='192.168.1.2')/TCP(dport=80)
#將嗅探到的數據包內容寫到pcap文件中 
wrpcap("hw.pcap",pkt)
#讀取pcap文件。
read=rdpcap('hw.pcap')
print(read[1])#打印嗅探到的包的數據

八、數據包與字符串轉換

更加直觀清晰的分析數據。

zfc= str(pkts[0]) 
z= Ether(zfc)

九、導入導出 base64 編碼

爲了方便我們對數據進行加密而發明的一種方式

export_object(str(pkts[0])) 導出數據包
new_Pkt = import_object() #將上一步導出的字符串填入

十、離線數據包的解析

如果我們捕獲到數據包,未聯網的情況下如何解析呢?

現在就可以使用我們的離線數據包分析數據了:

sniff(offline = "hw.pcap")#離線數據包

總結

通過上面的學習,我們對 scapy 算是有了一個基礎性的認識了,scapy 的確很強大,簡單的幾行命令就能實現發包收包,極大的節省了我們的開發時間

如果你深入學習它的每個命令,你會發現更多有趣的事情,當然這麼強大的工具可不要拿來做壞事哦!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/xsoGn21-uFh4Gq_Ct1kMxQ