優化中...php
#! /usr/bin/env python # -*- coding:utf-8 -*- # Author: Tdcqma ''' 獲取漏洞目標站點:綠盟安全漏洞通告 v1.0: 因爲網站結構存在變動的可能性,一旦爬蟲爬取的頁面發生變化則會影響正則表達式的匹配,致使爬蟲失效。爲了解決這個問題從新架構該爬蟲,新的爬蟲將分3個部分,即: 【1】信息收集:一旦網站結構發生變化只須要更改此部分的正則表達式便可,收集的信息須要保存至一個嵌套列表中。 【2】信息篩選:即便網站結構發生變化也不須要變動此部分。 【3】信息發送:即便網站結構發生變化也不須要變動此部分。 v1.1 添加 "風險級別" 功能到報警信息中,由【CVE 通用漏洞與披露】庫中獲取對應漏洞的風險級別 v1.2 添加漏洞總數功能 v1.3 刪除"風險級別"選項,由於http://cve.scap.org.cn/站點故障 優化代碼 v1.4 使用BeautifulSoup模塊優化內容搜索 v1.5 優化模塊2(信息篩選),對信息進行按系統分類顯示 v1.6 優化v1.5部分,對代碼部分進行函數化整理 ''' import urllib.request import ssl,re import smtplib,email import datetime from bs4 import BeautifulSoup # --------------------------------------------- # 【1】信息收集,正則表達匹配網站信息,包括date、title、url等, # 將全部信息保存至sec_all_list列表中 # --------------------------------------------- f = open("secInfo-lvmeng.txt", 'w', encoding='utf-8') # 爬蟲爬取當天的漏洞告警信息,也可指定如2017-10-09樣式的日期格式用於開發過程當中的測試 #today = str(datetime.date.today()) today = "2017-09-28" # 指定爬蟲網站的首頁連接 sec_vul_domain = "http://www.nsfocus.net/" # 生成字典用於保存漏洞網站的跳轉連接 vul_dict = {} # 該變量保存漏洞跳轉頁面連接:http://www.nsfocus.net/index.php?act=sec_bug sec_vul_homepage = "" # 收集全部漏洞信息並保存在列表中 sec_all_list = [] # 將列表漏洞轉換爲字符串 data_str = "" # 將須要監控的系統名稱添加至該列表便可實現爬蟲功能 system_list = ["Apache","Cisco","Samba","Dnsmasq","Microsoft"] # 該變量保存全部指定系統的格式化後的漏洞信息,郵件發送也是基於該變量裏保存的漏洞信息 all_vul_msg = "" # 計算漏洞總數 count = 0 # 傳入不一樣的page連接以獲取相應response def get_response(vul_url): request = urllib.request.Request(vul_url) # 當嘗試訪問https開始當站點時,設置全局取消SSL證書驗證 ssl._create_default_https_context = ssl._create_unverified_context response = urllib.request.urlopen(request) data = response.read().decode('utf-8') return data data_homepage = get_response(sec_vul_domain) soup = BeautifulSoup(data_homepage, features="lxml") tag1 = soup.find_all(name='a') for item in tag1: if "安全漏洞" in item: # 經過獲取標籤屬性,即便站點結構發生變化也能拿到漏洞頁面的連接 attrs = item.attrs vul_dict = attrs.copy() sec_vul_homepage = vul_dict.get('href') # 同一天的爆出的漏洞個數可能要佔用好幾個頁面,需指定被掃描網站須要掃描的網頁數範圍,默認讀取10頁 for i in range(10): sec_vul_pageNoUrl = sec_vul_homepage +"&type_id=&os=&keyword=&page=%s" % (i+1) data_sec_vul = get_response(sec_vul_pageNoUrl) if today in data_sec_vul: str_re = "<span>"+today+"</span>.*" res = re.findall(str_re,data_sec_vul) for item in res: data_str += item + '\n' sec_vul_soup = BeautifulSoup(data_str, features="lxml") tag_a = sec_vul_soup.find_all(name='a') for item in tag_a: # 生成列表用於收集單獨的漏洞信息 sec_sub_list = [] # 收集漏洞標題: title sec_sub_title = item.string sec_sub_list.append(sec_sub_title) # 收集漏洞url: sec_sub_url item = str(item) sub_url = re.findall("vulndb/\d+",item) sec_sub_url = sec_vul_domain + sub_url[0] sec_sub_list.append(sec_sub_url) # 收集漏洞受影響的版本: aff_ver data_sec_vul_cve = get_response(sec_sub_url) affected_version = re.findall("<blockquote>.*</blockquote>", data_sec_vul_cve, re.S) affected_version = str(affected_version[0][12:-13]) affected_version = affected_version.replace("<br />", "") affected_version = affected_version.replace(">",">") affected_version = affected_version.replace("<","<") aff_ver = affected_version.replace("</blockquote><b>不受影響系統:</b><blockquote>","\n不受影響版本:\n") sec_sub_list.append(aff_ver) if sec_sub_list not in sec_all_list: sec_all_list.append(sec_sub_list) # --------------------------------------------- # 【2】信息篩選 # --------------------------------------------- # 各系統漏洞在篩選後最終會保存至各自msg_***變量中, # >>>添加新監控系統時需相應添加如下記錄<<< msg_cisco = ">>> CISCO安全通告\n" msg_apache = "\n>>> APACHE安全通告\n" # 調用sub_sec_info方法,將漏洞信息格式化輸出 def sub_sec_info(): global count count += 1 sec_info = "\n漏洞名稱:" + line[0] \ + "\n漏洞連接:" + line[1] \ + "\n受影響的系統:\n" + line[2] + '\n' return sec_info # 調用get_sec_info函數,將目標系統或應用名稱做爲參數傳入,便可獲取相關爬蟲告警信息 def get_sec_info(vul): vul = vul.capitalize() global msg_cisco global msg_apache # >>>添加新監控系統時需相應添加如下elif記錄<<< if vul in line[0]: if "Cisco" in vul: msg_cisco += sub_sec_info() elif "Apache" in vul: msg_apache += sub_sec_info() # 漏洞信息篩選入口函數 for line in sec_all_list: for sys in system_list: get_sec_info(sys) # >>>添加新監控系統時需相應添加如下記錄<<< all_vul_msg += msg_cisco all_vul_msg += msg_apache all_vul_msg += "\n漏洞總數:【"+str(count)+"】 " # 爲放置數據丟失,同時將篩選後的爬蟲信息寫入文本f中,f指向secInfo-lvmeng.txt文檔。 f.writelines(all_vul_msg) #print(msg) # --------------------------------------------- # 【3】信息發送 # --------------------------------------------- # 配製收發郵件客戶端 chst = email.charset.Charset(input_charset = 'utf-8') header = ("From: %s\nTo: %s\nSubject: %s\n\n" % ("from_mail@163.com", "to_mail@163.com", chst.header_encode("[爬蟲安全通告-綠盟]"))) #借用163smtp服務器發送郵件,將上面讀到的報警信息(all_vul_msg)做爲郵件正文發送。 email_con = header.encode('utf-8') + all_vul_msg.encode('utf-8') smtp = smtplib.SMTP("smtp.163.com") smtp.login("from_mail@163.com","from_mail_pass") smtp.sendmail('from_mail@163.com','to_mail@163.com',email_con) print('mail send success!') smtp.quit()
郵件截圖:python