网络资产扫描-masscan和nmap结合扫描

 

一、引言:

  公司从2018年开始研发CMDB,项目的定位的方向是①作为公司产品的资产数据中心,提供统一的模型和对外接口,统一维护一份资产信息,避免各个产品(比如,全栈智能监控、自动化运维、带外、smartLog等)各自维护CI。②作为资源全生命周期管理平台,融合流程产品和CMDB自动发现能力,做一个闭环CI管理系统,提供最准确的设备资产信息及CI之间关系(部署、父子、包含、引用等)、机房机柜逻辑图等。作为其中一个亮点功能,指定网段或指定IP的CI扫描就必不可少。

 

二、网络资产扫描作用:

   通过原始IP报文来发现网络上存活的主机、主机提供的服务(应用程序名和版本)、服务运行的操作系统(包括版本信息),以及使用什么类型的报文过滤器/防火墙(对扫描的异常结果做分析)等。

 

三、masscan和Nmap分析:

1、masscan

 (1)优势----在6分钟内扫描完整个IPv4

  masscan使用的是无状态扫描的方法。TCP连接是有状态的,需要对SYN-ACK包进行seq number的校验这个等待连接的过程需要在缓冲区占用很大的资源,因此限制了扫描的速度。masscan无状态的扫描则是masscan与目标主机不建立完整的TCP连接,扫描者主机先向目标主机发送一个SYN请求连接数据包,目标主机会向扫描者主机回复一个SYN/ACK确认连接数据包,当扫描者主机收到目标主机发送回来的SYN/ACK确认连接数据包之后,扫描者主机向目标主机发送RST结束连接(选项–banners除外(因为要获取banner信息,必须要进行完整的三次握手))。即masscan不建立完整的TCP连接,收到SYN/ACK之后,发送RST结束连接(选项--banners除外)。masscan采用异步的方式批量的把数据包发出去,然后记录有回应的IP。因此,效率上得以大幅提高。

   (1.1) 补充:无状态扫描的原理

    TCP协议中三次握手的前两次

  1. 客户端在向服务器第一次握手时,会组建一个数据包,设置syn标志位,同时生成一个数字填充seq序号字段。
  2. 服务端收到数据包,检测到了标志位的syn标志,知道这是客户端发来的建立连接的请求包,服务端会回复一个数据包,同时设置syn和ack标志位,服务器随机生成一个数字填充到seq字段。并将客户端发送的seq数据包+1填充到ack确认号上。
  3. 在收到syn和ack后,我们返回一个rst来结束这个连接,如图所示

masscan无状态扫描原理,就是利用了这一步,因为seq是可以自定义的,所以在发送数据包时填充一个特定的数字,而在返回包中可以获得相应的响应状态,即是无状态扫描的思路了。

  

 (2)缺点

  masscan速度快,但只能扫描端口。异步传输意味着扫描仪在发送探测器之前不必等待回复。由于无状态的发包方式,如果遇到丢包的情况,不像有连接时候会进行重复查询,而是直接没有回应,因此准确率上不如SYN扫描那么准确,但是可以用重复扫描来弥补准确性上面的缺陷。

 

2、Nmap(Network Mapper)

  nmap是一款开源免费的网络发现(Network Discovery)和安全审计(Security Auditing)工具。Nmap可以检测目标机是否在线、端口开放情况、侦测运行的服务类型及版本信息、侦测操作系统与设备类型等信息。官网地址 https://nmap.org/

 2.1、Nmap包含四项基本功能:

  • 主机发现(Host Discovery)
  • 端口扫描(Port Scanning)
  • 版本侦测(Version Detection)
  • 操作系统侦测(Operating System Detection)

2.2、常用Nmap指令:

(1)完整全面的扫描

    如果希望对某台主机进行完整全面的扫描,那么可以使用nmap内置的-A选项。使用了改选项,nmap对目标主机进行主机发现、端口扫描、应用程序与版本侦测、操作系统侦测及调用默认NSE脚本扫描。

nmap –T4 –A –v targethost

  其中-A选项用于使用进攻性(Aggressive)方式扫描;-T4指定扫描过程使用的时序(Timing),总有6个级别(0-5),级别越高,扫描速度越快,但也容易被防火墙或IDS检测并屏蔽掉,在网络通讯状况良好的情况推荐使用T4;-v表示显示冗余(verbosity)信息,在扫描过程中显示扫描的细节,从而让用户了解当前的扫描状态。 
例如,扫描局域网内地址为192.168.1.100的电脑。显而易见,扫描出的信息非常丰富,在对192.168.1.100的扫描报告部分中(以红框圈出),可以看到主机发现的结果“Host is up”;端口扫描出的结果,有996个关闭端口,4个开放端口(在未指定扫描端口时,Nmap默认扫描1000个最有可能开放的端口);而版本侦测针对扫描到的开放状况进一步探测端口上运行的具体的应用程序和版本信息;OS侦测对该目标主机的设备类型与操作系统进行探测;而绿色框图是nmap调用NSE脚本进行进一步的信息挖掘的显示结果。

(2)主机发现

  主机发现(Host Discovery),即用于发现目标主机是否在线(Alive,处于开启状态)。

     (2.1)主机发现原理

  主机发现发现的原理与Ping命令类似,发送探测包到目标主机,如果收到回复,那么说明目标主机是开启的。Nmap支持十多种不同的主机探测方式,比如发送ICMP ECHO/TIMESTAMP/NETMASK报文、发送TCPSYN/ACK包、发送SCTP INIT/COOKIE-ECHO包,用户可以在不同的条件下灵活选用不同的方式来探测目标机。

  Nmap的用户位于源端,IP地址192.168.0.5,向目标主机192.168.0.3发送ICMP Echo Request。如果该请求报文没有被防火墙拦截掉,那么目标机会回复ICMP Echo Reply包回来。以此来确定目标主机是否在线。

  默认情况下,Nmap会发送四种不同类型的数据包来探测目标主机是否在线。

  1. ICMP echo request
  2. a TCP SYN packet to port 443
  3. a TCP ACK packet to port 80
  4. an ICMP timestamp request

  依次发送四个报文探测目标机是否开启。只要收到其中一个包的回复,那就证明目标机开启。使用四种不同类型的数据包可以避免因防火墙或丢包造成的判断错误。

  (2.2)常用指令:

  用法示例:

nmap –sn –PE –PS80,135 –PU53 scanme.nmap.org 

  探测局域网内活动主机:

nmap –sn 192.168.10.100-120 

  参数选项:

-sL: List Scan 列表扫描,仅将指定的目标的IP列举出来,不进行主机发现。  
-sn: Ping Scan 只进行主机发现,不进行端口扫描。  
-Pn: 将所有指定的主机视作开启的,跳过主机发现的过程。  
-PS/PA/PU/PY[portlist]: 使用TCPSYN/ACK或SCTP INIT/ECHO方式进行发现。  
-PE/PP/PM: 使用ICMP echo, timestamp, and netmask 请求包发现主机。-PO[protocollist]: 使用IP协议包探测对方主机是否开启。  
-n/-R: -n表示不进行DNS解析;-R表示总是进行DNS解析。  
--dns-servers : 指定DNS服务器。  
--system-dns: 指定使用系统的DNS服务器  
--traceroute: 追踪每个路由节点

  扫描target主机所有的TCP端口

nmap -v targethost

 

(3)端口扫描

  端口扫描是Nmap最基本最核心的功能,用于确定目标主机的TCP/UDP端口的开放情况。默认情况下,Nmap会扫描1000个最有可能开放的TCP端口。

  Nmap通过探测将端口划分为6个状态:

  • open:端口是开放的。
  • closed:端口是关闭的。
  • filtered:端口被防火墙IDS/IPS屏蔽,无法确定其状态。
  • unfiltered:端口没有被屏蔽,但是否开放需要进一步确定。
  • open|filtered:端口是开放的或被屏蔽。
  • closed|filtered :端口是关闭的或被屏蔽。

 扫描方式选项:

-sS/sT/sA/sW/sM:指定使用 TCP SYN/Connect()/ACK/Window/Maimon scans的方式来对目标主机进行扫描。
-sU: 指定使用UDP扫描方式确定目标主机的UDP端口状况。
-sN/sF/sX: 指定使用TCP Null, FIN, and Xmas scans秘密扫描方式来协助探测对方的TCP端口状态。
--scanflags <flags>: 定制TCP包的flags。
-sI <zombiehost[:probeport]>: 指定使用idle scan方式来扫描目标主机(前提需要找到合适的zombie host)
-sY/sZ: 使用SCTP INIT/COOKIE-ECHO来扫描SCTP协议端口的开放的情况。
-sO: 使用IP protocol 扫描确定目标机支持的协议类型。
-b <FTP relay host>: 使用FTP bounce scan扫描方式

  说明:

     -sA        ACK扫描       检查端口是否开放,可用于探测防火墙 

     -sP        Ping扫描      快速发现网络 

     -sR        PRC扫描       定位PRC,对成功扫描的机器记录 

     -sS        TCP SYN扫描   快速和隐蔽的扫描,半开放扫描 

     -sU        UDP扫描       确定符合特定UDP端口是否开放 

     -sX        XMAS扫描      隐蔽扫描,扫描特定配置的防火墙 

     -sL        列出扫描对象  列出要扫描的IP,使用-n选项确保不向网络中发数据包 

     -sO        IP协议扫描    寻找使用IP协议的主机 

     -sM        FIN/ACK扫描   隐蔽扫描,适用于unix系统 

     -sI          闲置扫描      僵尸主机扫描,非常隐蔽

  

端口参数及扫描顺序

-p <port ranges>: 扫描指定的端口
-F: Fast mode – 快速模式,仅扫描TOP 100的端口
-r: 不进行端口随机打乱的操作(如无该参数,nmap会将要扫描的端口以随机顺序方式扫描,以让nmap的扫描不易被对方防火墙检测到)。
--top-ports <number>:扫描开放概率最高的number个端口(nmap的作者曾经做过大规模地互联网扫描,以此统计出网络上各种端口可能开放的概率。以此排列出最有可能开放端口的列表,具体可以参见文件:nmap-services。默认情况下,nmap会扫描最有可能的1000个TCP端口)
--port-ratio <ratio>: 扫描指定频率以上的端口。与上述--top-ports类似,这里以概率作为参数,让概率大于--port-ratio的端口才被扫描。显然参数必须在在0到1之间,具体范围概率情况可以查看nmap-services文件。

  参数用法示例:

-p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9(其中T代表TCP协议、U代表UDP协议、S代表SCTP协议)

  常用指令:

nmap –sS –sU –T4 –top-ports port号 ip地址

  参数-sS表示使用TCP SYN方式扫描TCP端口;

  -sU表示扫描UDP端口;

  -T4表示时间级别配置4级;

  --top-ports 300表示扫描最有可能开放的300个端口(TCP和UDP分别有300个端口)。

 

确定端口状况:

  如果直接针对某台计算的IP地址或域名进行扫描,那么Nmap对该主机进行主机发现过程和端口扫描。该方式执行迅速,可以用于确定端口的开放状况。

nmap targethost

 

 (4)版本侦测

  用于确定目标主机开放端口上运行的具体的应用程序及版本信息。

 (4.1)原理

  简要的介绍版本的侦测原理。版本侦测主要分为以下几个步骤:

  1. 首先检查open与open|filtered状态的端口是否在排除端口列表内。如果在排除列表,将该端口剔除。
  2. 如果是TCP端口,尝试建立TCP连接。尝试等待片刻(通常6秒或更多,具体时间可以查询文件nmap-services-probes中Probe TCP NULL q||对应的totalwaitms)。通常在等待时间内,会接收到目标机发送的“WelcomeBanner”信息。nmap将接收到的Banner与nmap-services-probes中NULL probe中的签名进行对比。查找对应应用程序的名字与版本信息。
  3. 如果通过“Welcome Banner”无法确定应用程序版本,那么nmap再尝试发送其他的探测包(即从nmap-services-probes中挑选合适的probe),将probe得到回复包与数据库中的签名进行对比。如果反复探测都无法得出具体应用,那么打印出应用返回报文,让用户自行进一步判定。
  4. 如果是UDP端口,那么直接使用nmap-services-probes中探测包进行探测匹配。根据结果对比分析出UDP应用服务类型。
  5. 如果探测到应用程序是SSL,那么调用openSSL进一步的侦查运行在SSL之上的具体的应用类型。
  6. 如果探测到应用程序是SunRPC,那么调用brute-force RPC grinder进一步探测具体服务。

 (4.2)Nmap提供的版本侦测具有如下的优点:

  • 高速。并行地进行套接字操作,实现一组高效的探测匹配定义语法。
  • 尽可能地确定应用名字与版本名字。
  • 支持TCP/UDP协议,支持文本格式与二进制格式。
  • 支持多种平台服务的侦测,包括Linux/Windows/Mac OS/FreeBSD等系统。
  • 如果检测到SSL,会调用openSSL继续侦测运行在SSL上的具体协议(如HTTPS/POP3S/IMAPS)。
  • 如果检测到SunRPC服务,那么会调用brute-force RPC grinder进一步确定RPC程序编号、名字、版本号。
  • 支持完整的IPv6功能,包括TCP/UDP,基于TCP的SSL。
  • 通用平台枚举功能(CPE)
  • 广泛的应用程序数据库(nmap-services-probes)。目前Nmap可以识别几千种服务的签名,包含了180多种不同的协议。

  常用指令:

nmap –sV ip地址

  版本侦测的指令选项:

-sV: 指定让Nmap进行版本侦测
--version-intensity <level>: 指定版本侦测强度(0-9),默认为7。数值越高,探测出的服务越准确,但是运行时间会比较长。
--version-light: 指定使用轻量侦测方式 (intensity 2)
--version-all: 尝试使用所有的probes进行侦测 (intensity 9)
--version-trace: 显示出详细的版本侦测过程信息。

 

(5)OS侦测

  操作系统侦测用于检测目标主机运行的操作系统类型及设备类型等信息。Nmap拥有丰富的系统数据库nmap-os-db,目前可以识别2600多种操作系统与设备类型。

 (5.1)OS侦测原理

  Nmap使用TCP/IP协议栈指纹来识别不同的操作系统和设备。在RFC规范中,有些地方对TCP/IP的实现并没有强制规定,由此不同的TCP/IP方案中可能都有自己的特定方式。Nmap主要是根据这些细节上的差异来判断操作系统的类型的。

  具体实现方式如下:

  1. Nmap内部包含了2600多已知系统的指纹特征(在文件nmap-os-db文件中)。将此指纹数据库作为进行指纹对比的样本库。
  2. 分别挑选一个open和closed的端口,向其发送经过精心设计的TCP/UDP/ICMP数据包,根据返回的数据包生成一份系统指纹。
  3. 将探测生成的指纹与nmap-os-db中指纹进行对比,查找匹配的系统。如果无法匹配,以概率形式列举出可能的系统。

  常用指令:

nmap –O targethost

  OS侦测指令选项:

-O: 指定Nmap进行OS侦测。
--osscan-limit: 限制Nmap只对确定的主机的进行OS探测(至少需确知该主机分别有一个open和closed的端口)。
--osscan-guess: 大胆猜测对方的主机的系统类型。由此准确性会下降不少,但会尽可能多为用户提供潜在的操作系统。

 

详细了解可参考https://www.cnblogs.com/guge-94/p/11322334.html

 

masscan在存活主机主机扫描方面速度要高于Nmap,故为提高扫描准确度,可以先使用masscan扫描开启的端口,再用nmap进行详细的扫描。

 

四、代码示例(使用python脚本)

masscan扫描存活主机

 1 # -*- coding: UTF-8 -*-
 2 import re
 3 import commands
 4 import sys
 5 reload(sys)
 6 sys.setdefaultencoding('utf8')
 7 
11 # 执行命令
12 state, stdout = commands.getstatusoutput("masscan 指定ip -p22 --rate 10000")
13 # 获取命令结果
14 msgArr = []
15 discvArr = stdout.split("\n")
16 for discv in discvArr:
17     msgArr.append("".join(discv.encode("ascii")).strip().strip("\n"))
18 
19 set_addr = set()
20 set_ip = set()
21 addr = ""
22 for msg in msgArr[3:]:
23     if "Discovered" in msg:
24         discvArr = msg.split(" on ")
25         ip = discvArr[1]  # 截取ip地址
26         port = re.findall(".*port(.*)/tcp.*", info)  # 取出端口号
27         addr = ip.strip() + ":" + str(port).strip()
28         addr = addr.replace('[\' ', '').replace('\']', '').replace('[', '').replace(']', '')
29 
30         set_addr.add(addr)  # 保存扫描出的ip地址端口号
31         set_ip.add(ip)  # 保存ip地址
32 
33 for ip in set_ip:
34     print ip

Nmap精确扫描存活主机端口

 1 # -*- coding: UTF-8 -*-
 2 import commands
 3 import re
 4 import socket
29 
31 # 执行操作系统扫描任务
34 state, stdout = commands.getstatusoutput('nmap -O --osscan-guess -p ' + 指定端口+ ' ' + ip地址)
35 # 获取命令结果
36 discvArr = stdout.split("\n")
37 
38 msgArr = []
39 os = ""
40 hostname = ip2hostname(ip)
41 if hostname is None:
42     hostname = "未知服务"

44 for discv in discvArr:
45     disv = discv.lower()
53     # 操作系统
54     if "aggressive os guesses: " in discv:
55         os = discv[22:discv.find(",")].strip()
56     if "os details:" in discv:
57         os = discv.replace("os details:", "").strip()
58     # 主机名称和操作系统,ip:port##ssh@host@os
59     if re.match('\d+/\w+.*open.*', discv):
62         port = discv[0:discv.index('/')]
63         resName = discv[discv.index('open') + 4:]
64         line = ip + ':' + port + '##' + resName.strip()
66         msgArr.append(line)68 for line in msgArr:
69     line = line + "@" + hostname + "@" + os
70     print line

 

五、资料共享

masscan git地址 https://github.com/topics/masscan

Nmap git地址 https://github.com/nmap/nmap

 

 感谢各位大佬的分享,收获不少,同时也感谢您的阅读,如需转载请注明出处https://www.cnblogs.com/huyangshu-fs/p/13324701.html

posted on 2020-09-06 21:48  ys-fullStack  阅读(8735)  评论(0编辑  收藏  举报