前幾天在先知上看到偽全棧式安全研發:CVE監控這篇文章,就想着也實現一下代碼進行最新CVE的監控。語言采用了Python,數據庫也為Mongodb數據庫。代碼和實現的什么不重要,重要的是過程。
主要包括以下幾個方面。
- 獲取最新的CVE列表和詳情
主要采用了python的requests模塊和BeautifulSoup模塊。 - 將最新的CVE信息存入數據庫
數據庫使用了Mongodb,采用了pymongo模塊。 - 通過郵件發送最新的CVE信息
發送郵件采用了smtplib模塊。 - 定時執行任務
使用了linux的crontab來實現。
0x02 實現過程
1. 獲取最新的CVE列表和詳情
訪問https://cassandra.cerias.purdue.edu/CVE_changes/today.html ,可以獲取每天新增的CVE信息。
通過查看源代碼,發現沒html沒什么規律可言,都是些超鏈接。要想獲取最新的列表,可以通過取文本中間的方法來獲取。
這里需要獲取New entries:
和Graduations
之間的內容。然后通過BeautifulSoup來解析其中的超鏈接。
主要代碼如下:
def getCVES():# 獲取最新到CVE列表 |
獲取文本中間內容的代碼:
def getMiddleStr(content, startStr, endStr): # 獲取文本中間內容 |
運行效果:
超鏈接的地址是CVE的詳情。隨便進入一個查看效果。
例如:http://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-0874
這里需要記錄的信息有:CVE-ID、Description、Assigning CNA和Date Entry Created。
通過查看網頁源碼發現,所有需要記錄的信息在一個表格里面。但該頁面有很多table,而且沒有明顯的標識來區分。而該table在div中,可以通過id來獲取。
CVE-ID可以直接通過soup.find(nowrap='nowrap').find('h2').string
獲取。其他的幾個信息可以通過獲取相應tr中的td中的內容獲得。
這樣就可以獲取最新的CVE列表和詳情。
2. 將最新的CVE信息存入數據庫
數據庫采用了Mongodb。安裝方法apt-get install mongodb
然后啟動數據庫
mkdir /var/data/ #創建數據存儲位置 |
Mongodb數據庫插入一條數據,一般使用的是insert。
db.test.insert({"title":"test1", "blog_cont":"test1"}) |
如果我們想實現一個如果title存在,就對數據進行更新,不存在,就插入。可以這樣來實現。
db.test.update({"title":"test2"}, {$set:{"title":"test2", "blog_cont":"test2"}}, {upsert:true}) |
執行完成后最終有兩條數據,title分別為test1和test2,對應的內容為test3和test2.
因此在插入數據的時候,我們可以直接使用db.test.update({"title":"test2"}, {$set:{"title":"test2", "blog_cont":"test2"}}, {upsert:true})
這種方式來實現。
更新只需更改data內容即可。
為了數據庫的安全性,使用
--bind_ip 127.0.0.1
來設置數據庫僅本地可以連接。更多mongodb數據庫的配置可以參考MongoDB Mongodb.conf 配置 Auth。
3. 通過郵件發送最新的CVE信息
發送郵件這里用到了smtplib。
發送郵件比較簡單,就直接貼代碼了。
def sendEmail(mail_msg): # 發送郵件 |
4. 定時執行任務
直接使用linux下的crontab來完成。
例如設置每天早上7點執行,可以這樣設置:
0 7 * * * python /myJob/CVE-Monitor.py >> /log/CVE-Monitor.log |
根據https://cassandra.cerias.purdue.edu/CVE_changes/ 看到today.html更新的時間是明天的06:53,對應北京時間是19:53。若想及時獲取,可以更換時間為20:00.
5.完善和優化
到這里監控腳本完成的差不多了,剩下就是如何來融合一起並改善了。
為了方便發送郵件內容和插入數據庫,我們新建類CVEInfo。主要代碼如下:
class CVEInfo: |
為了美觀,將郵件以html方式發送
message = MIMEText(mail_msg, 'html', 'utf-8') |
郵箱收到的效果:
查看數據庫數據:
從上面兩張圖片可以看到有三十多個,但我們有時候並不是都需要看。我們可以根據Description中關鍵信息來進行過濾,僅僅將我們需要關注的CVE信息發送到郵箱或進行入庫操作。
如下圖為獲取CVE-2017-8295的信息。
然后修改main方法,根據是否有關注的CVE信息來決定郵件的內容。
這里先用本地服務器為例,新建today.html文件,其中包含CVE-2017-9805和CVE-2017-16241。
運行代碼結果打印了一條包含了我們的關鍵字的數據。
郵件中的內容如下所示:
這樣就能過濾其他CVE信息,僅僅記錄我們關注的內容了。
0x03 總結
本文主要用到了BeautifulSoup解析網頁和mongodb數據庫的使用,然后就可以將想要的內容保存到數據庫中。腳本並不限於在此處使用,也可以修改一下抓取其他網站內容。
代碼地址:https://github.com/fupinglee/MyPython/blob/master/work/CVE-Monitor.py
查詢的功能就不做了,若想實現其他功能,可以自行增加和修改。
0x03 參考
[1]https://xianzhi.aliyun.com/forum/topic/1694/
[2]http://blog.csdn.net/guoxingege/article/details/47339885