Python中Scapy使用方法,模块中的常用函数,简单的端口扫描编写
目錄
scapy是什么
scapy的使用
IP()
src()和dst()
Ether()
采用分層的方式來構造數據包
raw()和hexdump()
summary()和show()
如何在scapy中發送和接收數據包
send()和sendp()
sr()、sr1()和srp()
簡單的端口掃描
sniff()
使用scapy編寫簡單的端口掃描
scapy是什么
scapy是一個可用作網絡嗅探,獨立運行的工具,它提供了一個和python相同的交互方式命令行環境,可以在kali內單獨運行,該類庫在網絡安全領域有非常廣泛用例,可用于漏洞利用開發、流量的分析捕獲等等。我們使用這個庫實現對網絡數據包的發送、監聽和解析,編寫可以用進行網絡探測掃描的腳本
scapy的使用
scapy庫pycharm內的導入
file → settings → project:pythonproject → python interpreter
點擊“+”,搜索scapy,install package
IP()
在scapy中,使用了”類+屬性”的方法來構造數據包,每一個網絡協議都是一個類,所以只需要實例化一下這個類,就可以創建一個該協議的數據包,假設我們構造一個IP數據包,如下:
IP()?
導入scapy庫構造數據包
from scapy.layers.inet import IPpkt = IP() print(pkt)執行結果如圖下所示,以字節格式顯示了IP數據包的結果,由于bytes保存的就是原始的字節數據,可以直接在網絡上進行傳輸
src()和dst()
對于IP來說,最重要的就是源ip和目的ip,這兩個屬性分別以src類和dst類來實現
比如我們想構造一個發往“192.168.200.1”的數據包
from scapy.layers.inet import IP from scapy.all import lspkt = IP(dst="192.168.200.1") ls(pkt)執行結果如下圖,src為源ip,dst則是目標ip,ls()類用來實現查看一個數據包的詳細信息
以上是構造了一個最簡單的數據包,IP類的屬性非常復雜,除了最重要的源地址和目的地址外,還有TTL值,版本,長度,協議類型,校驗等等
在了解了src和dst后,我們可以構造一個TTL值為22,源地址為192.168.200.140且目的地址為192.168.200.1的數據包
from scapy.layers.inet import * from scapy.all import lspkt = IP(src="192.168.200.140",dst="192.168.200.1",ttl=22) ls(pkt)Ether()
scapy采用分層的方式來構造數據包,以最簡單的TCP/IP協議簇為例,自頂而下分別為
應用層↓
????????傳輸層↓
????????????????網絡層↓
????????????????????????鏈路層
通常最底層的協議為ether協議,?于實現鏈路層的數據傳輸和地址封裝,然后是IP,然后是TCP、UDP,再然后是DNS、DHCP等,例如我們使用Ether(),這個類可以設置發送方和接收方的MAC地址,假設我們產生一個廣布數據包,如下:
from scapy.layers.inet import * from scapy.all import lspkt = Ether(dst="ff:ff:ff:ff:ff:ff") ls(pkt)采用分層的方式來構造數據包
分層是通過符號"/"實現的,如果一個數據包由多層協議組成,那么這些協議就需要使用"/"分開,并按照協議由底而上的順序從左往右排列
構造一個Ether()/IP()/TCP()/數據包
from scapy.layers.inet import * from scapy.all import *pkt1 = Ether()/IP()/TCP() ls(pkt1)構造一個HTTP數據包
from scapy.layers.inet import * from scapy.all import *pkt2 = IP()/TCP()/"GET HTTP/1.0\r\n\r\n" ls(pkt2)raw()和hexdump()
raw()以字節格式來顯示數據包的內容
而hexdump()則以十六進制顯示數據包的內容
summary()和show()
summary()以不超過一行的摘要來簡單描述數據包,而show()與summary()則相反(顯示數據包的詳細信息)
from scapy.layers.inet import * from scapy.all import *pkt2 = IP()/TCP()/"GET HTTP/1.0\r\n\r\n" print(pkt2.summary()) print('--------------------------') print(pkt2.show())如何在scapy中發送和接收數據包
send()和sendp()
剛才我們構造了一個IP數據包,不過并沒有將其發送出去,scapy內提供了多個用來發送數據包的函數(如:send()和sendp()),而兩者的區別在于前者是發送IP數據包的,而后者是發送Ether數據包。
我們在網絡中經常會使用到ICMP協議,比如使用的用于檢查網絡通不通的 Ping命令,這個“Ping”的過程實際上就是ICMP協議工作的過程。那么我們構造一個目標地址為192.168.2.46的ICMP數據包,并且將其發送出去
from scapy.layers.inet import * from scapy.all import *pkt = IP(dst = "192.168.2.46")/ICMP() send(pkt)如下圖所示,sent 1 packets為發送成功標記
如果需要將MAC地址作為目標時,則使用sendp()函數
from scapy.layers.inet import * from scapy.all import *sendp(Ether(dst = "ff:ff:ff:ff:ff:ff"))以上兩個函數的特點是只發不收,也就是說只會將數據包發送出去,但是不會管這個數據包是否會被目的地址接收,同樣也不會處理該數據包的應答數據包,在實際應用中,我們不但要將制作好的數據包發送出去,同樣需要接收響應數據包
sr()、sr1()和srp()
scary提供了三個用來發送和接收數據包的核心函數,sr()和sr1()主要用于IP地址,而srp()主要用于MAC地址
這里我們使用sr()函數,對“192.168.2.46”發送一個ICMP數據包,需要注意的是,這里的目的地址需要真實存活。首先當數據包產生后被發送出去,scapy會監聽接收到的數據包,然后篩選出需要的。sr1()函數跟sr()函數作用基本一樣,但是前者只返回一個應答的包,而后者的返回值是兩個列表,第一個列表包含了收到的應答數據包,第二個列表包含未收到的數據包
from scapy.layers.inet import * from scapy.all import *pkt = IP(dst = "192.168.2.46")/ICMP() ans,uans = sr(pkt) ans.summary() print("------------------------------------------") ans = sr1(pkt) ans.summary()如下圖,ans和uans分別保存sr()函數的返回值,使用summary()查看數據包內容,Reveived表示收到的數據包的個數,answers表示發送數據包的應答個數
簡單的端口掃描
使用sr1()函數來測試目標的mysql數據庫端口是否開放,采用SYN掃描方法
(注意:測試時仍需要3306端口開放)
from scapy.layers.inet import * from scapy.all import *pkt = IP(dst="192.168.2.46")/TCP(dport=3306,flags="S") ans = sr1(pkt) ans.summary()sniff()
這個函數可以在自己的程序中捕獲經過本機網卡的數據包
該函數的完整格式為:
suiff(filter="",iface="",count=""prn="")
第一個參數為filter,可以表示需要過濾或篩選的數據包;第二個參數為iface,表示指定使用的網卡;count表示用來指定監聽到的數據包數量;prn表示對捕獲的數據包進行處理
例如,我們捕獲與192.168.2.46有關的數據包
from scapy.layers.inet import * from scapy.all import *pkt = sniff(filter="host 192.168.2.46") pkt.summary()正常情況下,是不會有去往或者來自192.168.2.46的數據包的,所以這時候可以打開一個新的終端,然后在里面執行命令“ping -c 3 192.168.202.10”
在執行完畢腳本后,按暫停鍵結束捕獲,這時可以看到已經捕獲到了三個分別來和往的數據包 ?
常見的filter實例
-
host 192.168.2.46【篩選源地址或目的地址為192.168.2.46的數據包】
-
dst host 192.168.2.46【篩選目的地址為192.168.2.46的數據包】
-
src host 192.168.2.46【篩選源地址為192.168.2.46的數據包】
-
ether host ff:ff:ff:ff:ff:ff【篩選以太網源地址或目的地址為192.168.2.46的數據包】
-
ether dst ff:ff:ff:ff:ff:ff【篩選以太網目的地址為192.168.2.46的數據包】
-
ether src ff:ff:ff:ff:ff:ff【篩選以太網源地址為192.168.2.46的數據包】
-
dst port 8080【篩選目的地址為8080端口的數據包】
-
src port 8080【篩選源地址為8080端口的數據包】
-
port 8080【篩選源地址和目的地址為8080的數據包,所有port前面都可以加上TCP和UDP】
比如在網卡eth0上監聽源地址或目的地址為192.168.2.46的ICMP數據包,當接收到10個及以上時停止監聽
使用scapy編寫簡單的端口掃描
import time from scapy.layers.inet import IP, TCP from scapy.sendrecv import sr1def scan(ip):try:packet = IP(dst=ip)/TCP(flags="A", dport=3306) # 構造標志為ACK的數據包,通過調用TCP將構造好的請求包發送到目的地址,并根據目的地址的響應數據包中的flags字段值判斷主機是否存活,若flags字段為R,其整型數值為4時表示接收response = sr1(packet)if response:if int(response[TCP].flags) == 4:time.sleep(0.1)print(ip + ' ' + 'is up')else:print(ip + ' ' + 'is down')else:print(ip + ' ' + 'is down')except:passscan('192.168.2.46')總結
以上是生活随笔為你收集整理的Python中Scapy使用方法,模块中的常用函数,简单的端口扫描编写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python运维(六)--系统监控psu
- 下一篇: arduino蓝牙主从机通讯