您好,登錄后才能下訂單哦!
本篇內容介紹了“Scapy如何處理數據包”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
發送僅設置了SYN的空TCP數據包。
SYN/ACK或RST響應表示機器已啟動并正在運行。
>>> ans,unans=sr(IP(dst="60.205.177.0/28")/TCP(dport=80,flags="S")) Begin emission: Finished sending 16 packets. .*********..................................................................................^C Received 92 packets, got 9 answers, remaining 7 packets >>> ans.summary(lambda s:s[1].sprintf("%IP.src% is alive")) 60.205.177.1 is alive 60.205.177.2 is alive 60.205.177.4 is alive 60.205.177.6 is alive 60.205.177.7 is alive 60.205.177.8 is alive 60.205.177.11 is alive 60.205.177.12 is alive 60.205.177.14 is alive
發送僅設置了ACK位的空TCP數據包。
未經請求的ACK數據包應通過RST進行響應,RST顯示一臺機器。
SYN-ping和ACK-ping看起來可能是多余的,但是大多數無狀態防火墻不會過濾未經請求的ACK數據包,所以最好同時使用這兩種ping技術。
>>> ans, unans = sr(IP(dst='60.205.177.90-105')/TCP(dport=80, flags='A')) Begin emission: Finished sending 16 packets. .*.******....................................................................................................................................................................^C Received 173 packets, got 7 answers, remaining 9 packets >>> ans.summary(lambda s:s[1].sprintf("{IP: %IP.src% is alive}")) 60.205.177.91 is alive 60.205.177.94 is alive 60.205.177.95 is alive 60.205.177.97 is alive 60.205.177.100 is alive 60.205.177.101 is alive 60.205.177.102 is alive
將UDP數據包發送給給定的端口(無論是否帶有有效載荷),協議特定的有效載荷會使掃描更加有效。
選擇最有可能關閉的端口(開放的UDP端口可能會收到空數據包,但會忽略它們)。
ICMP端口不可達表示機器是啟動的。
>>> ans, unans = sr(IP(dst='60.205.177.100-254')/UDP(dport=90),timeout=0.1) Begin emission: Finished sending 155 packets. ..******..*****... Received 18 packets, got 11 answers, remaining 144 packets >>> ans.summary(lambda s:s[1].sprintf("%IP.src% is unreachable")) 60.205.177.106 is unreachable 60.205.177.108 is unreachable 60.205.177.107 is unreachable 60.205.177.111 is unreachable 60.205.177.125 is unreachable 60.205.177.172 is unreachable 60.205.177.191 is unreachable 60.205.177.203 is unreachable 60.205.177.224 is unreachable 60.205.177.242 is unreachable 60.205.177.244 is unreachable
在同一網絡/ LAN上探測存活主機時,可以使用ARP Ping。
更快,更可靠,因為它僅通過ARP在第2層上運行。
ARP是任何第2層通信的骨干協議
由于在 IPv6 中沒有 ARP協議,所以在 IPv6 上層定義了 NDP 協議實現 ARP 的地址解析,沖突地址檢測等功能以及IPV6 的鄰居發現功能。
>>> ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="172.17.51.0/24"),timeout=2) Begin emission: Finished sending 256 packets. *******************************************************************************.***********************************************************************************........................... Received 190 packets, got 162 answers, remaining 94 packets >>> ans.summary(lambda r: r[0].sprintf("%Ether.src% %ARP.pdst%") ) 00:16:3e:0c:d1:ad 172.17.51.0 00:16:3e:0c:d1:ad 172.17.51.1 00:16:3e:0c:d1:ad 172.17.51.2 00:16:3e:0c:d1:ad 172.17.51.3 00:16:3e:0c:d1:ad 172.17.51.4 00:16:3e:0c:d1:ad 172.17.51.5 00:16:3e:0c:d1:ad 172.17.51.6 00:16:3e:0c:d1:ad 172.17.51.7
ICMP掃描涉及無處不在的_ping程序_發送的標準數據包。
向目標IP發送一個ICMP類型8(回顯請求)數據包,收到一個ICMP類型0(回顯應答)的包表示機器存活。
現在許多主機和防火墻阻止這些數據包,因此基本的ICMP掃描是不可靠的。
ICMP還支持時間戳請求和地址掩碼請求,可以顯示計算機的可用性。
>>> ans,unans=sr(IP(dst="60.205.177.168-180")/ICMP()) >>> ans.summary(lambda s:s[0].sprintf("{IP: %IP.dst% is alive}")) 60.205.177.168 is alive 60.205.177.169 is alive 60.205.177.171 is alive 60.205.177.172 is alive 60.205.177.175 is alive 60.205.177.174 is alive 60.205.177.176 is alive 60.205.177.179 is alive 60.205.177.178 is alive 60.205.177.180 is alive
找了個網圖( 侵刪)
這里展示一下tcpdump抓到的握手包
192.168.2.1.35555 > 192.168.2.12.4444: Flags [S] seq=12345 192.168.2.12.4444 > 192.168.2.1.35555: Flags [S.], seq=9998 ack=12346 192.168.2.1.35555 > 192.168.2.12.4444: Flags [.] seq=12346 ack=9999
IP與端口號之間以'.'分隔,ACK用'.'表示,SYN用'S'表示,而[S.]則表示SYN+ACK
使用源IP地址和目標IP地址制作一個IP頭。
制作一個TCP標頭,在其中生成TCP源端口,設置服務器偵聽的目標端口,設置TCP的flag SYN,并生成客戶端的seq。
ip=IP(src="192.168.2.53", dst="60.205.177.168") syn_packet = TCP(sport=1500, dport=80, flags="S", seq=100)
保存服務器的響應。
獲取服務器的TCP序列號,并將該值加1。
synack_packet = sr1(ip/syn_packet) my_ack = synack_packet.seq+1
IP標頭與初始SYN數據包具有相同的源和目標。
TCP報頭具有與syn數據包相同的TCP源端口和目標端口,僅設置ACK位,由于SYN數據包消耗一個序列號,因此將客戶端的ISN遞增1,將確認值設置為遞增的服務器的序列號值。
ack_packet = TCP(sport=1500, dport=80, flags="A", seq=101, ack=my_ack) send(ip/ack_packet)
完整代碼如下
#!/usr/bin/python from scapy.all import * # 構建payload get='GET / HTTP/1.0\n\n' #設置目的地址和源地址 ip=IP(src="192.168.2.53",dst="60.205.177.168") # 定義一個隨機源端口 port=RandNum(1024,65535) # 構建SYN的包 SYN=ip/TCP(sport=port, dport=80, flags="S", seq=42) # 發送SYN并接收服務器響應(SYN,ACK) SYNACK=sr1(SYN) #構建確認包 ACK=ip/TCP(sport=SYNACK.dport,dport=80,flags="A",seq=SYNACK.ack,ack=SYNACK.seq+1)/get #發送ack確認包 reply,error=sr(ACK) # 打印響應結果 print(reply.show())
SYN掃描也稱為半開放掃描。可以使用這種策略來確定通信端口的狀態而無需建立完整的連接。客戶端首先向被測主機發送一個syn數據包,如果端口開放,那么服務端會響應一個syn+ack的數據包,之后客戶端會發送rst數據包進行重置。否則服務端會直接響應一個rst包,表示端口沒有開放。如果我們發了大量的syn包而不去確認,服務端會繼續發送syn+ack的包,會不斷的消耗服務器的CPU和內存,這也就是我們常說的syn泛洪攻擊了。
接下來我們使用scapy來模擬syn掃描
使用sr1功能發送并響應數據包
使用sprintf方法在響應中打印字段。(“ SA”標志表示開放的端口,“ RA”標志表示關閉的端口)
>>> syn_packet = IP(dst='60.205.177.168')/TCP(dport=22,flags='S') >>> rsp=sr1(syn_packet) Begin emission: Finished sending 1 packets. ..* Received 3 packets, got 1 answers, remaining 0 packets >>> rsp.sprintf("%IP.src% %TCP.sport% %TCP.flags%") '60.205.177.168 ssh SA'
>>> ans,unans=sr(IP(dst="60.205.177.168")/TCP(dport=(20,22),flags="S")) Begin emission: Finished sending 3 packets. ..*..** Received 7 packets, got 3 answers, remaining 0 packets >>> ans.summary(lambda s:s[1].sprintf("%TCP.sport% %TCP.flags%" )) ftp_data RA ftp RA ssh SA
make_table接受三個值,行,列和表數據。(在下面的示例中,目標IP位于x軸上,目標端口位于y軸上,響應中的TCP標志是表格數據)
60.205.177.169的20和22端口沒有響應數據包,猜測中間可能有設備(防火墻)給攔下了。
>>> ans,unans = sr(IP(dst=["60.205.177.168-170"])/TCP(dport=[20,22,80],flags="S")) Begin emission: Finished sending 9 packets. ..*..**..*.................................................................................................................................................................................................................................................^C Received 251 packets, got 4 answers, remaining 5 packets >>> ans.make_table(lambda s: (s[0].dst, s[0].dport,s[1].sprintf("%TCP.flags%"))) 60.205.177.168 60.205.177.169 20 RA - 22 SA - 80 SA SA
客戶端會發送帶有fin標志(關閉連接)的數據包到服務端,當服務端沒有響應時,表示端口是開放狀態,否則會收到rst的包。
>>> fin_packet = IP(dst='60.205.177.168')/TCP(dport=4444,flags='F') >>> resp = sr1(fin_packet) Begin emission: Finished to send 1 packets. ^C Received 0 packets, got 0 answers, remaining 1 packets
>>> fin_packet = IP(dst='60.205.177.168')/TCP(dport=4399,flags='F') >>> resp = sr1(fin_packet) >>> resp.sprintf('%TCP.flags%') 'RA'
null掃描會發送一個沒有設置任何flag的TCP數據包,當收到rst的響應包則表示端口關閉,否則表示端口開放,如果收到類型為3且代碼為1、2、3、9、10或13的ICMP錯誤表示該端口已被過濾,獲取不到端口狀態。
>>> null_scan_resp = sr1(IP(dst="60.205.177.168")/TCP(dport=4399,flags=""),timeout=1) >>> null_scan_resp.sprintf('%TCP.flags%') 'RA'
XMAS掃描會發送帶有URG,PUSH,FIN標志的TCP數據包,如果未接收到任何數據包,則認為該端口處于打開狀態;如果接收到RST數據包,則將該端口視為已關閉。如果收到類型為3且代碼為1、2、3、9、10或13的ICMP錯誤表示該端口已被過濾,獲取不到端口狀態。
>>> xmas_scan_resp=sr1(IP(dst="60.205.177.168")/TCP(dport=4399,flags=”FPU”),timeout=1) Begin emission: .Finished sending 1 packets. * Received 2 packets, got 1 answers, remaining 0 packets >>> xmas_scan_resp.sprintf('%TCP.flags%') 'RA'
UDP掃描最常見于檢測DNS,SNMP和DHCP服務。客戶端會發送帶有要連接的端口號的UDP數據包。如果服務器使用UDP數據包響應客戶端,那么該端口在服務器上是開放的。如果返回ICMP端口不可達的類型為3和code為3錯誤數據包,表示該端口在服務器是關閉狀態。
>>> udp_scan=sr1(IP(dst="60.205.177.168")/UDP(dport=53),timeout=1))
跟蹤路由技術基于IP協議的設計方式。IP標頭中的TTL值被視為跳數限制。每當路由器收到要轉發的數據包時,它將TTL減1并轉發數據包。當TTL達到0時,路由器將向源計算機發送答復,表示數據包已被丟棄。
各種工具背后的技術是相同的,但是實現它們的方式略有不同。Unix系統使用UDP數據報文,而Windows tracert則發送ICMP請求,Linux的tcptraceroute使用TCP協議。
>>> ans,unans=sr(IP(dst="49.232.152.189",ttl=(1,10))/ICMP()) Begin emission: Finished sending 10 packets. *****.**........................................................................................................^C Received 112 packets, got 7 answers, remaining 3 packets >>> ans.summary(lambda s:s[1].sprintf("%IP.src%")) 10.36.76.142 10.54.138.21 10.36.76.13 45.112.216.134 103.216.40.18 9.102.250.221 10.102.251.214
>>> ans,unans=sr(IP(dst="baidu.com",ttl=(1,10))/TCP(dport=53,flags="S")) Begin emission: Finished sending 10 packets. *********......................^C Received 31 packets, got 9 answers, remaining 1 packets >>> ans.summary(lambda s:s[1].sprintf("%IP.src% {ICMP:%ICMP.type%}")) 10.36.76.142 time-exceeded 10.36.76.13 time-exceeded 10.102.252.130 time-exceeded 117.49.35.150 time-exceeded 10.102.34.237 time-exceeded 111.13.123.150 time-exceeded 218.206.88.22 time-exceeded 39.156.67.73 time-exceeded 39.156.27.1 time-exceeded
Scapy包含一個內置的traceroute()函數可以實現與上面相同的功能
>>> traceroute("baidu.com") Begin emission: Finished sending 30 packets. ************************ Received 24 packets, got 24 answers, remaining 6 packets 220.181.38.148:tcp80 2 10.36.76.13 11 3 10.102.252.34 11 4 117.49.35.138 11 5 116.251.112.185 11 6 36.110.217.9 11 7 36.110.246.201 11 8 220.181.17.150 11 14 220.181.38.148 SA 15 220.181.38.148 SA 16 220.181.38.148 SA 17 220.181.38.148 SA 18 220.181.38.148 SA 19 220.181.38.148 SA 20 220.181.38.148 SA 21 220.181.38.148 SA 22 220.181.38.148 SA 23 220.181.38.148 SA 24 220.181.38.148 SA 25 220.181.38.148 SA 26 220.181.38.148 SA 27 220.181.38.148 SA 28 220.181.38.148 SA 29 220.181.38.148 SA 30 220.181.38.148 SA (<Traceroute: TCP:17 UDP:0 ICMP:7 Other:0>, <Unanswered: TCP:6 UDP:0 ICMP:0 Other:0>
我們可以通過在traceroute()函數的l4參數中指定完整的數據包來執行DNS跟蹤路由
>>> ans,unans=traceroute("60.205.177.168",l4=UDP(sport=RandShort())/DNS(qd=DNSQR(qname="thesprawl.org"))) Begin emission: ****Finished sending 30 packets. ................. Received 21 packets, got 4 answers, remaining 26 packets 60.205.177.168:udp53 1 10.2.0.1 11 2 114.242.29.1 11 4 125.33.185.114 11 5 61.49.143.2 11
“Scapy如何處理數據包”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。