网络资产扫描-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

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

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

 2.2、Nmap在端口扫描方面非常强大,提供了十多种探测方式。

     -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        闲置扫描      僵尸主机扫描,非常隐蔽

详细了解可参考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 infoArr = []
15 discoverArr = stdout.split("\n")
16 for discover in discoverArr:
17     infoArr.append("".join(discover.encode("ascii")).strip().strip("\n"))
18 
19 set_addr = set()
20 set_ip = set()
21 addr = ""
22 for info in infoArr[3:]:
23     if "Discovered" in info:
24         discoverArr = info.split(" on ")
25         ip = discoverArr[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 discoverArr = stdout.split("\n")
37 
38 infoArr = []
39 os = ""
40 hostname = ip2hostname(ip)
41 if hostname is None:
42     hostname = "未知服务"

44 for discover in discoverArr:
45     discover = discover.lower()
53     # 操作系统
54     if "aggressive os guesses: " in discover:
55         os = discover[22:discover.find(",")].strip()
56     if "os details:" in discover:
57         os = discover.replace("os details:", "").strip()
58     # 主机名称和操作系统,ip:port--ssh@host@os
59     if re.match('\d+/\w+.*open.*', discover):
62         port = discover[0:discover.index('/')]
63         resName = discover[discover.index('open') + 4:]
64         line = ip + ':' + port + '--' + resName.strip()
66         infoArr.append(line)
67     if re.match('\d+/\w+.*filtered.*', discover):
70         port = discover[0:discover.index('/')]
71         resName = discover[discover.index('filtered') + 8:]
72         line = ip + ':' + port + '--' + resName.strip()
74         infoArr.append(line)

75 for line in infoArr:
76     line = line + "@" + hostname + "@" + os
77     print line

 

五、资料共享

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

Nmapgit地址 https://github.com/nmap/nmap

 

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章