Python——实现集中式的病毒扫描&实现高效的端口扫描器
1、pyClamad模块安装方法
1 yum install clamav clamd clamav-update -y #安装clamavp相关程序包 2 chkconfig --levels 235 clamd on #添加扫描守护进场clamd系统服务 3 /usr/bin/freshclam #更新病毒库,建议配置到crontab中定期更新 4 setenforce 0 #关闭SELinux,避免远程扫描时提示无权限的问题 5 6 #更新守护进程监听IP配置文件,根据不同环境自行修改监听的IP,'0.0.0.0'为监听所有主机IP 7 sed -i -e '/^TCPAddr/{ s/127.0.0.1/0.0.0.0/; }' /etc/clamd.conf 8 /etc/init.d/clamd start #启动扫描守护进程 9 10 #主控端部署pyClamad环境 11 wget https://pypi.python.org/packages/13/73/97a0518b59f1b6aefa2ac851566038d2c9128f8a5503bcf4cd0adf8b0072/pyClamd-0.4.0.tar.gz 12 tar -xf pyClamd-0.4.0.tar.gz 13 cd pyClamd-0.4.0 14 python setup.py install
实践:实现集中病毒扫描
本文实现了一个集中式的病毒扫描管理,可以针对不同的业务环境定制扫描策略,比如:扫描对象、描述模式、扫描路径、调度频率等。实现的架构如下图,首先业务服务器打开clamd服务(监听3310端口),管理服务器启用多线程对指定的服务集群进行扫描,扫描模式、扫描路径会传递到clamd,最后返回扫描结果给管理服务器端。
1 #!/usr/bin/env python 2 #coding=utf-8 3 4 import time 5 import pyclamd 6 from threading import Thread 7 8 class Scan(Thread): 9 def __init__(self, IP, scan_type, file): 10 Thread.__init__(self) 11 self.IP = IP 12 self.scan_type = scan_type 13 self.file = file 14 self.connstr = "" 15 self.scanresult = "" 16 17 def run(self): 18 """多进程run方法""" 19 try: 20 #创建网络套接字连接对象 21 cd = pyclamd.ClamdNetworkSocket(self.IP, 3310) 22 23 #测试连通性 24 if cd.ping(): 25 self.connstr = self.IP + " connection [OK]" 26 #重载clamd病毒特征库,建议更新病毒库后做reload()操作 27 cd.reload() 28 #选择不同的扫描模式 29 if self.scan_type == "contscan_file": 30 self.scanresult = "{0}\n.".format(cd.contscan_file(self.file)) 31 elif self.scan_type == "multiscan_file": 32 self.scanresult = "{0}\n.".format(cd.multiscan_file(self.file)) 33 elif self.scan_type == "scan_file": 34 self.scanresult = "{0}\n.".format(cd.scan_file(self.file)) 35 #线程挂起1秒 36 time.sleep(1) 37 else: 38 self.connstr = self.IP + " ping error, exit" 39 return 40 except Exception, e: 41 self.connstr = self.IP + " " + str(e) 42 43 #扫描主机列表 44 IPs = ['192.168.209.121'] 45 #指定扫描模式,支持contscan_file、multiscan_file、scan_file 46 scantype = "multiscan_file" 47 #指定扫描路径 48 scanfile = "/data/www" 49 i = 1 50 51 #指定启动线程数 52 threadnum = 2 53 #存储扫描Scan类线程对象列表 54 scanlist = [] 55 56 for ip in IPs: 57 #创建扫描Scan类对象,参数(IP,扫描模式,扫描路径) 58 currp = Scan(ip, scantype, scanfile) 59 #追加对象到列表 60 scanlist.append(currp) 61 62 #当达到指定的线程数或IP列表数后启动、退出线程 63 if i % threadnum == 0 or i == len(IPs): 64 for task in scanlist: 65 #启动线程 66 task.start() 67 68 for stask in scanlist: 69 #等待所有子线程退出,并输出扫描结果 70 task.join() 71 #打印服务器连接信息 72 print task.connstr 73 #打印扫描结果 74 print task.scanresult 75 scanlist = [] 76 77 i+=1
2、python-nmap模块的安装方法
1 yum install nmap -y #安装nmap工具 2 3 #模块源码安装 4 wget http://xael.org/pages/python-nmap-0.6.1.tar.gz 5 tar -xf python-nmap-0.6.1.tar.gz 6 cd python-nmap-0.6.1 7 python setup.py install
通过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/env python 2 #coding=utf-8 3 4 5 import sys 6 import nmap 7 8 scan_row = [] 9 input_data = raw_input('Please input hosts and port: ') 10 #以空格分隔 11 scan_row = input_data.split(' ') 12 13 if len(scan_row) != 2: 14 print "Input errors, example \"192.168.209.0/24 80,443,22 \"" 15 sys.exit(0) 16 17 #接收用户输入的主机 18 hosts = scan_row[0] 19 #接收用户收入的端口 20 port = scan_row[1] 21 22 try: 23 #创建端口扫描对象 24 nm = nmap.PortScanner() 25 except nmap.PortScannerError: 26 print 'Nmap not found', sys.exc_info()[0] 27 sys.exit(0) 28 except Exception, e: 29 print "Unexpected error:", sys.exc_info()[0] 30 print str(e) 31 sys.exit(0) 32 33 try: 34 #调用扫描方法,参数指定扫描主机hosts,nmap扫描命令行参数arguments 35 nm.scan(hosts=hosts, arguments=' -v -sS -p ' + port) 36 except Exception, e: 37 print "Scan error:" + str(e) 38 39 for host in nm.all_hosts(): #遍历扫描主机 40 print '---------------------------------------------------------------------' 41 #输出主机及主机名 42 print 'Host : %s (%s)' % (host, nm[host].hostname()) 43 #输出主机状态,如up、down 44 print 'State : %s' % nm[host].state() 45 #遍历扫描协议,tcp、udp 46 for proto in nm[host].all_protocols(): 47 print '--------------' 48 #输出协议名 49 print 'Protocol : %s' % proto 50 51 #获取协议的所有扫描端口 52 lport = nm[host][proto].keys() 53 #端口列表排序 54 lport.sort() 55 #遍历端口输出端口与状态 56 for port in lport: 57 print 'port %s\tstate : %s' % (port, nm[host][proto][port]['state'])