网络扫描对于侵、维护都十分重要,是信息收集工作的一部分。
通过网络扫描我们可以知道主机的开放情况、主机端口的开放情况、是否采用防火墙等。
以下内容由Chat-GPT生成:
ICMP(Internet Control Message Protocol)是一种在计算机网络中广泛使用的网络层协议。它的主要目的是用于在IP网络中传输控制消息和错误报告。以下是对ICMP协议的详细解释:
- 控制消息传递:ICMP主要用于向网络中的设备发送控制消息,以执行各种网络功能。这些控制消息可以用于检测目标设备是否可达、测量网络延迟、跟踪路由路径等。
- 错误报告:当发生网络错误时,ICMP还用于生成错误报告,这些报告将被发送回源设备,以通知其发生了问题。例如,如果目标主机不可达,ICMP会生成”目标不可达”消息并将其发送回源主机。
- Ping工具:ICMP的一个常见用途是用于Ping工具。Ping工具通过发送ICMP Echo请求消息到目标主机,然后等待目标主机返回Echo响应消息来测试目标主机是否可达和网络延迟情况。
- Traceroute工具:Traceroute工具使用ICMP协议来跟踪数据包在网络中的路径。它通过发送一系列的ICMP Echo请求消息,每个请求逐步增加TTL(Time to Live)值,以便在每一跃点收到目标不可达消息时返回网络路径信息。
- ICMP消息类型:ICMP定义了多种不同类型的消息,包括Echo请求和Echo响应(用于Ping)、目标不可达消息、超时消息、路由更改通知等。每种消息类型都有特定的目的和用途。
- 网络管理和故障排除:ICMP还在网络管理和故障排除中起着关键作用。网络管理员可以使用ICMP消息来监视网络设备的状态、诊断问题以及测量网络性能。
- 可控制性:ICMP消息可以根据网络需求进行控制和配置。管理员可以选择允许或禁止特定类型的ICMP消息,以增强网络安全或满足特定需求。
ICMP报文的格式如下:
1 | +-----------------------+ |
一般来说,ICMP报文的头部固定字段有:
这些字段总共64位,也就是8字节。
Type(类型):
Code(代码):
最简单的ping程序,发送一个ICMP type 8 (回声请求)报文到目标IP地址,如果目标主机回应一个type 0的报文,那么就表示主机是开放的。
但是很多主机为了保护资产安全,都会有防火墙拦截此类报文,所以仅仅ICMP扫描对于互联网上的目标通常是不够的。
以下内容基于Nmap工具以及Nmap官方文档。
1 | nmap -sL 202.115.32.43/24 |
它仅仅列出指定网络上的每台主机, 不发送任何报文到目标主机。
也就是说,该命令的结果并不会表明主机是否开机,他只是对主机进行反向域名解析以获得它们的名字。因为这些名字也是会有有价值的信息,比如: fw.chi.playboy.com
是花花公子芝加哥办公室的防火墙。
1 | nmap -sP 202.115.32.43/24 |
让Nmap仅仅使用ping扫描,然后打印有反应的主机。
地毯式ping而非广播ping,许多主机都不会响应广播请求。
-sP
选项在默认情况下, 发送一个ICMP回声请求和一个TCP报文到80端口。如果非特权用户执行,就发送一个SYN报文 (用connect()
系统调用)到目标机的80端口。 当特权用户扫描局域网上的目标机时,会发送ARP请求(-PR
), ,除非使用了--send-ip
选项。-sP
选项可以和除-P0
)之外的任何发现探测类型-P*
选项结合使用以达到更大的灵活性。 一旦使用了任何探测类型和端口选项,默认的探测(ACK和回应请求)就被覆盖了。 当防守严密的防火墙位于运行Nmap的源主机和目标网络之间时, 推荐使用那些高级选项。否则,当防火墙捕获并丢弃探测包或者响应包时,一些主机就不能被探测到。附:ARP请求的基本工作方式:
- 设备A知道设备B的IP地址,但不知道它的MAC地址。
- 设备A创建一个ARP请求数据包,其中包含它自己的IP地址、MAC地址、目标IP地址(设备B的IP地址)以及一个特殊的ARP请求操作码。
- 设备A将ARP请求数据包发送到本地网络上的所有设备。
- 其他设备(包括设备B)接收ARP请求数据包,但只有设备B会响应。
- 设备B接收ARP请求后,知道设备A需要它的MAC地址,因此设备B创建一个ARP响应数据包,其中包含它的IP地址、MAC地址,以及目标IP地址(设备A的IP地址)。
- 设备B将ARP响应数据包发送回设备A。
- 设备A接收ARP响应后,知道了设备B的MAC地址,现在可以使用它来构建数据包并将数据包发送到设备B。
1 | nmap -P0 localhost/24 |
-Pn
同-P0
,跳过主机发现。
该选项完全跳过Nmap发现阶段。 通常Nmap在进行高强度的扫描时用它确定正在运行的机器。 默认情况下,Nmap只对正在运行的主机进行高强度的探测如 端口扫描,版本探测,或者操作系统探测。
这意味着,Nmap会对给出的所有的IP地址进行扫描,好像每个IP所对应的主机都是开启的。
1 | PS D:\Program Files (x86)\Nmap> nmap -P0 192.168.1.105/31 |
1 | nmap -PS localhost/24 |
该选项发送一个设置了SYN标志位的空TCP报文。 默认目的端口为80 (可以通过改变
nmap.h
) 文件中的DEFAULT-TCP-PROBE-PORT值进行配置,但不同的端口也可以作为选项指定。 甚至可以指定一个以逗号分隔的端口列表(如-PS22,23,25,80,113,1050,35000
), 在这种情况下,每个端口会被并发地扫描。SYN标志位告诉对方您正试图建立一个连接。 通常目标端口是关闭的,一个RST (复位) 包会发回来。 如果碰巧端口是开放的,目标会进行TCP三步握手的第二步,回应 一个SYN/ACK TCP报文。然后运行Nmap的机器则会扼杀这个正在建立的连接, 发送一个RST而非ACK报文,否则,一个完全的连接将会建立。 RST报文是运行Nmap的机器而不是Nmap本身响应的,因为它对收到 的SYN/ACK感到很意外。
Nmap并不关心端口开放还是关闭。 无论RST还是SYN/ACK响应都告诉Nmap该主机正在运行。
在UNIX机器上,通常只有特权用户
root
能否发送和接收 原始的TCP报文。因此作为一个变通的方法,对于非特权用户, Nmap会为每个目标主机进行系统调用connect(),它也会发送一个SYN 报文来尝试建立连接。如果connect()迅速返回成功或者一个ECONNREFUSED 失败,下面的TCP堆栈一定已经收到了一个SYN/ACK或者RST,该主机将被 标志位为在运行。 如果连接超时了,该主机就标志位为down掉了。这种方法也用于IPv6 连接,因为Nmap目前还不支持原始的IPv6报文。
这类方法也用于端口扫描。
1 | nmap -PA localhost |
TCP ACK ping和刚才讨论的SYN ping相当类似。 也许您已经猜到了,区别就是设置TCP的ACK标志位而不是SYN标志位。 ACK报文表示确认一个建立连接的尝试,但该连接尚未完全建立。 所以远程主机应该总是回应一个RST报文, 因为它们并没有发出过连接请求到运行Nmap的机器,如果它们正在运行的话。
-PA
选项使用和SYN探测相同的默认端口(80),也可以 用相同的格式指定目标端口列表。如果非特权用户尝试该功能, 或者指定的是IPv6目标,前面说过的connect()方法将被使用。 这个方法并不完美,因为它实际上发送的是SYN报文,而不是ACK报文。提供SYN和ACK两种ping探测的原因是使通过防火墙的机会尽可能大。 许多管理员会配置他们的路由器或者其它简单的防火墙来封锁SYN报文,除非 连接目标是那些公开的服务器像公司网站或者邮件服务器。 这可以阻止其它进入组织的连接,同时也允许用户访问互联网。 这种无状态的方法几乎不占用防火墙/路由器的资源,因而被硬件和软件过滤器 广泛支持。Linux Netfilter/iptables 防火墙软件提供方便的
--syn
选项来实现这种无状态的方法。 当这样的无状态防火墙规则存在时,发送到关闭目标端口的SYN ping探测 (-PS
) 很可能被封锁。这种情况下,ACK探测格外有闪光点,因为它正好利用了 这样的规则。另外一种常用的防火墙用有状态的规则来封锁非预期的报文。 这一特性已开始只存在于高端防火墙,但是这些年类它越来越普遍了。 Linux Netfilter/iptables 通过
--state
选项支持这一特性,它根据连接状态把报文 进行分类。SYN探测更有可能用于这样的系统,由于没头没脑的ACK报文 通常会被识别成伪造的而丢弃。解决这个两难的方法是通过即指定-PS
又指定-PA
来即发送SYN又发送ACK。
同样该方法也适用于端口扫描。
详细内容见:主机发现 | Nmap参考指南(Man Page)
Nmap把端口分成六个状态: open
(开放的), closed
(关闭的),filtered
(被过滤的), unfiltered
(未被过滤的), open|filtered(开放或者被过滤的)
,或者 closed|filtered(关闭或者被过滤的)
。
详细内容见:端口扫描基础 | Nmap参考指南(Man Page)
端口扫描技术有很多种,对于一些特定的场景,默认的扫描方法可能不适用,这就需要找出最适合的端口扫描技术,但要做到这些,前提就要了解大量的端口扫描技术。
接下来的博客内容记录Nmap的常用的端口扫描的功能。
大部分扫描类型只对特权用户可用。 这是因为他们发送接收原始报文,这在Unix系统需要root权限。 在Windows上推荐使用administrator账户,但是当WinPcap已经被加载到操作系统时, 非特权用户也可以正常使用Nmap。当Nmap在1997年发布时,需要root权限是一个严重的 局限,因为很多用户只有共享的shell账户。现在,世界变了,计算机便宜了,更多人拥有互联网连接 ,桌面UNIX系统 (包括Linux和MAC OS X)很普遍了。Windows版本的Nmap现在也有了,这使它可以运行在更多的桌面上。 由于所有这些原因,用户不再需要用有限的共享shell账户运行Nmap。 这是很幸运的,因为特权选项让Nmap强大得多也灵活得多。
虽然Nmap努力产生正确的结果,但请记住所有结果都是基于目标机器(或者它们前面的防火墙)返回的报文的。 。这些主机也许是不值得信任的,它们可能响应以迷惑或误导Nmap的报文。 更普遍的是非RFC兼容的主机以不正确的方式响应Nmap探测。FIN,Null和Xmas扫描 特别容易遇到这个问题。
1 | nmap -sS localhost -p portNum |
TCP SYN是Nmap的默认扫描,执行的速度很快。
而且不易被察觉,因为没有完成完整的TCP连接,而且几乎所有的平台都遵守统一规则。可以明确地区分端口的状态。
TCP SYN被称为半开放扫描, 因为它不打开一个完全的TCP连接。它发送一个SYN报文, 就像您真的要打开一个连接,然后等待响应。 SYN/ACK表示端口在监听 (开放
open
),而 RST (复位)表示没有监听者closed
。如果数次重发后仍没响应, 该端口就被标记为被过滤filtered
。如果收到ICMP不可到达错误 (类型3,代码1,2,3,9,10,或者13),该端口也被标记为被过滤。
1 | nmap -sT localhost -p portNum |
创建系统调用connect(),直接与目标端口建立连接,所以并不会构造原始报文并发送。
系统中的网络应用程序一样会调用connect(),用于与其他主机通信。
Nmap会使用该API读取每个连接的信息,而不是分析原始报文。这导致,TCP connect()扫描耗费的时间比SYN扫描要长许多。
当SYN扫描可用时,它通常是更好的选择。因为Nmap对高层的
connect()
调用比对原始报文控制更少, 所以TCP connect()的效率较低。 该系统调用完全连接到开放的目标端口而不是像SYN扫描进行 半开放的复位。这不仅花更长时间,需要更多报文得到同样信息,目标机也更可能 记录下连接。IDS(入侵检测系统)可以捕获两者,但大部分机器没有这样的警报系统。 当Nmap连接,然后不发送数据又关闭连接, 许多普通UNIX系统上的服务会在syslog留下记录,有时候是一条加密的错误消息。 此时,有些真正可怜的服务会崩溃,虽然这不常发生。如果管理员在日志里看到来自同一系统的 一堆连接尝试,她应该知道她的系统被扫描了。
1 | nmap -sU localhost -p portNum |
由于大多数服务都是运行在TCP协议上的,但是也有运行在UDP协议上的服务,可以使用-sU命令进行扫描。
虽然互联网上很多流行的服务运行在TCP 协议上,UDP服务也不少。 DNS,SNMP,和DHCP (注册的端口是53,161/162,和67/68)是最常见的三个。 因为UDP扫描一般较慢,比TCP更困难,一些安全审核人员忽略这些端口。 这是一个错误,因为可探测的UDP服务相当普遍,攻击者当然不会忽略整个协议。 所幸,Nmap可以帮助记录并报告UDP端口。
UDP扫描用
-sU
选项激活。它可以和TCP扫描如 SYN扫描 (-sS
)结合使用来同时检查两种协议。UDP扫描发送空的(没有数据)UDP报头到每个目标端口。 如果返回ICMP端口不可到达错误(类型3,代码3), 该端口是
closed
(关闭的)。 其它ICMP不可到达错误(类型3, 代码1,2,9,10,或者13)表明该端口是filtered
(被过滤的)。 偶尔地,某服务会响应一个UDP报文,证明该端口是open
(开放的)。 如果几次重试后还没有响应,该端口就被认为是open|filtered
(开放|被过滤的)。 这意味着该端口可能是开放的,也可能包过滤器正在封锁通信。 可以用版本扫描(-sV
)帮助区分真正的开放端口和被过滤的端口。
UDP扫描的问题:
UDP扫描的巨大挑战是怎样使它更快速。 开放的和被过滤的端口很少响应,让Nmap超时然后再探测,以防探测帧或者 响应丢失。关闭的端口常常是更大的问题。 它们一般发回一个ICMP端口无法到达错误。但是不像关闭的TCP端口响应SYN或者Connect 扫描所发送的RST报文,许多主机在默认情况下限制ICMP端口不可到达消息。 Linux和Solaris对此特别严格。例如, Linux 2.4.20内核限制一秒钟只发送一条目标不可到达消息
1 | nmap -sN localhost -p portNum |
这是根据TCP RFC中的规范发展出来的扫描方法。
如果扫描系统遵循该RFC,当端口关闭时,任何不包含SYN,RST,或者ACK位的报文会导致 一个RST返回,而当端口开放时,应该没有任何响应。只要不包含SYN,RST,或者ACK, 任何其它三种**(FIN,PSH,and URG)**的组合都行。Nmap有三种扫描类型利用这一点:
Null扫描 (
-sN
)不设置任何标志位(tcp标志头是0)
FIN扫描 (
-sF
)只设置TCP FIN标志位。
Xmas扫描 (
-sX
)设置FIN,PSH,和URG标志位,就像点亮圣诞树上所有的灯一样。
除了探测报文的标志位不同,这三种扫描在行为上完全一致。 如果收到一个RST报文,该端口被认为是
closed
(关闭的),而没有响应则意味着 端口是open|filtered
。 如果收到ICMP不可到达错误(类型 3,代号 1,2,3,9,10,或者13),该端口就被标记为filtered
。
优势:可以躲过一些防火墙,没有建立连接比较神秘。
劣势:并非所有的系统平台都遵循了词条RFC规定。在这些平台(包含Windows)上,针对这样的不含SYN、RST、ACK的报文,端口无论开放或者关闭,都会返回RST,导致所有端口都被标记为closed。并且它不能辨别端口是open
还是filtered
。
但是大多数的Unix操作系统都可以使用此类方法。
1 | nmap -sA localhost -p portNum |
上一种将ACK SYN RST置零的扫描模式无法确定端口是open
还是filtered
,
-sA TCP ACK扫描方式与前面都不同,它无法确定端口处于open
还是closed
,它的作用是确定防火墙是否启用,即端口是否被过滤。
原理:
ACK扫描探测报文只设置ACK标志位(除非您使用
--scanflags
)。当扫描未被过滤的系统时,open
(开放的)和closed
(关闭的) 端口 都会返回RST报文。Nmap把它们标记为unfiltered
(未被过滤的),意思是 ACK报文不能到达,但至于它们是open
(开放的)或者closed
(关闭的) 无法确定。不响应的端口 或者发送特定的ICMP错误消息(类型3,代号1,2,3,9,10, 或者13)的端口,标记为filtered
(被过滤的)。
1 | nmap -sW localhost -p portNum |
窗口扫描其实与ACK扫描差不多,它会分析返回的RST报文。
它与ACK扫描一样,发送TCP ACK数据包,但是将TCP 窗口字段设为非零值,意在与对方服务器商讨窗口范围。如果服务器返回的RST报文中,窗口值的大小为正数,那么该端口的状态为open
,如果为0,则closed
,而ACK扫描仅会将其判定为unfiltered
。
该扫描依赖于互联网上少数系统的实现细节, 因此您不能永远相信它。不支持它的系统会通常返回所有端口
closed
。 当然,一台机器没有开放端口也是有可能的。 如果大部分被扫描的端口是closed
,而一些常见的端口 (如 22, 25,53) 是filtered
,该系统就非常可疑了。 偶尔地,系统甚至会显示恰恰相反的行为。 如果您的扫描显示1000个开放的端口和3个关闭的或者被过滤的端口, 那么那3个很可能也是开放的端口。
1 | nmap --scanflags SYNACK localhost -p 80 |
☆ 还需要指定响应类型,如果不指定,就会用SYN扫描的响应类型来分析返回的数据包。
除了设置需要的标志位,您也可以设置 TCP扫描类型(如
-sA
或者-sF
)。 那个基本类型告诉Nmap怎样解释响应。例如, SYN扫描认为没有响应意味着filtered
端口,而FIN扫描则认为是open|filtered
。 除了使用您指定的TCP标记位,Nmap会和基本扫描类型一样工作。 如果您不指定基本类型,就使用SYN扫描。
自定义头部,自定义响应类型可以更加灵活地对端口进行扫描。
-sI <zombie host[:probeport]>
(Idlescan)-sO
(IP协议扫描)-b <ftp relay host>
(FTP弹跳扫描)详细内容见:端口扫描技术 | Nmap参考指南(Man Page)
-p portNum
扫描指定端口-F
快速扫描-r
随机扫描端口待补充,可以参见:Nmap参考指南(Man Page)
实验要求:
本次实验主要对主机扫描和端口扫描原理的理解。使用python(scapy库)编写端口扫描程序,对目标IP(包含IP地址段)进行扫描,完成以下功能:
1)使用icmp协议探测主机是否开启;
2)对本机(关闭防火墙)的开放端口和非开放端口完成半连接、ACK、FIN、Null、Xmas、windows扫描,并与nmap扫描结果进行比较。
3)对远程(有防火墙)主机的开放端口和非开放端口完成半连接、ACK、FIN、Null、Xmas、windows扫描,并与2)进行比较,分析结果。
4)回答问题:样例程序中“conf.L3socket=L3RawSocket”的作用是什么?
实验代码部分:
1 | # 导入所需的库 |
本次实验主要是通过python代码实现网络数据包的构造、发送、接收、分析。
再通过计算机网络知识结合RFC规则,判断主机和端口状态。