巡風掃描器--vulscan源碼分析

vulscan部分的目錄結構如下:
在這裏插入圖片描述
vulscan裏面包含的是掃描插件,有兩種類型一是python腳本型插件,一是json文件型插件;

vulscan代碼分析

1、程序開頭

sys.path.append(sys.path[0] + '/vuldb')
	sys.path.append(sys.path[0] + "/../")

將 vuldb 目錄和上級目錄加入系統路徑中;
2、找到程序入口

if __name__ == '__main__':
    # 插件初始化加載
    init()

init() 函數首先進行插件初始化加載,如果發現數據庫中已經存儲有插件數據,就不繼續執行了。

file_list = os.listdir(sys.path[0] + '/vuldb')
    for filename in file_list:
        try:
            if filename.split('.')[1] == 'py':
                script_plugin.append(filename.split('.')[0])
            if filename.split('.')[1] == 'json':
                json_plugin.append(filename)
        except:
            pass

插件信息如果沒有存儲到數據庫中,用 os.listdir() 函數列出插件目錄下的文件, 按文件名後綴對兩種類型插件分類。

os.listdir() 方法用於返回指定的文件夾包含的文件或文件夾的名字的列表。
語法:os.listdir(path)
    for plugin_name in script_plugin:
        try:
            res_tmp = __import__(plugin_name)
            plugin_info = res_tmp.get_plugin_info()
            plugin_info['add_time'] = time_
            plugin_info['filename'] = plugin_name
            plugin_info['count'] = 0
            na_plugin.insert(plugin_info)
        except:
            pass

對於 python 腳本插件,用 import (動態導入),然後統一調用插件中的 get_plugin_info() 方法,將插件詳細的描述信息存入數據庫;

    for plugin_name in json_plugin:
        try:
            json_text = open(sys.path[0] + '/vuldb/' + plugin_name, 'r').read()
            plugin_info = json.loads(json_text)
            plugin_info['add_time'] = time_
            plugin_info['filename'] = plugin_name
            plugin_info['count'] = 0
            # 刪除關於檢測部分的漏洞,然後也是隻將描述信息存入數據庫
            del plugin_info['plugin']
            na_plugin.insert(plugin_info)
        except:
            pass

對 json 文件型插件,用 json.loads() 函數加載文件內容;
3、初始化插件之後
將密碼字典、運行線程數、超時時間、ip地址白名單從數據庫中取出;

PASSWORD_DIC, THREAD_COUNT, TIMEOUT, WHITE_LIST = get_config()

接着開啓了一個監控線程--------監控是否加載任務,並及時更新密碼字典、運行線程數、超時時間、ip 地址白名單;

 python thread.start_new_thread(monitor, ())
def monitor():
    global PASSWORD_DIC, THREAD_COUNT, TIMEOUT, WHITE_LIST
    while True:
        queue_count = na_task.find({"status": 0, "plan": 0}).count()
        if queue_count:
            load = 1
        else:
            ac_count = thread._count()
            load = float(ac_count - 6) / THREAD_COUNT
        if load > 1:
            load = 1
        if load < 0:
            load = 0
        na_heart.update({"name": "load"}, {
                        "$set": {"value": load, "up_time": datetime.datetime.now()}})

這裏設置load值,表示當前有無插件被調用(1正被調用,0沒有調用)。
4、while True語句

   while True:
        # 取出計劃任務信息
        try:
            task_id, task_plan, task_target, task_plugin = queue_get()
            # 如過沒有任務,sleep後,回到上一行代碼
            if task_id == '':
                time.sleep(10)
                continue  # 否則進入下面的流程,準備掃描漏洞
       
 if PLUGIN_DB:
  del sys.modules[PLUGIN_DB.keys()[0]] 

清理插件緩存,sys.modules.key()儲存了已經加載的模塊,在調用是獲得其中的緩存,並沒有重新導入;

PLUGIN_DB.keys()[0]
sys.modules是一個全局字典,該字典是python啓動後就加載在內存中。每當程序員導入新的模塊,sys.modules都將記錄這些模塊。字典sys.modules對於加載模塊起到了緩衝的作用。當某個模塊第一次導入,字典sys.modules將自動記錄該模塊。當第二次再導入該模塊時,python會直接到字典中查找,從而加快了程序運行的速度。

5、接下來開始掃描部分

 for task_netloc in task_target:
                while True:
                    if int(thread._count()) < THREAD_COUNT:
                        # 跳過白名單ip
                        if task_netloc[0] in WHITE_LIST:
                            break
                        try:
                            thread.start_new_thread(
                                vulscan, (task_id, task_netloc, task_plugin))
                        except Exception as e:
                            print e
                        break

遍歷目標,一個目標開一個線程,但是隻有當前運行的總線程數(thread._count())小於設置的總線程數(THREAD_COUNT)時,纔會繼續開新的線程,避免目標過多,開的線程太多卡死;

 if int(thread._count()) < THREAD_COUNT:

然後檢測了ip地址是否爲白名單中的地址,如果不是纔會繼續進行下去;將任務id、ip地址和端口號、使用的插件傳入VulScan進行正式掃描。

 if task_netloc[0] in WHITE_LIST:
                            break
                        try:
                            thread.start_new_thread(
                                vulscan, (task_id, task_netloc, task_plugin))
                        except Exception as e:
                            print e
                        break
                    else:
                        time.sleep(2)

6、然後看類vulscan下面定義的每一個函數的功能:

class vulscan():
    # 數據初始化
    def __init__(self, task_id, task_netloc, task_plugin):...
    # 掃描流程
    def start(self):...
     # 根據插件名查詢插件信息
    def get_plugin_info(self):...
    # 讀取json插件信息
    def load_json_plugin(self):...
     # 數據結構轉換爲請求對象
    def set_request(self):...
     # 獲取網站頁面編碼方式
    def get_code(self, header, html):...
    #  json 文件型插件的漏洞檢測函數 poc_check()
    def poc_check(self):...
    #保存結果到數據庫
    def save_request(self):...
    #控制檯信息輸出
    def log(self, info):... 

然後對每個函數具體分析。

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