基於大數據和機器學習的Web異常參數檢測系統Demo實現
*本文原創作者:foxscheduler,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載
前 言
如何在網路安全領域利用數據科學解決安全問題一直是一個火熱的話題,討論演算法和實現的文章也不少。前段時間看到楚安的文章
《數據科學在Web威脅感知中的應用》,其中提到如何用隱馬爾可夫模型(HMM)建立web
參數模型,檢測注入類的web攻擊。獲益匪淺,遂嘗試用python實現該演算法,並嘗試在大數據環境下的部署應用。
演算法一般過程
隱馬爾可夫模型是一個統計模型,可以利用這個模型解決三類基本問題:
學習問題:給定觀察序列,學習出模型參數
評估問題:已知模型參數,評估出觀察序列出現在這個模型下的概率
解碼問題:已知模型參數和給出的觀察序列,求出可能性最大的隱藏狀態序列
這裡我們是要解決前兩類問題,使用白樣本數據學習出模型和參數基線,計算檢測數據在該模型下出現的可能性,如果得分低於基線就可以認為這個參數異常,產出告警。演算法可分為訓練過程和檢測過程,演算法本身我這裡不在細說,這裡重點講一下參數的抽取和泛化。
參數的抽取
對http請求數據進行拆解,提取如下參數,這部分的難點在於如何正確的識別編碼方式並解碼:
GET、POST、Cookie請求參數
GET、POST、Cookie參數名本身
請求的URL路徑
http請求頭,如Content_type、Content-Length(對應strust2-045)
參數泛化
需要將參數值泛化為規律性的觀測經驗,並取字元的unicode數值作為觀察序列,泛化的方法如下:
大小寫英文字母泛化為」A」,對應的unicode數值為65
數字泛化為」N」,對應的unicode數值為78
中文或中文字元泛化為「C」,對應的unicode數值為67
特殊字元和其他字符集的編碼不作泛化,直接取unicode數值
參數值為空的取0
系統架構
在訓練過程中要使用儘可能多的歷史數據進行訓練,這顯然是一個批(batch)計算過程;在檢測過程中我們希望能夠實時的檢測數據,及時的發現攻擊,這是一個流(streaming)計算過程。典型的批+流式框架如Cisco的Opensoc使用開源大數據架構,kafka作為消息匯流排,Storm進行實時計算,Hadoop存儲數據和批量計算。但是這樣的架構有一個缺點,我們需要維護Storm和MapReduce兩套不同的代碼。考慮到學習成本,使用Spark作為統一的數據處理引擎,即可以實現批處理,也可以使用spark streaming實現近實時的計算。
系統架構如上圖,需要在spark上運行三個任務,sparkstreaming將kafka中的數據實時的存入hdfs;訓練演算法定期載入批量數據進行模型訓練,並將模型參數保存到Hdfs;檢測演算法載入模型,檢測實時數據,並將告警保存到ES。
Spark簡介
Apache Spark是一個快速通用的大數據計算框架,由Scala語言實現,同時提供Java、python、R語言的API介面。相比於Hadoop的Mapreduce,Spark可以實現在內存中計算,具有更高的計算速度,並且spark streaming提供流數據計算框架,以類似批處理的方式處理流數據。
RDD
RDD是Spark中抽象的數據結構類型,是一個彈性分布式數據集,數據在Spark中被表示為RDD。RDD提供豐富的API介面,實現對數據的操作,如map、flatmap、reduce、filter、groupby等等。
DStream
DStream(離散數據流)是Spark Streaming中的數據結構類型,它是由特定時間間隔內的數據RDD構成,可以實現與RDD的互操作,Dstream也提供與RDD類似的API介面。
DataFrame
DataFrame是spark中結構化的數據集,類似於資料庫的表,可以理解為內存中的分布式表,提供了豐富的類SQL操作介面。
數據採集與存儲
獲取http請求數據通常有兩種方式,第一種從web應用中採集日誌,使用logstash從日誌文件中提取日誌並泛化,寫入Kafka(
可參見兜哥文章);第二種可以從網路流量中抓包提取http信息。我這裡使用第二種,用python結合Tcpflow採集http數據,在數據量不大的情況下可穩定運行。
數據採集
與Tcpdump以包單位保存數據不同,Tcpflow是以流為單位保存數據內容,分析http數據使用tcpflow會更便捷。Tcpflow在linux下可以監控網卡流量,將tcp流保存到文件中,因此可以用python的pyinotify模塊監控流文件,當流文件寫入結束後提取http數據,寫入Kafka,Python實現的過程如下圖。
核心代碼:
數據存儲
開啟一個SparkStreaming任務,從kafka消費數據寫入Hdfs,Dstream的python API沒有好的入庫介面,需要將Dstream的RDD轉成DataFrame進行保存,保存為json文件。
核心代碼:
演算法實現
抽取器(Extractor)
抽取器實現原始數據的參數提取和數據泛化,傳入一條json格式的http請求數據,可以返回所有參數的id、參數類型、參數名、參數的觀察狀態序列。
代碼示例:
訓練器(Trainer)
訓練器完成對參數的訓練,傳入參數的所有觀察序列,返回訓練好的模型和profile,HMM模型使用python下的hmmlearn模塊,profile取觀察序列的最小得分。
核心代碼:
訓練任務
Spark訓練任務抽取所有http請求數據的參數,並按照參數ID分組,分別進行訓練,將訓練模型保存到Hdfs。
核心代碼:
檢測任務
Spark Streaming檢測任務實時獲取kafka流數據,抽取出數據的參數,如果參數有訓練模型,就計算參數得分,小於基線輸出告警到Elasticsearch。
核心代碼:
總 結
所有的機器學習演算法都大致可分為訓練、檢測階段,基於HMM的web參數異常檢測是其中的典型代表,本文嘗試將機器學習演算法在大數據環境下使用,所有用到的代碼都會在Github上公開(其實數據抽取部分並不完美,歡迎提出好的建議)。
代碼地址
:https://github.com/SparkSharly/Sharly
*本文原創作者:foxscheduler,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載


※Linux內核添加異構內存管理將帶來加速GPU的新方式,還有可能帶來其他類型的機器學習硬體
※谷歌 IO 2017:值得期待的機器學習內容有哪些?
※深度學習PK傳統機器學習
※機器學習中用來防止過擬合的方法有哪些?
※亞馬遜:機器學習對Kiva機器人的價值非常大!
TAG:機器學習 |
※HttpRunner 實現參數化數據驅動機制
※Spotlight 論文:非參數化方法實現的極端無監督特徵學習
※DBScan+iris數據集實現+參數調節
※利用Kubernetes和Helm進行高效的超參數調優
※Prostate Cancer P D:雙參數MRI和多重參數MRI在檢測臨床顯著前列腺癌中的比較
※使用網格搜索優化CatBoost參數
※Python 環境下的自動化機器學習超參數調優
※LeCun力薦:Facebook推出十億參數超大容量存儲器
※PHP PDO fetch 模式各種參數的輸出結果一覽
※Radiology:容積多參數MRI在預測型經導管動脈化學栓塞術後不可切除性肝內膽管細胞癌的生存期
※iPhone X Plus參數曝光 尺寸與iPhone 8Plus相仿
※C 方法與參數 常見命名空間匯總 using的使用 main方法參數
※5.使用dynamic_reconfigure實現節點參數動態更新
※RPM命令的——nodeps 和——force參數解釋
※Megabass Orochi 蟒蛇系列路亞竿參數
※比iPhone X貴的手機 RED Hydrogen One部分參數公布
※CVPR2018搶先看 | DiracNets:無需跳層連接,訓練更深神經網路,結構參數化與Dirac參數化的ResNet
※常用的shell腳本參數整理
※Jeff Dean等人提出ENAS:通過參數共享實現高效的神經架構搜索
※佳能PowerShot G5 X MarkII參數曝光