如今互联网安全形势日趋严峻,给系统管理员带来很大的挑战,网络的开放性以及黑客的攻击是造成网络不安全的主因,稍有疏忽将给黑客带来可乘之机,给企业带来无法弥补的损失,比如由于系统管理员误操作,导致核心业务服务器的22,21,3389,3306等高危端口暴露在互联网上,大大提高了被入侵的风险,因此,定制一种规避此安全事故的机制已经迫在眉睫,本节主要讲述通过python的第三方模块python-nmap来实现高效的端口扫描,达到发现异常时可以再第一时间发现并处理,将安全风险降到最低的目的,python-nmap模块作为nmap命令的python封装,可以让Python很方便的操作nmap扫描器,他可以帮助管理员完成自动扫描任务和生成报告,
1.安装:
[root@mankel py] yum -y install nmap [root@mankel py] pip3 install python-nmap [root@mankel py] python3 >>> import nmap
4.2.1 模块常用方法说明
本节介绍python-nmap模块的两个常用类,一个为PortScanner()类,实现一个nmap工具的端口扫描功能封装;另一个为PortScannerHostDict()类,实现存储与访问主机的扫描结果,
下面介绍一些常用方法:
import nmap # 导入 nmap.py 模块 nm = nmap.PortScanner() # 获取 PortScanner 对象 nm.scan('127.0.0.1', '22-443') # 扫描主机 127.0.0.1 端口号 22-443 # nm.scan(self, hosts='127.0.0.1', ports=None, arguments='-sV') # hosts字符串类型,格式:"scanme.nmap.org"、"192.116.0-255.1-127"、"216.163.128.20/20" # ports字符串类型,格式:"22,53,110,143-4564" # arguments: -sS -sU -sC等 nm.command_line() # 获取用于扫描的命令行:nmap -oX - -p 22-443 127.0.0.1 nm.scaninfo() # 获取本次扫描的信息 {'tcp': {'services': '22-443', 'method': 'connect'}} nm.all_hosts() # 获取所有扫描到的主机 nm['127.0.0.1'].hostname() # 获取 127.0.0.1 的主机名 nm['127.0.0.1'].hostnames() # 获取list格式的主机名dict 127.0.0.1 # 如 [{'name':'hostname1', 'type':'PTR'}, {'name':'hostname2', 'type':'user'}] nm['127.0.0.1'].state() # 获取主机 127.0.0.1 的状态 (up|down|unknown|skipped) nm['127.0.0.1']['tcp'].keys() # 获取所有tcp端口 nm['127.0.0.1'].all_tcp() # 获取所有tcp端口 (已排序) nm['127.0.0.1'].all_udp() # 获取所有udp端口 (已排序) nm['127.0.0.1'].all_ip() # 获取所有ip端口 (已排序) nm['127.0.0.1'].all_sctp() # 获取所有sctp端口 (已排序) nm['127.0.0.1'].has_tcp(22) # 是否含有主机 127.0.0.1 的 22 端口的信息 nm['127.0.0.1']['tcp'][22] # 获取主机 127.0.0.1 22 端口(tcp)的所有信息 nm['127.0.0.1'].tcp(22) # 获取主机 127.0.0.1 22 端口的所有信息 nm['127.0.0.1'].all_protocols() #获取扫描的协议
4.2.2 实践: 实现高效的端口扫描
本次实践通过python-nmap实现一个高效的端口扫描工具,与定时作业crontab及邮件告警结合,可以很好的帮助我们及时发现异常开放的高危端口,当然,该工具也可以作为业务服务端口得可用性探测,例如扫描192.168.1.20-25网段Web服务端口80是否处于open状态,实践所采用的scan()方法的arguments参数指定为"-v -PE -p’+端口",-v表示启用细节模式,可以返回非Up状态主机清单;-PE表示采用TCP同步扫描(TCP,SYN)方式;-p指定扫描端口范围,程序输出部分采用了三个for循环体,第一层遍历扫描主机,第二层为遍历协议,第三层为遍历端口,最后输出主机状态,具体实现代码如下:
1.代码:
#!/usr/bin/python3 # -*- coding: utf-8 -*- import sys import nmap scan_row = [] input_data = input('Please input hosts and port: ') scan_row = input_data.split(" ") if len(scan_row)!=2: print("Input errors,example \"192.168.0.0 80,443,22\"") sys.exit(0) hosts = scan_row[0] port = scan_row[1] try: nm = nmap.PortScanner() except nmap.PortScannerError: print('Nmap not found', sys.exc_info()[0]) sys.exit(0) except: print("Unexpected error:", sys.exc_info()[0]) sys.exit(0) try: nm.scan(hosts=hosts, arguments=' -v -sS -p '+port) except Exception as e: print("Scan erro:"+str(e)) for host in nm.all_hosts(): print("----------------------------------------------------------") print('Host : %s (%s)' % (host, nm[host].hostname())) print('State : %s' % nm[host].state()) for proto in nm[host].all_protocols(): print('-------------') print('Protocol : %s' % proto) lport = nm[host][proto].keys() for port in lport: print('port : %s\tstate : %s' % (port, nm[host][proto][port]['state']))
2.代码运行结果: