新聞中心
大家好,我是黃偉。今天跟大家講的是Python 用于發(fā)送接受網(wǎng)絡(luò)數(shù)據(jù)包的模塊-------scapy。

創(chuàng)新互聯(lián)公司專(zhuān)注于網(wǎng)站建設(shè),為客戶(hù)提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)開(kāi)發(fā)服務(wù),多年建網(wǎng)站服務(wù)經(jīng)驗(yàn),各類(lèi)網(wǎng)站都可以開(kāi)發(fā),成都品牌網(wǎng)站建設(shè),公司官網(wǎng),公司展示網(wǎng)站,網(wǎng)站設(shè)計(jì),建網(wǎng)站費(fèi)用,建網(wǎng)站多少錢(qián),價(jià)格優(yōu)惠,收費(fèi)合理。
前言
眾所周知,我們每天上網(wǎng)都會(huì)有很多數(shù)據(jù)包需要發(fā)送,然后處理在接受在發(fā)送,這樣一個(gè)循環(huán)往復(fù)的過(guò)程,
這里就顯示了很多數(shù)據(jù)包的發(fā)送接收數(shù)據(jù)。那么,什么是包呢?下面一起看看。
包(packet)是網(wǎng)絡(luò)通信傳輸中的數(shù)據(jù)單位,一般稱(chēng)之為數(shù)據(jù)包,其主要由源地址,目標(biāo)地址,凈載數(shù)據(jù)組成。包括包頭和包體,包頭是固定長(zhǎng)度,包體長(zhǎng)度不變。簡(jiǎn)單了解下包的定義,下面我們來(lái)看看發(fā)包利器scapy的用法吧。(參考資料來(lái)源:百度百科-數(shù)據(jù)包)
一、常用命令
1、ls():顯示所有支持的數(shù)據(jù)包對(duì)象,可帶參數(shù)也可不帶,參數(shù)可以是任意具體的包。
可以看出,它包含了全部的內(nèi)容,如果我們想詳細(xì)查看某個(gè)模塊中的內(nèi)容,比如說(shuō)我想查看ARP ,tcp的話(huà)了,可以這樣:
在這里要告訴大家的是,我們必須要注意大小寫(xiě),ls(ARP)這樣才可以得出正確結(jié)果,ls(arp)是錯(cuò)誤的。
2、lsc():列出所有函數(shù)
滿(mǎn)屏的英文,小編我頭都是大的,不知道大家此時(shí)此刻是什么樣的心情,哈哈哈哈。
3、hide_defaults():用來(lái)刪除一些用戶(hù)提供的那些和default value相同的項(xiàng)目
- a=IP()
- print(a.hide_defaults())
4.display():可以簡(jiǎn)單查看當(dāng)前packet的各個(gè)參數(shù)的取值情況,
- a=IP()
- a.display()
5.更多命令
- 命令 作用
- show_interfaces() 顯示網(wǎng)卡信息
- str(pkt) 組裝數(shù)據(jù)包
- hexdump(pkt) 十六進(jìn)制轉(zhuǎn)儲(chǔ)
- ls(pkt) 顯示出字段值的列表
- pkt.summary() 一行摘要
- pkt.show() 針對(duì)數(shù)據(jù)包的展開(kāi)視圖
- pkt.show2() 顯示聚合的數(shù)據(jù)包(例如,計(jì)算好了的校驗(yàn)和)
- pkt.sprintf() 用數(shù)據(jù)包字段填充格式字符串
- pkt.decode_payload_as() 改變payload的decode方式
- pkt.psdump() 繪制一個(gè)解釋說(shuō)明的PostScript圖表
- pkt.pdfdump() 繪制一個(gè)解釋說(shuō)明的PDF
- pkt.command() 返回可以生成數(shù)據(jù)包的Scapy命令
- nsummary() 同上,但規(guī)定了數(shù)據(jù)包數(shù)量
- conversations() 顯示一個(gè)會(huì)話(huà)圖表
- filter() 返回一個(gè)lambda過(guò)濾后的數(shù)據(jù)包列表
- hexdump() 返回所有數(shù)據(jù)包的一個(gè)hexdump
- import_hexcap() 將hexdump重新導(dǎo)入到Scapy中
- hexraw() 返回所有數(shù)據(jù)包Raw layer的hexdump
- padding() 返回一個(gè)帶填充的數(shù)據(jù)包的hexdump
- nzpadding() 返回一個(gè)具有非零填充的數(shù)據(jù)包的hexdump
- plot() 規(guī)劃一個(gè)應(yīng)用到數(shù)據(jù)包列表的lambda函數(shù)
- make table() 根據(jù)lambda函數(shù)來(lái)顯示表格
- traceroute("baidu.com") 查看IP路徑的traceroute功能
- export_object() 數(shù)據(jù)包轉(zhuǎn)換成base64編碼的Python數(shù)據(jù)結(jié)構(gòu)
- import_object() 可以將輸出重新導(dǎo)入
- save_session() 保存所有的session變量
- load_session() 讀取保存的session
- fuzz() 更改一些默認(rèn)的不被計(jì)算的值(比如校驗(yàn)和checksums),更改的值是隨機(jī)的,但是是符合字段的值的。
二、嗅探數(shù)據(jù)包
- 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:過(guò)濾條件
- iface:網(wǎng)卡接口名稱(chēng)
- count:數(shù)據(jù)包數(shù)量
- prn:回調(diào)函數(shù),通常與lambda搭配使用
- sprintf()函數(shù)控制輸入信息
- 抓取源地址為192.168.3.3的端口為80的tcp報(bào)文:
- sniff(filter="ip src 192.168.3.3 and tcp and tcp port 80", prn=lambda x:x.summary())
- 抓取目的地址網(wǎng)段為192.168.3.3/24的報(bào)文:
- sniff(filter="dst net 192.168", prn=lambda x:x.summary())
- 抓取非ICMP的報(bào)文:
- sniff(filter="not icmp", prn=lambda x:x.summary())
- 將抓取到的報(bào)文的summary打印出來(lái):
- sniff(filter="icmp", prn=lambda x:x.summary(), count=10)
- 將所有IP報(bào)文的源地址打印出來(lái):
- sniff(filter="icmp", prn=lambda x:x[IP].src, count=10)
三、構(gòu)造數(shù)據(jù)包
- pkt= Ether()/IP(dst='192.168.1.2')/TCP(dport=80)
提到數(shù)據(jù)包,不得不說(shuō)各個(gè)協(xié)議了,提到協(xié)議,又自然而然想到了osi七層模型。
| OSI七層網(wǎng)絡(luò)模型 | TCP/IP四層概念模型 | 對(duì)應(yīng)網(wǎng)絡(luò)協(xié)議 |
|---|---|---|
| 應(yīng)用層(Application) | 應(yīng)用層 | HTTP、TFTP, FTP, NFS, WAIS、SMTP |
| 表示層(Presentation) | 應(yīng)用層 | Telnet, Rlogin, SNMP, Gopher |
| 會(huì)話(huà)層(Session) | 應(yīng)用層 | SMTP, DNS |
| 傳輸層(Transport) | 傳輸層 | TCP, UDP |
| 網(wǎng)絡(luò)層(Network) | 網(wǎng)絡(luò)層 | IP, ICMP, ARP, RARP, AKP, UUCP |
| 數(shù)據(jù)鏈路層(Data Link) | 數(shù)據(jù)鏈路層 | FDDI, Ethernet, Arpanet, PDN, SLIP, PPP, |
| 物理層(Physical) | 數(shù)據(jù)鏈路層 | IEEE 802.1A, IEEE 802.2到IEEE 802.11
|
以上便是各個(gè)網(wǎng)絡(luò)協(xié)議對(duì)應(yīng)的osi模型,那么各個(gè)協(xié)議的用法是怎樣的了,下面我們一起來(lái)看下。
四、各個(gè)協(xié)議用法
1、構(gòu)造一個(gè) IP 包,并傳入一些參數(shù)
- #構(gòu)造一個(gè) IP 包,并傳入一些參數(shù)
- pkt = IP(dst="192.168.1.2",ttl=10)
- ls(pkt)
- version:版本號(hào)
- ihl:頭長(zhǎng)度
- tos:服務(wù)類(lèi)型
- len:IP數(shù)據(jù)包總長(zhǎng)
- id:標(biāo)識(shí)符
- flags:標(biāo)記
- flag:片偏移
- ttl:生存時(shí)間
- proto:協(xié)議類(lèi)型
- chksum:頭部校驗(yàn)
- src:源IP地址
- dst:目的IP地址
- options:可選項(xiàng)
2、構(gòu)造ARP包
- #構(gòu)造ARP包
- ARP(op=1, hwdst="ff:ff:ff:ff:ff:ff", pdst=ip_address)
- #arp類(lèi)的構(gòu)造函數(shù)列表:
- ls(ARP)
- hwtype : XShortField = (1) 值為1表示以太網(wǎng)地址,其它還可能表示令牌環(huán)地址
- ptype : XShortEnumField = (2048) 0x0800表示IP地址,其它還可能是ICMP/IGMP
- hwlen : ByteField = (6) ARP報(bào)文中,它的值為6
- plen : ByteField = (4) ARP報(bào)文中,它的值為4
- op : ShortEnumField = (1) 取值為1或者2,代表ARP請(qǐng)求或者響應(yīng)包。1.ARP請(qǐng)求,2.ARP應(yīng)答,3.RARP請(qǐng)求,4.RARP應(yīng)答
- hwsrc : ARPSourceMACField = (None) 發(fā)送方Mac地址。
- psrc : SourceIPField = (None) 發(fā)送方IP地址。
- hwdst : MACField = ('00:00:00:00:00:00') 目標(biāo)Mac地址。
- pdst : IPField = ('0.0.0.0') 目標(biāo)IP地址。
3、構(gòu)造Ether
- #構(gòu)造Ether
- Ether(dst="ff:ff:ff:ff:ff:ff")
- ls(Ether)
- dst : DestMACField = (None) 目的MAC
- src : SourceMACField = (None) 源MAC
- type : XShortEnumField = (36864)
- 構(gòu)造一個(gè)以太網(wǎng)數(shù)據(jù)包通常需要指定目標(biāo)和源MAC地址,如果不指定,默認(rèn)發(fā)出的就是廣播包ff:ff:ff:ff:ff:ff
4、構(gòu)造TCP包
- #構(gòu)造TCP包
- sport : ShortEnumField = 20 (20) 目標(biāo)端口
- 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) =
( ) - window : ShortField = 8192 (8192)
- chksum : XShortField = None (None)
- urgptr : ShortField = 0 (0)
- options : TCPOptionsField = [] (b'')
五、發(fā)包,收包
可分為兩種情況,用法如下:
1、只發(fā)不收
- send(pkt, inter=0, loop=0, count=1, iface=N)
- pkt:數(shù)據(jù)包
- inter:發(fā)包間隔時(shí)間
- count:發(fā)包數(shù)量
- iface:網(wǎng)卡接口名稱(chēng)
- send(),在第三層發(fā)包,沒(méi)有接收功能;send(IP(dst="www.baidu.com",ttl=2)/ICMP())
- sendp(),在第二層發(fā)包,沒(méi)有接收功能。sr(Ether()/IP(dst="www.baidu.com"))
2、發(fā)包且收包
- sr()和sr1()都是在第三層發(fā)包,sr1表示只接收第一個(gè)回復(fù)。
- sr(IP(dst="www.baidu.com",ttl=(1,4))/TCP(dport=[21,23,80],flags="S")) 返回兩個(gè)值
- 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一次,一共執(zhí)行兩次
- #inter表示間隔,count記錄次數(shù)
- srp()和srp1()都是根據(jù)第二層發(fā)包,srp1表示只接收第一個(gè)回復(fù)
- srp(Ether()/IP(dst="www.baidu.com"))
- srp1(Ether()/IP(dst="www.baidu.com"))
六、SYN半開(kāi)式掃描
當(dāng)TCP鏈接指定端口時(shí),flags參數(shù)設(shè)為S時(shí)則為半開(kāi)式掃描,若此時(shí)該端口處于監(jiān)聽(tīng)狀態(tài),返回syn/ack,否則返回rst/ack.
- sr1(IP(dst="192.168.1.2")/TCP(dport=80,flags="S"))
七、數(shù)據(jù)包序列化,反序列化
序列化:將數(shù)據(jù)包對(duì)象保存為pcap文件
反序列化:讀取pcap文件中的內(nèi)容
- pkt= Ether()/IP(dst='192.168.1.2')/TCP(dport=80)
- #將嗅探到的數(shù)據(jù)包內(nèi)容寫(xiě)到pcap文件中
- wrpcap("hw.pcap",pkt)
- #讀取pcap文件。
- read=rdpcap('hw.pcap')
- print(read[1])#打印嗅探到的包的數(shù)據(jù)
八、數(shù)據(jù)包與字符串轉(zhuǎn)換
更加直觀(guān)清晰的分析數(shù)據(jù)。
- zfc= str(pkts[0])
- z= Ether(zfc)
九、導(dǎo)入導(dǎo)出base64編碼
為了方便我們對(duì)數(shù)據(jù)進(jìn)行加密而發(fā)明的一種方式。
- export_object(str(pkts[0])) 導(dǎo)出數(shù)據(jù)包
- new_Pkt = import_object() #將上一步導(dǎo)出的字符串填入
十、離線(xiàn)數(shù)據(jù)包的解析
如果我們捕獲到數(shù)據(jù)包,未聯(lián)網(wǎng)的情況下如何解析呢?
現(xiàn)在就可以使用我們的離線(xiàn)數(shù)據(jù)包分析數(shù)據(jù)了:
- sniff(offline = "hw.pcap")#離線(xiàn)數(shù)據(jù)包
總結(jié)
通過(guò)上面的學(xué)習(xí),我們對(duì)scapy算是有了一個(gè)基礎(chǔ)性的認(rèn)識(shí)了,scapy的確很強(qiáng)大,簡(jiǎn)單的幾行命令就能實(shí)現(xiàn)發(fā)包收包,極大的節(jié)省了我們的開(kāi)發(fā)時(shí)間。如果你深入學(xué)習(xí)它的每個(gè)命令,你會(huì)發(fā)現(xiàn)更多有趣的事情,當(dāng)然這么強(qiáng)大的工具可不要拿來(lái)做壞事哦!!
本文轉(zhuǎn)載自微信公眾號(hào)「Python爬蟲(chóng)與數(shù)據(jù)挖掘」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Python爬蟲(chóng)與數(shù)據(jù)挖掘公眾號(hào)。
網(wǎng)站標(biāo)題:盤(pán)點(diǎn)一款Python發(fā)包收包利器——Scapy
文章網(wǎng)址:http://m.fisionsoft.com.cn/article/djsgeho.html


咨詢(xún)
建站咨詢(xún)
