kavin

数据包处理利器—Scapy高级使用(一)

kavin 安全防护 2022-12-12 343浏览 0

数据包处理利器—Scapy高级使用(一)

主机探测

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连接扫描

找了个网图( 侵删)

数据包处理利器—Scapy高级使用(一)

这里展示一下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高级使用(一)

数据包处理利器—Scapy高级使用(一)

接下来我们使用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的包。

数据包处理利器—Scapy高级使用(一)

端口开放

>>>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错误表示该端口已被过滤,获取不到端口状态。

数据包处理利器—Scapy高级使用(一)

数据包处理利器—Scapy高级使用(一)

端口关闭

>>>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错误表示该端口已被过滤,获取不到端口状态。

数据包处理利器—Scapy高级使用(一)

数据包处理利器—Scapy高级使用(一)

端口关闭

>>>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错误数据包,表示该端口在服务器是关闭状态。

数据包处理利器—Scapy高级使用(一)

>>>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

继续浏览有关 安全 的文章
发表评论