主机探测
TCP SYN Ping
- 发送仅设置了SYN的空TCP数据包。
- SYN/ACK或RST响应表示机器已启动并正在运行。
>>>ans,unans=sr(IP(dst="60.205.177.0/28")/TCP(dport=80,flags="S")) Beginemission: Finishedsending16packets. .*********..................................................................................^C Received92packets,got9answers,remaining7packets >>>ans.summary(lambdas:s[1].sprintf("%IP.src%isalive")) 60.205.177.1isalive 60.205.177.2isalive 60.205.177.4isalive 60.205.177.6isalive 60.205.177.7isalive 60.205.177.8isalive 60.205.177.11isalive 60.205.177.12isalive 60.205.177.14isalive
TCP ACK Ping
- 发送仅设置了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')) Beginemission: Finishedsending16packets. .*.******....................................................................................................................................................................^C Received173packets,got7answers,remaining9packets >>>ans.summary(lambdas:s[1].sprintf("{IP:%IP.src%isalive}")) 60.205.177.91isalive 60.205.177.94isalive 60.205.177.95isalive 60.205.177.97isalive 60.205.177.100isalive 60.205.177.101isalive 60.205.177.102isalive
UDP Ping
- 将UDP数据包发送给给定的端口(无论是否带有有效载荷),协议特定的有效载荷会使扫描更加有效。
- 选择最有可能关闭的端口(开放的UDP端口可能会收到空数据包,但会忽略它们)。
- ICMP端口不可达表示机器是启动的。
>>>ans,unans=sr(IP(dst='60.205.177.100-254')/UDP(dport=90),timeout=0.1) Beginemission: Finishedsending155packets. ..******..*****... Received18packets,got11answers,remaining144packets >>>ans.summary(lambdas:s[1].sprintf("%IP.src%isunreachable")) 60.205.177.106isunreachable 60.205.177.108isunreachable 60.205.177.107isunreachable 60.205.177.111isunreachable 60.205.177.125isunreachable 60.205.177.172isunreachable 60.205.177.191isunreachable 60.205.177.203isunreachable 60.205.177.224isunreachable 60.205.177.242isunreachable 60.205.177.244isunreachable
ARP Ping
- 在同一网络/ 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) Beginemission: Finishedsending256packets. *******************************************************************************.***********************************************************************************........................... Received190packets,got162answers,remaining94packets >>>ans.summary(lambdar:r[0].sprintf("%Ether.src%%ARP.pdst%")) 00:16:3e:0c:d1:ad172.17.51.0 00:16:3e:0c:d1:ad172.17.51.1 00:16:3e:0c:d1:ad172.17.51.2 00:16:3e:0c:d1:ad172.17.51.3 00:16:3e:0c:d1:ad172.17.51.4 00:16:3e:0c:d1:ad172.17.51.5 00:16:3e:0c:d1:ad172.17.51.6 00:16:3e:0c:d1:ad172.17.51.7
ICMP Ping
- ICMP扫描涉及无处不在的_ping程序_发送的标准数据包。
- 向目标IP发送一个ICMP类型8(回显请求)数据包,收到一个ICMP类型0(回显应答)的包表示机器存活。
- 现在许多主机和防火墙阻止这些数据包,因此基本的ICMP扫描是不可靠的。
- ICMP还支持时间戳请求和地址掩码请求,可以显示计算机的可用性。
>>>ans,unans=sr(IP(dst="60.205.177.168-180")/ICMP()) >>>ans.summary(lambdas:s[0].sprintf("{IP:%IP.dst%isalive}")) 60.205.177.168isalive 60.205.177.169isalive 60.205.177.171isalive 60.205.177.172isalive 60.205.177.175isalive 60.205.177.174isalive 60.205.177.176isalive 60.205.177.179isalive 60.205.177.178isalive 60.205.177.180isalive
服务发现(端口扫描)
TCP连接扫描
找了个网图( 侵删)
这里展示一下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=9998ack=12346 192.168.2.1.35555>192.168.2.12.4444:Flags[.]seq=12346ack=9999
IP与端口号之间以’.’分隔,ACK用’.’表示,SYN用’S’表示,而[S.]则表示SYN+ACK
在Scapy中制作三次握手包
第1步-将客户端的SYN发送到侦听服务器
- 使用源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)
第2步-监听服务器的响应(SYN-ACK)
- 保存服务器的响应。
- 获取服务器的TCP序列号,并将该值加1。
synack_packet=sr1(ip/syn_packet) my_ack=synack_packet.seq+1
第3步从客户端发送对服务器响应的确认(ACK)
- 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 fromscapy.allimport* #构建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数据包,如果端口开放,那么服务端会响应一个syn+ack的数据包,之后客户端会发送rst数据包进行重置。否则服务端会直接响应一个rst包,表示端口没有开放。如果我们发了大量的syn包而不去确认,服务端会继续发送syn+ack的包,会不断的消耗服务器的CPU和内存,这也就是我们常说的syn泛洪攻击了。
接下来我们使用scapy来模拟syn扫描
在单个主机,单个端口上进行SYN扫描
- 使用sr1功能发送并响应数据包
- 使用sprintf方法在响应中打印字段。(“ SA”标志表示开放的端口,“ RA”标志表示关闭的端口)
>>>syn_packet=IP(dst='60.205.177.168')/TCP(dport=22,flags='S') >>>rsp=sr1(syn_packet) Beginemission: Finishedsending1packets. ..* Received3packets,got1answers,remaining0packets >>>rsp.sprintf("%IP.src%%TCP.sport%%TCP.flags%") '60.205.177.168sshSA'
在单个主机,多个端口上进行SYN扫描
>>>ans,unans=sr(IP(dst="60.205.177.168")/TCP(dport=(20,22),flags="S")) Beginemission: Finishedsending3packets. ..*..** Received7packets,got3answers,remaining0packets >>>ans.summary(lambdas:s[1].sprintf("%TCP.sport%%TCP.flags%")) ftp_dataRA ftpRA sshSA
对多个主机,多个端口进行SYN扫描
- 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")) Beginemission: Finishedsending9packets. ..*..**..*.................................................................................................................................................................................................................................................^C Received251packets,got4answers,remaining5packets >>>ans.make_table(lambdas:(s[0].dst,s[0].dport,s[1].sprintf("%TCP.flags%"))) 60.205.177.16860.205.177.169 20RA- 22SA- 80SASA
Fin 扫描
客户端会发送带有fin标志(关闭连接)的数据包到服务端,当服务端没有响应时,表示端口是开放状态,否则会收到rst的包。
端口开放
>>>fin_packet=IP(dst='60.205.177.168')/TCP(dport=4444,flags='F') >>>resp=sr1(fin_packet) Beginemission: Finishedtosend1packets. ^C Received0packets,got0answers,remaining1packets
端口关闭
>>>fin_packet=IP(dst='60.205.177.168')/TCP(dport=4399,flags='F') >>>resp=sr1(fin_packet) >>>resp.sprintf('%TCP.flags%') 'RA'
NULL 扫描
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 扫描
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) Beginemission: .Finishedsending1packets. * Received2packets,got1answers,remaining0packets >>>xmas_scan_resp.sprintf('%TCP.flags%') 'RA'
UDP扫描
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协议。
使用ICMP进行路由跟踪
>>>ans,unans=sr(IP(dst="49.232.152.189",ttl=(1,10))/ICMP()) Beginemission: Finishedsending10packets. *****.**........................................................................................................^C Received112packets,got7answers,remaining3packets >>>ans.summary(lambdas: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
使用tcp进行路由跟踪
>>>ans,unans=sr(IP(dst="baidu.com",ttl=(1,10))/TCP(dport=53,flags="S")) Beginemission: Finishedsending10packets. *********......................^C Received31packets,got9answers,remaining1packets >>>ans.summary(lambdas:s[1].sprintf("%IP.src%{ICMP:%ICMP.type%}")) 10.36.76.142time-exceeded 10.36.76.13time-exceeded 10.102.252.130time-exceeded 117.49.35.150time-exceeded 10.102.34.237time-exceeded 111.13.123.150time-exceeded 218.206.88.22time-exceeded 39.156.67.73time-exceeded 39.156.27.1time-exceeded
Scapy包含一个内置的traceroute()函数可以实现与上面相同的功能
>>>traceroute("baidu.com") Beginemission: Finishedsending30packets. ************************ Received24packets,got24answers,remaining6packets 220.181.38.148:tcp80 210.36.76.1311 310.102.252.3411 4117.49.35.13811 5116.251.112.18511 636.110.217.911 736.110.246.20111 8220.181.17.15011 14220.181.38.148SA 15220.181.38.148SA 16220.181.38.148SA 17220.181.38.148SA 18220.181.38.148SA 19220.181.38.148SA 20220.181.38.148SA 21220.181.38.148SA 22220.181.38.148SA 23220.181.38.148SA 24220.181.38.148SA 25220.181.38.148SA 26220.181.38.148SA 27220.181.38.148SA 28220.181.38.148SA 29220.181.38.148SA 30220.181.38.148SA (<Traceroute:TCP:17UDP:0ICMP:7Other:0>, <Unanswered:TCP:6UDP:0ICMP:0Other:0>
使用DNS跟踪路由
我们可以通过在traceroute()函数的l4参数中指定完整的数据包来执行DNS跟踪路由
>>>ans,unans=traceroute("60.205.177.168",l4=UDP(sport=RandShort())/DNS(qd=DNSQR(qname="thesprawl.org"))) Beginemission: ****Finishedsending30packets. ................. Received21packets,got4answers,remaining26packets 60.205.177.168:udp53 110.2.0.111 2114.242.29.111 4125.33.185.11411 561.49.143.211
转载请注明:IT运维空间 » 安全防护 » 数据包处理利器—Scapy高级使用(一)
发表评论