馮寶龍 高飛



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