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):...
然後對每個函數具體分析。