1.收發數據包函數
scapy模塊中有好幾個收發數據包的函數,他們能完成不同的功能:
- send() 只發送而不接收數據包,並且網絡層之下的都默認處理好了,只需傳給它網絡層之上(包括網絡層)的參數即可
- sendp() 只發送不接收,並且數據鏈路層之下的都處理好了,只需傳給它數據鏈路層之上(包括數據聯絡層,最常用的是Ether)的參數
- sr1() 發送完只接受1個響應包
- sr() 發送完會返回2個列表,一個用來存收到的所以響應,另一個存未收到響應的數據包
2.發送ARP包
使用ls(ARP)查看scapy模塊中的ARP類:
發送ARP包:
1 2 3 4 5 6 |
eth = Ether(src="bc:77:37:d7:cd:14",type=0x0806) arp = ARP(hwtype=0x1,ptype=0x0800,op=0x1,hwsrc="bc:77:37:d7:cd:14",\ psrc="192.168.1.107",pdst="192.168.1.108") package = eth/arp recv = srp1(package) recv.show() |
注意:/ 用來連接不同層。
3.發送ICMP包
先看看IP類
一般情況下只需要填寫IP類的src,dst即源和目的地址即可。ICMP類的參數可以用同樣方法查看。
發送ICMP包:
1 2 |
ans,unans = sr(IP(dst="192.168.1.108")/ICMP()) ans.show() |
4.發送TCP包
TCP類如下:
sport,dport是源和目的端口,flags可以設置SYN,FIN等一些標誌。其他序列號之類的就不再多說。
發送TCP SYN數據包探測主機端口是否開放:
1 2 |
recv = sr1(IP(dst="220.181.51.53")/TCP(dport=80,flags="S")) recv.show() |
如果端口開放則返回flags爲SA(SYN/ACK):
如果沒開放則返回flags爲RA(RST/ACK):
用這個原理也可以實現SYN泛洪攻擊,端口掃描器等等。另外,發送UDP和TCP類似。
一、進入scapy交互界面
在終端下輸入:scapy ,進入交互界面:
二、查看scapy已經實現的網絡協議
ls() 列出scapy中已實現的網絡協議
ls(協議類型) 查看某個協議頭部字段格式
lsc() 列出scapy中可以使用的命令或函數,比如嗅探時,我們經常會用到sniff()函數
IP().show() 顯示包的IP信息
IP().display() 顯示包的模板
dpkg = sniff(filter="tcp",count=4)
dpkg[2].show() 顯示包抓取到的tkpk的第3個數據包的的詳細內容
dpkg[2].summary() 查看捕獲到數據包的信息摘要
wrpcap("dpkgsniff.pcap",dpkg) 將嗅探到的packet內容寫到pcap文件
dpkg_read = rdpcap("dpkgsniff.pcap") 讀取pcap文件
三、構造數據包
#構造一個ip數據包
dpkg = IP()
#修改數據包的值
dpkg.ttl = 24
#構造一個ICMP數據包
dpkg = ICMP()
#構造一個TCP數據包
dpkg = TCP()
通過“/”來表示網絡中各個層的組合
dpkg=Ether()/IP(dst="www.baidu.com")/TCP()/"GET /index.html HTTP/1.0 \n\n"
dpkg.show()
hexdump(dpkg)
sprintf()輸出某一層某個參數的取值,如果不存在就輸出”??”,具體的format格式是:%[[fmt][r],][layer[:nb].]field%
%[[fmt][r],][layer[:nb].]field%
layer: 協議層的名字,如Ether、IP、Dot11、TCP等。
filed: 需要顯示的參數。
nb: 當有兩個協議層有相同的參數名時,nb用於到達你想要的協議層。
r: 一個標誌。當使用r標誌時,意味着顯示的是參數的原始值。
例如,TCP標誌中使用人類可閱讀的字符串’SA’表示SYN和ACK標誌,而其原始值是18.
例子:pkt.sprintf("Etherent source: %Ether.src% IP src: %IP.src%")
或者:pkt.sprintf(
'%Raw.load%'
) #其中Raw爲具體的協議層
顯示具體的網絡層的信息:
dpkg["IP"].show() 或者dpkg[IP].show() 也可以
dpkg["TCP"].show()
dpkg["Raw"].show()
#或者等價於
dpkg.getlayer(ip).show()
dpkg.getlayer(TCP).show()
dpkg.getlayer(Raw).show()
獲取某個協議的具體字段值:
dpkg["Raw"].load
dpkg.getlayer(TCP).window
基本命令
ls()
List all available protocols and protocol options
lsc()
List all available scapy command functions
conf
Show/set scapy configuration parameters
生成數據包
# Setting protocol fields
>>> ip=IP(src="10.0.0.1")
>>> ip.dst="10.0.0.2"
# Combining layers
>>> l3=IP()/TCP()
>>> l2=Ether()/l3
# Splitting layers apart
>>> l2.getlayer(1)
<IP frag=0 proto=tcp |<TCP |>>
>>> l2.getlayer(2)
<TCP |>
顯示數據包
# Show an entire packet
>>> (Ether()/IPv6()).show()
###[ Ethernet ]###
dst= ff:ff:ff:ff:ff:ff
src= 00:00:00:00:00:00
type= 0x86dd
###[ IPv6 ]###
version= 6
tc= 0
fl= 0
plen= None
nh= No Next Header
hlim= 64
src= ::1
dst= ::1
# Show field types with default values
>>> ls(UDP())
sport : ShortEnumField = 1025 (53)
dport : ShortEnumField = 53 (53)
len : ShortField = None (None)
chksum : XShortField = None (None)
指定地址和值(Specifying Addresses and Values)
指定IP值 Explicit IP address (use quotation marks)
>>> IP(dst="192.0.2.1")
指定域名 DNS name to be resolved at time of transmission
>>> IP(dst="example.com")
# IP network (results in a packet template)
>>> IP(dst="192.0.2.0/24")
隨機生成ip和mac Random addresses with RandIP() and RandMAC()
>>> IP(dst=RandIP())
>>> Ether(dst=RandMAC())
指定TTL範圍 Set a range of numbers to be used (template)
>>> IP(ttl=(1,30))
# Random numbers with RandInt() and RandLong()
>>> IP(id=RandInt())
發送包(Sending Packets)
send(pkt, inter=0, loop=0, count=1, iface=N)
發送三層包(Send one or more packets at layer three)
sendp(pkt, inter=0, loop=0, count=1, iface=N)
發送二層包(Send one or more packets at layer two)
sendpfast(pkt, pps=N, mbps=N, loop=0, iface=N)
Send packets much faster at layer two using tcpreplay
>>> send(IP(dst="192.0.2.1")/UDP(dport=53))
.Sent 1 packets.
>>> sendp(Ether()/IP(dst="192.0.2.1")/UDP(dport=53))
.Sent 1 packets.
發送和接受包(Sending and Receiving Packets)
sr(pkt, filter=N, iface=N), srp(…)
Send packets and receive replies
sr1(pkt, inter=0, loop=0, count=1, iface=N), srp1(…)
Send packets and return only the first reply
srloop(pkt, timeout=N, count=N), srploop(…)
Send packets in a loop and print each reply
>>> srloop(IP(dst="packetlife.net")/ICMP(), count=3)
RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140
RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140
RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140
嗅探包(Sniffing Packets)
sniff(count=0, store=1, timeout=N)
Record packets off the wire; returns a list of packets when stopped
# Capture up to 100 packets (or stop with ctrl-c)
>>> pkts=sniff(count=100, iface="eth0")
>>> pkts
<Sniffed: TCP:92 UDP:7 ICMP:1 Other:0>