1. 程式人生 > >Python之——實現集中式的病毒掃描

Python之——實現集中式的病毒掃描

注意:這裡我們用的伺服器為CentOS 6.5 x64, 主機名為liuyazhuang121, IP為192.168.209.121

一、架構描述

本文實現了一個集中式的病毒掃描管理,可以針對不同的業務環境定製掃描策略,比如:掃描物件、描述模式、掃描路徑、排程頻率等。實現的架構如下圖,首先業務伺服器開啟clamd服務(監聽3310埠),管理伺服器啟用多執行緒對指定的服務叢集進行掃描,掃描模式、掃描路徑會傳遞到clamd,最後返回掃描結果給管理伺服器端。


二、具體實現

這裡我們通過ClamdNetworkSocket()方法實現與業務伺服器建立socket連線,再通過啟動不同的掃描方式實施病毒掃描並返回結果,實現的掃描指令碼scanner.py程式碼如下:

# -*- coding:UTF-8 -*-
'''
Created on 2018年1月6日

@author: liuyazhuang
'''
import time
import pyclamd
from threading import Thread

class Scan(Thread):
    def __init__(self, IP, scan_type, file):
        Thread.__init__(self)
        self.IP = IP
        self.scan_type = scan_type
        self.file = file
        self.connstr = ""
        self.scanresult = ""
        
    def run(self):
        """多程序run方法"""
        try:
            #建立網路套接字連線物件
            cd = pyclamd.ClamdNetworkSocket(self.IP, 3310)
            
            #測試連通性
            if cd.ping():
                self.connstr = self.IP + " connection [OK]"
                #過載clamd病毒特徵庫,建議更新病毒庫後做reload()操作
                cd.reload()
                #選擇不同的掃描模式
                if self.scan_type == "contscan_file":
                    self.scanresult = "{0}\n.".format(cd.contscan_file(self.file))
                elif self.scan_type == "multiscan_file":
                    self.scanresult = "{0}\n.".format(cd.multiscan_file(self.file))
                elif self.scan_type == "scan_file":
                    self.scanresult = "{0}\n.".format(cd.scan_file(self.file))
                #執行緒掛起1秒
                time.sleep(1)
            else:
                self.connstr = self.IP + " ping error, exit"
                return
        except Exception, e:
            self.connstr = self.IP + " " + str(e)

#掃描主機列表
IPs = ['192.168.209.121']
#指定掃描模式,支援contscan_file、multiscan_file、scan_file
scantype = "multiscan_file"
#指定掃描路徑
scanfile = "/data/www"
i = 1

#指定啟動執行緒數
threadnum = 2
#儲存掃描Scan類執行緒物件列表
scanlist = []

for ip in IPs:
    #建立掃描Scan類物件,引數(IP,掃描模式,掃描路徑)
    currp = Scan(ip, scantype, scanfile)
    #追加物件到列表
    scanlist.append(currp)
    
    #當達到指定的執行緒數或IP列表數後啟動、退出執行緒
    if i % threadnum == 0 or i == len(IPs):
        for task in scanlist:
            #啟動執行緒
            task.start()

        for stask in scanlist:
            #等待所有子執行緒退出,並輸出掃描結果
            task.join()
            #列印伺服器連線資訊
            print task.connstr
            #列印掃描結果
            print task.scanresult
        scanlist = []
        
    i+=1

三、初步掃描結果

此時,我們通過python scanner.py執行掃描程式,結果為未發現病毒程式。具體掃描結果如下:

[[email protected] chapter4]# python scanner.py
192.168.209.121 connection [OK]
None
.
[[email protected] chapter4]# 

四、生成帶病毒特徵的檔案

我們現在生成一個帶病毒特徵的檔案,這裡我們同樣利用Python的pyclamd生成病毒特徵的檔案,這裡我們新建一個Python指令碼create.py,具體程式碼如下:

# -*- coding:UTF-8 -*-
'''
Created on 2018年1月7日

@author: liuyazhuang
'''
import pyclamd
cd = pyclamd.ClamdNetworkSocket('192.168.209.121', 3310)
#通過EICAR()方法生成一個帶有病毒特徵的檔案/tmp/EICAR,編譯測試
void = open('/tmp/EICAR', 'w').write(cd.EICAR())
我們執行這個指令碼後會在/tmp目錄下生成一個EICAR病毒特徵檔案,如下:
[[email protected] chapter4]# python create.py 
[[email protected] chapter4]# cat /tmp/EICAR 
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
此時,我們將/tmp/EICAR檔案移動到/data/www目錄下。
 mv /tmp/EICAR /data/www

五、再次掃描結果

此時,我們再次執行掃描指令碼scanner.py,結果如下:

[[email protected] chapter4]# python scanner.py 
192.168.209.121 connection [OK]
{u'/data/www/EICAR': ('FOUND', 'Eicar-Test-Signature')}
.
[[email protected] chapter4]# 
這裡,發現一個病毒特徵檔案/data/www/EICAR。

六、執行刪除病毒檔案命令,再次掃描

這裡,我們執行命令

rm /data/www/EICAR
刪除病毒特徵檔案,然後再次執行掃描指令碼檔案,得出結果如下:
[[email protected] chapter4]# python scanner.py  
192.168.209.121 connection [OK]
None
.
[[email protected] chapter4]# 
此時,未發現任何病毒特徵檔案。
到此,我們實現的病毒掃描案例結束。