馮寶龍 高飛
摘要:網(wǎng)絡(luò)信息安全工作中,網(wǎng)站監(jiān)測通常注重兩個方面:網(wǎng)站是否可以正常訪問和網(wǎng)站是否被篡改。系統(tǒng)通過爬蟲和自動化測試技術(shù)獲取關(guān)鍵文本內(nèi)容及頁面截圖,并分別進行分析,利用Python語言實現(xiàn)了基于多模態(tài)的網(wǎng)站動態(tài)監(jiān)測,在實際工作中取得了一定的效果。
關(guān)鍵詞:信息安全;多模態(tài);網(wǎng)站監(jiān)測;爬蟲;Python
中圖分類號:TP311 ? ? ?文獻標識碼:A
文章編號:1009-3044(2022)13-0028-03
1 開發(fā)背景
當前,高校中越來越多的業(yè)務(wù)網(wǎng)站上線運行。同時,傳統(tǒng)的學校主站及各院系部處的網(wǎng)站,在對外宣傳、展示學校形象等方面也起到越來越重要的作用[1]。
與此同時,高校網(wǎng)站業(yè)務(wù)系統(tǒng)由于其特殊性也成為黑客攻擊的重要目標之一,因此如何能夠自動化地監(jiān)測不斷增加的網(wǎng)站業(yè)務(wù)系統(tǒng)的運行狀態(tài)及其內(nèi)容安全,成為高校網(wǎng)絡(luò)信息安全維護工作中迫切需要解決的問題。
針對以上問題,筆者結(jié)合實際工作需要,設(shè)計并實現(xiàn)了一個基于關(guān)鍵文本內(nèi)容對比和頁面截圖對比的多模態(tài)網(wǎng)站動態(tài)監(jiān)測系統(tǒng)。
2 總體設(shè)計
系統(tǒng)首先讀取需要監(jiān)測的網(wǎng)站、業(yè)務(wù)系統(tǒng)(以下簡稱網(wǎng)站)的地址。獲取網(wǎng)站地址信息后,對網(wǎng)站的可訪問性進行判斷,若網(wǎng)站無法訪問,發(fā)送告警信息到指定郵箱。若網(wǎng)站可以訪問,繼續(xù)獲取網(wǎng)站頁面的關(guān)鍵文本內(nèi)容信息,與上一次獲取的關(guān)鍵文本內(nèi)容信息進行比對,若發(fā)現(xiàn)變化,發(fā)送告警郵件到指定郵箱。關(guān)鍵文本內(nèi)容信息比對完畢,再對當前訪問地址頁面進行截圖,同時與上一次獲取的截圖進行比對,若發(fā)現(xiàn)變化,將截圖中變化的部分標注后,發(fā)送告警郵件到指定郵箱。
系統(tǒng)可根據(jù)用戶設(shè)定的時間間隔,重復上面的業(yè)務(wù)流程,實現(xiàn)對網(wǎng)站頁面的自動化監(jiān)測告警。
3 關(guān)鍵功能實現(xiàn)
3.1 網(wǎng)站地址的獲取
網(wǎng)站地址管理可以通過兩種方式:1)通過MySQL數(shù)據(jù)庫;2)通過CSV格式文件。
MySQL數(shù)據(jù)庫是主流的關(guān)系型數(shù)據(jù)庫,其社區(qū)版開源免費具有體積小、速度快、總體擁有成本低的特點,是中小企業(yè)和網(wǎng)站的首選[2]。通過MySQL數(shù)據(jù)庫管理數(shù)據(jù)不僅可以滿足當前功能需求,也可以滿足后期其他擴展功能的實現(xiàn)。數(shù)據(jù)庫共一張表,用來存儲網(wǎng)站地址和備注信息。
Python連接MySQL數(shù)據(jù)庫需要安裝PyMySQL包進行驅(qū)動,再通過Pandas包進行具體的讀取操作。PyMySQL是實現(xiàn)Python訪問MySQL數(shù)據(jù)庫的一個最方便快捷的方法[3],Pandas是一個用于數(shù)據(jù)分析的開源Python庫,提供了數(shù)據(jù)快速加載、操作、合并等功能[4]。系統(tǒng)將相關(guān)函數(shù)進行了二次封裝,封裝后的函數(shù)代碼如下:
def data_fromsql(strsql,dbname,host,user,passwd):
conn = pymysql.connect(host=host, user=user, passwd=passwd, db=dbname)
strsql = strsql
df = pd.read_sql(strsql, conn)
conn.close()
return df
函數(shù)調(diào)用時需要對相應的參數(shù)變量進行賦值:strsql對應執(zhí)行查詢的sql語句;dbname對應要訪問的數(shù)據(jù)庫名字;host對應數(shù)據(jù)庫所在服務(wù)器地址;user對應訪問數(shù)據(jù)庫的用戶名;passwd對應訪問數(shù)據(jù)庫用戶的密碼,函數(shù)執(zhí)行成功返回DataFrame類型數(shù)據(jù)。
CSV格式文件是逗號分隔值格式文件,它是一種通用的、相對簡單的文件格式,被廣泛應用,該格式文件以純文本形式存儲表格數(shù)據(jù),每行一條記錄,每條記錄用分隔符分割字段。一般以逗號作為分隔符,首行為字段標題。用CSV格式文件管理網(wǎng)站地址既滿足了當前功能需求,也免去了安裝MySQL數(shù)據(jù)庫,方便不熟悉數(shù)據(jù)庫的用戶使用。
CSV文件數(shù)據(jù)的讀取如下,同樣獲得DataFrame類型數(shù)據(jù)。
df = pd.read_csv(fname)
3.2 網(wǎng)站是否可以訪問的判斷
客戶端向服務(wù)器端發(fā)送HTTP請求后,服務(wù)器端會返回HTTP響應報文,其中狀態(tài)行部分包含狀態(tài)碼,當狀態(tài)碼返回值是200的時候,說明HTTP請求成功,網(wǎng)站可以正常訪問,否則說明網(wǎng)站無法正常訪問。核心代碼如下:
r=requests.get(webindex,timeout=2) #webindex為需要監(jiān)測的網(wǎng)站地址
res_str = str(r.status_code) ? ? ? #res_str為返回的狀態(tài)碼
3.3 關(guān)鍵文本內(nèi)容信息的獲取與對比
對于網(wǎng)站文本內(nèi)容的惡意篡改一般包括添加js腳本、修改a鏈接地址及內(nèi)容、添加隱藏iframe、修改添加圖片地址、修改meta和title相關(guān)信息。網(wǎng)絡(luò)爬蟲技術(shù)的發(fā)展,為獲取網(wǎng)站中這些特定字段信息提供了技術(shù)支撐[5]。系統(tǒng)通過網(wǎng)絡(luò)爬蟲程序自動提取網(wǎng)站中關(guān)鍵文本內(nèi)容信息進行持久化保存,每次保存后與前一次保存的數(shù)據(jù)做差集運算進行對比,發(fā)現(xiàn)新增內(nèi)容就發(fā)送告警郵件,每次比對完成刪除前一次保存的數(shù)據(jù)。核心代碼如下:
#獲取html數(shù)據(jù):
html = BeautifulSoup(web_txt, "html.parser")
#從html數(shù)據(jù)獲取title
title_set = set()
for x in html.find_all('title'):
title_one = x.get_text()
title_set.add(title_one)
#從html數(shù)據(jù)獲取meta中的content:
meta_set = set()
for x in html.find_all('meta'):
meta_one = x.get("content")
meta_set.add(meta_one)
#從html數(shù)據(jù)獲取a標簽內(nèi)容以及a標簽中href數(shù)據(jù)
atxt_set = set()
alink_set = set()
for x in html.find_all('a'):
atxt_one_set=set(x.get_text().replace(" ","").split("\n"))
atxt_set=atxt_set | atxt_one_set
alink_one = x.get("href")
alink_set.add(alink_one)
#關(guān)鍵文本內(nèi)容信息的持久化保存:
joblib.dump(content,f_name) ? ?#數(shù)據(jù)的保存
t_start = joblib.load(f_start) #數(shù)據(jù)的讀取
#關(guān)鍵文本內(nèi)容信息差集運算:
t_diff= t_end-t_start
3.4 網(wǎng)站頁面截圖與相似度計算
另外一種常見的惡意篡改是對原站正常顯示的圖片進行修改,添加惡意文字后上傳替換原圖片,這種惡意篡改通常影響惡劣,修改方式隱秘,不能通過前面關(guān)鍵文本內(nèi)容信息的比對發(fā)現(xiàn),而圖像對比技術(shù)恰恰可以解決這一問題。系統(tǒng)通過Python調(diào)用selenium自動化測試框架,對整個頁面進行截圖保存,然后通過圖像對比技術(shù)計算前后兩次頁面截圖的結(jié)構(gòu)相似性度[6],當計算的結(jié)果低于設(shè)定的閾值時,說明圖像有了較大的變化,立即發(fā)送告警郵件到指定郵箱。核心代碼如下:
#頁面截圖相關(guān)
#chrome相關(guān)設(shè)置
chromedriver = r"driver/chromedriver"
os.environ["webdriver.chrome.driver"] = chromedriver
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('disable-dev-shm-usage')
chrome_options.add_argument('lang=zh_CN.UTF-8')
chrome_options.add_argument('Accept-Language=zh-CN,zh;q=0.9,en;q=0.8')
driver = webdriver.Chrome(chromedriver, chrome_options=chrome_options)
#訪問頁面
driver.get(url)
#設(shè)置截圖寬高
width = driver.execute_script("return document.documentElement.scrollWidth")
height = driver.execute_script("return document.documentElement.scrollHeight")
driver.set_window_size(width, height)
#截圖保存
driver.save_screenshot('pic/' + f_name)
#圖像比較相關(guān)
#將圖像灰度化處理后計算結(jié)構(gòu)相似度:
grayA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)
(diff_score, diff) = compare_ssim(grayA, grayB, full=True)
#根據(jù)圖像變化,在新的截圖上框出圖像變化的位置:
diff = (diff * 255).astype("uint8")
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for c in cnts:
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(imgB, (x, y), (x + w, y + h), (0, 0, 255), 2)
3.5 告警郵件的創(chuàng)建與發(fā)送
當今主流的郵件系統(tǒng)都已經(jīng)通過綁定微信或者安裝單獨的客戶端等方式,實現(xiàn)了在郵箱收到郵件時,第一時間通知用戶有新郵件到達的功能。系統(tǒng)通過向指定郵箱發(fā)送告警郵件,幫助用戶實時監(jiān)測網(wǎng)站,使用戶在系統(tǒng)發(fā)現(xiàn)網(wǎng)站出現(xiàn)問題并發(fā)送告警信郵件后,能夠及時收到告警郵件到達信息。對于網(wǎng)站無法正常訪問、關(guān)鍵文本內(nèi)容變化系統(tǒng)發(fā)送的郵件僅包含文字信息,而對于截圖比對后的告警信息系統(tǒng)會附帶變化后的標注圖片作為附件發(fā)送告警郵件。告警郵件的發(fā)送通過Python提供的smtplib模塊[7]實現(xiàn),而告警郵件的創(chuàng)建需要通過Python提供的email模塊[8]實現(xiàn),創(chuàng)建及發(fā)送帶附件的告警郵件核心代碼如下:
#郵件創(chuàng)建
email = set_email()#提前設(shè)置好的郵件基礎(chǔ)信息包括收件人,主題,發(fā)件人郵箱、密碼,發(fā)送服務(wù)器等信息。
message = MIMEMultipart()#定義帶附件的郵件
message.attach(MIMEText(email['to_mail_content'], 'plain', 'utf-8'))
attachment = MIMEApplication(open(fattach_path, 'rb').read())#讀取附件文件
attachment.add_header('Content-Disposition', 'attachment',filename=fattach_path.split("/")[-1])
message.attach(attachment)
#發(fā)送郵件
smtpObj = smtplib.SMTP_SSL(from_mail_host,465)
smtpObj.login(from_mail_user,from_mail_pass) smtpObj.sendmail(from_mail_user,email['to_mail_user'],message.as_string())
4 系統(tǒng)運行效果
系統(tǒng)在東北農(nóng)業(yè)大學實際環(huán)境中測試運行正常,發(fā)現(xiàn)無法正常訪問網(wǎng)站若干,可以收到告警郵件,達到網(wǎng)站監(jiān)測的目的?;诎踩紤],以下運行效果截圖均針對測試站點用于演示。
5 結(jié)束語
系統(tǒng)使用Python3.6進行開發(fā),實現(xiàn)了對網(wǎng)站基于文本和圖像多模態(tài)進行動態(tài)監(jiān)測的目標,易于部署,在實際應用中取得了一定的效果,具有一定的研究及推廣價值。然而,系統(tǒng)也存在一定的不足,如發(fā)現(xiàn)網(wǎng)站內(nèi)容變化后,如何進一步分析變化的內(nèi)容將是系統(tǒng)下一步改進的方向。
參考文獻:
[1] 夏中林.校園網(wǎng)網(wǎng)站監(jiān)測系統(tǒng)的設(shè)計與實現(xiàn)[J].電腦知識與技術(shù),2012,8(8):1842-1843,1856.
[2] 王飛飛,崔洋,賀亞茹.MySQL數(shù)據(jù)庫應用從入門到精通[M].2版.北京:中國鐵道出版社,2014.
[3] 李曉雨.利用python實現(xiàn)對存儲在Mysql數(shù)據(jù)庫的日志文件的分析和保存[J].科學技術(shù)創(chuàng)新,2021(29):94-96.
[4] 丹尼爾·陳.Python數(shù)據(jù)分析:活用Pandas庫[M].武傳海,譯.北京:人民郵電出版社,2020.
[5] 江穎碩.關(guān)鍵目標網(wǎng)絡(luò)信息自動獲取技術(shù)研究[D].哈爾濱:哈爾濱工業(yè)大學,2021.
[6] 苗力元,李啟明,劉雅東,等.圖像比對技術(shù)在軟件自動化測試中的應用探究[J].信息通信技術(shù)與政策,2019(11):79-84.
[7] 于長宇.基于Python實現(xiàn)的高校教務(wù)工作效能提升——以自動化群發(fā)郵件程序設(shè)計為例[J].科技創(chuàng)新與應用,2021,11(28):194-196.
[8] 黃美瓊.基于Python定時批量發(fā)送郵件的實現(xiàn)[J].電腦編程技巧與維護,2022(1):51-52.
【通聯(lián)編輯:謝媛媛】