數(shù)據(jù)科學(xué)在Web威脅感知中的應(yīng)用(一)

文 | 楚安 2015.02

前言?

從一開始我們就試圖把分析處理對(duì)象指定為大規(guī)模環(huán)境中的Web威脅,不是為了浮夸與博眼球,也不是為了刻意拔高姿態(tài),而是寄希望與能找到一種普世通用的數(shù)據(jù)方法論能適用于各種不同類別的中小型站點(diǎn)所面臨的威脅。這里的「大規(guī)?!?,指的是有著成百萬乃至上千萬的站點(diǎn)的環(huán)境。這些站點(diǎn)使用著不同的編程語言、不同的框架、不同的Web組件,有著不同的業(yè)務(wù)、不同的邏輯以及不同的用戶,唯一相同的是它們每天都在遭受著各式各樣的攻擊。

同時(shí),大規(guī)模的環(huán)境之下充斥著各種轉(zhuǎn)瞬既逝的信息,消逝之快快到我們來不及停下來諦聽,新的信息又聯(lián)翩而至。對(duì)于威脅,沒有什么是比「大規(guī)?!古c「轉(zhuǎn)瞬既逝」還更好的庇護(hù)。相比茫然,我們更多的是恐懼,恐懼的不是看到了這么多威脅,而是那些還沒看到的威脅。我們甚至回答不出還有多少是未知,而未知,永遠(yuǎn)又是最為可怕的。我們一次次為新的未知感到驚喜,而又一次次的面對(duì)著新的未知,懷疑自己懷疑著這個(gè)世界。

這個(gè)系列至少有三個(gè)部分,我們希望能在不斷探索的過程中,嘗試摸索楚一些科學(xué)的數(shù)據(jù)方法,用有別于經(jīng)典安全產(chǎn)品的思路來嘗試解決一些新問題,以及對(duì)老問題的解法「re-design」。由于篇幅有限,第一部分只能先鋪墊一些淺層次的知識(shí),感知的也注定只是一些淺層次的線索。同時(shí),第一部分的所有思路都不是任何一個(gè)人的功勞,是多少個(gè)日夜大家一起碰撞后的成果。他們是:

@碳基體、@Rainy_zh、@zhouxiangrong、@mkods、@醬油男高漸離、@yuklin_、@破-見、@FlyR4nk、@fangzheng_rhw、@_X110、@ThomasBright、@Olonglong、@楚安、@tata

1. 異常模型

1.1 參數(shù)異常模型

回顧一下Web威脅中的幾大類攻擊,SQLi、XSS、RCE……等雖然攻擊方式各不相同,但基本都有一個(gè)通用的模式,即通過對(duì)參數(shù)進(jìn)行注入payload來進(jìn)行攻擊,參數(shù)可能是出現(xiàn)在GET、POST、COOKIE、PATH等等位置。所以第一個(gè)異常模型,我們希望能覆蓋掉參數(shù)中出現(xiàn)的異常,這樣就能覆蓋掉很大一部分的常見的Web攻擊。

1.1.1 模型原理

假設(shè)有這樣一條url:www.xxx.com/index.php?id=123。如果我們拉出所有這條url的訪問記錄,不難發(fā)現(xiàn):正常用戶的正常請(qǐng)求雖然不一定完全相同,但總是彼此相似;攻擊者的異常請(qǐng)求總是彼此各有不同,同時(shí)又明顯不同于正常請(qǐng)求。

正??偸腔鞠嗨?異常卻各有各的異常

正??偸腔鞠嗨?,異常卻各有各的異常。基于這樣一條觀測經(jīng)驗(yàn),如果我們能夠搜集大量參數(shù)id的正常的參數(shù)值,建立起一個(gè)能表達(dá)所有正常值的正常模型,那么一切不滿足于該正常模型的參數(shù)值,即為異常。

異常由正常決定

如果我們把參數(shù)id的每個(gè)參數(shù)值看作一個(gè)序列(Sequence),那么參數(shù)值中的每個(gè)字符就是這個(gè)序列中的一個(gè)狀態(tài)(State)。同時(shí),對(duì)于一個(gè)序列,為123或者124甚至是345,其背后所表達(dá)的安全上的解釋都是「數(shù)字 數(shù)字 數(shù)字」,我們用「N」來表示「數(shù)字」,這樣就得到了對(duì)應(yīng)的隱含序列。

參數(shù)值安全上的解釋

到這里已經(jīng)隱約看到了隱馬爾可夫的影子。對(duì)于數(shù)字我們用N來表示,相應(yīng)的對(duì)于其他unicode字符,也做類似的泛化對(duì)應(yīng)關(guān)系。英文字符、中文字符、中文標(biāo)點(diǎn)字符以及其他語言的所有字符對(duì)應(yīng)狀態(tài)「A」,對(duì)控制字符以及英文標(biāo)點(diǎn)字符,對(duì)應(yīng)隱含狀態(tài)為自身。

觀測序列與隱含序列

這樣做的原因是因?yàn)橥ǔR粋€(gè)參數(shù)注入式的Web攻擊payload是由一些攻擊關(guān)鍵詞,加上一些特殊符號(hào)構(gòu)成。特殊符號(hào)起到閉合前后正常語句,分隔攻擊關(guān)鍵詞的作用。通常這些特殊字符為英文標(biāo)點(diǎn)符號(hào)、控制字符等,所以對(duì)這些字符不做泛化的對(duì)應(yīng)。

XSS payload

但是,也有一些特殊情況,如上幾個(gè)XSS payload是利用了字符集編碼轉(zhuǎn)換:故也可以考慮對(duì)「??シセ??……」等幾個(gè)特殊字符單做處理。

隱馬爾可夫模型

回顧一下HMM的三類應(yīng)用:

解碼問題,根據(jù)模型參數(shù)和觀測序列,找出該觀測序列最優(yōu)的隱含狀態(tài)序列;評(píng)估問題,根據(jù)模型參數(shù)和觀測序列,計(jì)算該觀測序列是由該模型生成的概率;學(xué)習(xí)問題,根據(jù)一系列觀測序列,建立對(duì)應(yīng)該系列序列最優(yōu)的HMM模型。

這里我們只用得到后兩個(gè)。在訓(xùn)練階段,對(duì)應(yīng)「學(xué)習(xí)問題」,用大量正常的參數(shù)值訓(xùn)練出站點(diǎn)www.xxx.com下index.php下的參數(shù)id的HMM模型;在檢測階段,對(duì)應(yīng)「評(píng)估問題」,待檢測的參數(shù)值帶入模型檢測是否是正常。

參數(shù)異常模型

不同的參數(shù),正常的值不同。同時(shí),有參數(shù)傳遞的地方,就有可能發(fā)生參數(shù)注入型攻擊。所以,需要對(duì)站點(diǎn)下所有路徑下,所有GET、POST、PATH、COOKIE中的所有參數(shù)都訓(xùn)練各自的正常模型。另外,對(duì)參數(shù)名本身,也訓(xùn)練其正常的模型,見如下case:

dedecms payload

1.1.2 工程實(shí)現(xiàn)

整個(gè)模型包含4個(gè)主要模塊,抽取器「Extractor」、訓(xùn)練器「Trainer」、檢測器「Detector」、重訓(xùn)練器「reTrainer」。

對(duì)每條Http原始日志,先經(jīng)過Extractor進(jìn)行參數(shù)拆解,各種ETL,解碼等處理。這一步是最容易描述但確是最難做好的。比如URL中雖然都是百分號(hào)編碼,但字符集卻有GBK、UTF-8、GB2312等等,如何選擇正確的字符集來解碼?再比如POST傳遞參數(shù),可以通過urlencoded、multipart/form-data、json或xml等,如何保證能夠正確的提取?

Extractor

良好的數(shù)據(jù)質(zhì)量,才能保證上層建筑的精準(zhǔn)。有句話是這么說的「寧愿去洗廁所,也不寧愿洗數(shù)據(jù)」,但是不經(jīng)歷過數(shù)據(jù)之臟,如何有資格經(jīng)歷數(shù)據(jù)之美?「Extractor」出來的數(shù)據(jù),根據(jù)是否已經(jīng)有對(duì)應(yīng)的訓(xùn)練好的模型,拆分為兩部分,沒有對(duì)應(yīng)模型的數(shù)據(jù)進(jìn)入Trainer開始訓(xùn)練流程。

Extractor 分割

上文中我們提到,我們要訓(xùn)練的是正常參數(shù)值從而得到正常模型。這就需要保證進(jìn)入訓(xùn)練集中的數(shù)據(jù)都必須是正常數(shù)據(jù)。如果都是異常數(shù)據(jù),那么得到的將是關(guān)于異常的模型,也就是說模型將會(huì)被污染。那么問題來了,如何在不知道什么是正常的情況下保證正常?

Trainer 過濾

第一步,對(duì)某個(gè)ip,只要其當(dāng)天內(nèi)所有請(qǐng)求中有一條命中了WAF,其余所有請(qǐng)求不管是正常的還是異常的,均不進(jìn)入Trainer;如果某個(gè)ip命中掃描器特征或掃描器行為(這個(gè)模型將在另外一篇文章中介紹),該ip所有請(qǐng)求也不進(jìn)入Trainer。

Trainer 抽樣

第二步,對(duì)每個(gè)要訓(xùn)練的參數(shù),每個(gè)ip每天只能貢獻(xiàn)一次參數(shù)值。這樣能保證上述過濾失效的情況下也只能有一條異常數(shù)據(jù)混進(jìn)該參數(shù)的Trainer中。只要大多數(shù)進(jìn)入訓(xùn)練池的數(shù)據(jù)是正常的,那么對(duì)模型的影響也不大。這就是「正常由大多數(shù)投票表決來決定」。同時(shí),每個(gè)參數(shù)的訓(xùn)練池有最低條數(shù)的限制,沒達(dá)到條數(shù)限制的參數(shù)不做訓(xùn)練,繼續(xù)等待更多的數(shù)據(jù)進(jìn)入Trainer。

有最低限制,就相應(yīng)的有最高限制,對(duì)于部分?jǐn)?shù)據(jù)量很大的參數(shù),過多的訓(xùn)練數(shù)據(jù)會(huì)導(dǎo)致訓(xùn)練時(shí)間太長。對(duì)這種情況,我們?cè)僮鲆粋€(gè)分層抽樣。

觀測序列與隱含序列

在模型原理部分我們提到觀測序列與隱含序列的對(duì)應(yīng)關(guān)系,但在工程實(shí)現(xiàn)中這樣去做,會(huì)存在很大的問題 。比如訓(xùn)練集中id參數(shù)的觀測序列全為「123abc」,相應(yīng)的隱含序列為「NNNAAA」,訓(xùn)練好模型后,待檢測序列為「124abc」。由于「4」這個(gè)觀測狀態(tài)不在訓(xùn)練集的狀態(tài)空間中,所以會(huì)被直接判定為異常。

工程實(shí)現(xiàn)中的觀測狀態(tài)數(shù)與隱含狀態(tài)數(shù)

但事實(shí)上我們并不需要這么「敏感」的異常。所以我們直接使用泛化后的序列「NNNAAA」作為觀測序列,而隱含狀態(tài)數(shù)取訓(xùn)練集中所有觀測序列的觀測狀態(tài)數(shù)均值四舍五入。

模型完成訓(xùn)練后,需要設(shè)定一個(gè)異常的閾值。什么樣的概率值的序列為異常?0.8,0.5?如果訓(xùn)練集中所有參數(shù)值均為正常,那么只需取訓(xùn)練集中的最低概率值為閾值即可。但即便之前我們做了這么多步,也是有可能混入一兩條異常數(shù)據(jù)進(jìn)入訓(xùn)練集的。這里我們可以簡單的使用3sigma來抵消,如果最低概率值位于3sigma區(qū)間外,取次低概率值,再求3sigma,如此反復(fù)。

「Trainer」部分結(jié)束后,開始「Detector」部分。從「Extractor」出來的有對(duì)應(yīng)Model的數(shù)據(jù),直接開始檢測,如果概率P<異常概率閾值H - epsilon小量,則認(rèn)為是異常,epsilon = (1/100) H。異常的數(shù)據(jù)最終再由data_id還原出對(duì)應(yīng)的原始Http數(shù)據(jù)。

任何模型都有衰減期,尤其是攻防模型。昨天的異常不一定今天就是異常,這就需要有一個(gè)重訓(xùn)練模塊「reTrainer」來持續(xù)迭代訓(xùn)練模型,用以抵消衰減的影響。比如/index.php?id=123在訓(xùn)練時(shí)id為123是正常的,但之后該Web應(yīng)用修改了代碼,正常的參數(shù)值變成了/index.php?id=abc+||+123,如果模型一層不變,所有之后的abc++123都會(huì)被認(rèn)為是異常。

reTrainer

那么什么時(shí)候需要開始重訓(xùn)練呢?當(dāng)過去的「大多數(shù)」已經(jīng)不能代表現(xiàn)在的「大多數(shù)」的時(shí)候。若大量不同人對(duì)某個(gè)參數(shù)出現(xiàn)大量相同序列的異常,且這些異常都不會(huì)命中威脅模型(下一節(jié)將介紹到)。同時(shí),數(shù)量上遠(yuǎn)大于對(duì)應(yīng)的模型的訓(xùn)練集中的數(shù)據(jù)量,訓(xùn)練集中的參數(shù)值序列也持續(xù)一段時(shí)間沒有再出現(xiàn)過,則將這部分異常開始重訓(xùn)練。至此,整個(gè)參數(shù)異常模型部分結(jié)束。

參數(shù)異常模型流程

1.2 節(jié)點(diǎn)異常模型

不能寄希望于一個(gè)模型就能覆蓋掉所有攻防上的異常,比如Webshell、敏感文件下載等這類Web威脅,在參數(shù)異常模型中,不會(huì)觸發(fā)任何異常。所以,我們考慮從另一個(gè)角度,來覆蓋這類節(jié)點(diǎn)異常。

1.2.1 模型原理

如果把站點(diǎn)看作一張大圖,站點(diǎn)下的每個(gè)頁面為這張大圖中的每個(gè)節(jié)點(diǎn),而不同頁面之間的鏈接指向關(guān)系為節(jié)點(diǎn)與節(jié)點(diǎn)之間的有向邊,那么我們能畫出如下這張有向圖:

Web Directed Graph

節(jié)點(diǎn)是否是異常,由其所處的環(huán)境中的其他節(jié)點(diǎn)來決定。類似一個(gè)簡化版的PageRank,如果大量其他節(jié)點(diǎn)指向某個(gè)節(jié)點(diǎn)(入度較大),那么該節(jié)點(diǎn)是異常的概率就很小。相反,如果一個(gè)節(jié)點(diǎn)是Graph中的孤立點(diǎn)(入度為0),則是異常的概率就很大。

單有這張有向圖還不夠,諸如/robots.txt、/crossdomain.xml之類的正常節(jié)點(diǎn)卻又無其他節(jié)點(diǎn)指向的情況太多了,這個(gè)層面的異常能表達(dá)的信息量太少,所以我們還需要引入另一個(gè)異常。

通常一個(gè)異常節(jié)點(diǎn)(如Webshell),大多數(shù)正常人是不會(huì)去訪問的,只有少量的攻擊者會(huì)去訪問(這里不考慮修改頁面寫入webshell的情況,這個(gè)模型不能覆蓋這類case)。用一個(gè)簡單的二部有向圖就能很好表達(dá)。入度越少的節(jié)點(diǎn),同樣越有可能是異常。

節(jié)點(diǎn)異常模型

聯(lián)合兩張圖中的異常,其聯(lián)合異常就會(huì)比單獨(dú)任一張圖產(chǎn)出的異常更具表達(dá)力。該模型較為簡單,不再贅述。

1.2.2?工程實(shí)現(xiàn)

整個(gè)模型包含3個(gè)主要模塊,抽取器「Extractor」、訓(xùn)練器「Trainer」、檢測器「Detector」。對(duì)每條Http原始日志,同樣先經(jīng)過「Extractor」進(jìn)行路徑抽取,各種ETL,解碼等處理。這里需要由于有向圖中的邊關(guān)系由referer->path來確定,而referer是可以輕易偽造的,所以,需要對(duì)fake referer做個(gè)檢測。

Session Navigation Pattern

先做一個(gè)session identification,對(duì)每個(gè)session塊中的數(shù)據(jù),分析其導(dǎo)航模式。正常的referer必然會(huì)出現(xiàn)在當(dāng)前session中之前的path數(shù)據(jù)中,同時(shí),能夠與當(dāng)前session之前的數(shù)據(jù)形成連通路徑。當(dāng)然,導(dǎo)航模式并不能完全檢測所有的偽造referer,攻擊者完全可以先訪問A,再構(gòu)造一個(gè)referer為A訪問B的請(qǐng)求。不過沒關(guān)系,后面還有方法能避免這些數(shù)據(jù)進(jìn)入Trainer。

「Extractor」出來后的數(shù)據(jù),直接進(jìn)入「Detector」,Detector檢測path是否在有向圖中,如果在,則更新有向圖中節(jié)點(diǎn)的最后訪問時(shí)間;如果不在則認(rèn)為是有向圖異常,進(jìn)入到二部圖中。二部圖維護(hù)一個(gè)N天的生命周期,如果某path節(jié)點(diǎn)總的入度小于L,則為最終異常。

「Trainer」每天從二部圖中過濾掉當(dāng)天命中WAF、掃描器特征或掃描器行為的源ip所有請(qǐng)求,若節(jié)點(diǎn)總?cè)攵却笥贛的節(jié)點(diǎn),則迭代節(jié)點(diǎn)極其鏈接關(guān)系加入到有向圖中,并在二部圖中去除該節(jié)點(diǎn)以及對(duì)應(yīng)邊。同時(shí),對(duì)于有向圖中最后訪問時(shí)間超過30天的節(jié)點(diǎn)直接丟棄。

節(jié)點(diǎn)異常模型 流程

2. 威脅模型

2.1 攻擊識(shí)別

99%的異常事實(shí)上都不是什么攻擊,異常的發(fā)現(xiàn)并不難,難的是對(duì)異常的解讀,或者說賦予異常一個(gè)安全業(yè)務(wù)上的解釋。理論上來說,如果能有足夠豐富的各個(gè)層面的數(shù)據(jù),能夠?qū)γ總€(gè)異常都做出一個(gè)合理的解釋。

上文中我們提到,多數(shù)的普通Web攻擊都是由「特殊字符」加上「攻擊關(guān)鍵詞」這種模式構(gòu)成。而參數(shù)異常模型本身就能夠很好的表達(dá)「特殊字符」,剩下的我們其實(shí)只要能表達(dá)「攻擊關(guān)鍵詞」這一層的信息即可。

所以我們想嘗試在參數(shù)異常數(shù)據(jù)的基礎(chǔ)上,注入一些領(lǐng)域知識(shí),從而構(gòu)成一個(gè)分類器,從異常中剝離出攻擊,并且能夠?qū)Σ煌N類的攻擊進(jìn)行分類。但我們又不太想人為構(gòu)造樣本人工打標(biāo)記,因?yàn)檫@樣又會(huì)帶來一些個(gè)體因素的影響,我們希望能用真實(shí)世界中的流量來獲得領(lǐng)域知識(shí)。

首先第一步,我們先從WAF中提取近幾年的數(shù)據(jù),對(duì)各個(gè)類別的攻擊payload做一個(gè)簡單的分詞。然后再從參數(shù)異常模型的歷史數(shù)據(jù)中提取大量的「絕對(duì)正?!箻颖?,也做一個(gè)簡單的分詞。顯而易見,如果某一個(gè)詞(Term)在一類攻擊payload樣本中出現(xiàn)的次數(shù)越多,那么我們認(rèn)為該詞與該類攻擊的相關(guān)程度越大。同時(shí),不同的詞的重要程度是不同的,如果該詞只在這類攻擊中出現(xiàn),而在正常樣本中幾乎沒有出現(xiàn),那么該詞對(duì)與該類攻擊重要性更高。

TF-IDF

自然就聯(lián)想到了TF-IDF。數(shù)學(xué)意義上,TF用來表達(dá)相關(guān)程度,IDF用來表達(dá)重要程度。在TF中,分子部分,表示i這個(gè)term在攻擊類別j中出現(xiàn)的次數(shù)。為了避免對(duì)「短payload攻擊」的不利,需要將詞數(shù)(term count)轉(zhuǎn)換為詞頻(term frequency),所以分母部分表示在攻擊類別j中所有term出現(xiàn)的總次數(shù)。在IDF中,分子部分表示所有樣本庫中(包含正常和攻擊)的樣本總數(shù),分母部分表示包含term的樣本數(shù),加1是為了避免為0,取對(duì)數(shù)是為了表達(dá)tearm的信息量。最終TF與IDF二者相乘,用來刻畫一個(gè)term對(duì)該類攻擊的描述程度。

接下來就涉及到分類器的選擇,事實(shí)上我們?cè)跍y試了多個(gè)分類器后,發(fā)現(xiàn)在該場景下,僅僅就用簡單的基于規(guī)則的分類器就已能滿足大部分的情況。如果還想繼續(xù)提高精度,可以嘗試再表達(dá)term與term之間的順序關(guān)系,如二元gram、長亭科技提到的基于編譯原理的語法分析等等。另外一種思路是直接描述整個(gè)payload的「結(jié)構(gòu)」特征。例如如下兩個(gè)payload,如果采用類似參數(shù)異常模型中對(duì)序列泛化的思路(長度上也做壓縮泛化),將得到一條相同的泛化序列:

payload 結(jié)構(gòu)

不難發(fā)現(xiàn),其結(jié)構(gòu)上是相同的。事實(shí)上我們抽取了WAF 1000w+真實(shí)環(huán)境中的SQLi payload分析后發(fā)現(xiàn),其泛化后的序列只有幾萬。所以從「結(jié)構(gòu)」這條路上去探索,也是個(gè)不錯(cuò)的選擇。

2.2 識(shí)別成功的攻擊

在異常中,99%的異常都不是攻擊,而在攻擊中,99%的攻擊又都是無害的攻擊。而我們的精力總是有限的,我們希望能關(guān)注那些危害程度更高的攻擊,這就迫使我們需要從攻擊中識(shí)別出哪些是成功的攻擊。

Kill Chain的思想本身是很好的,在攻擊者的攻擊鏈路上的幾個(gè)關(guān)鍵節(jié)點(diǎn),如果能串聯(lián)起來,說明這是一次成功的攻擊。但是Kill Chain設(shè)計(jì)最初是為了檢測APT,所以在Web威脅中,我們只需要借鑒這種思路,而沒必要生搬硬套7個(gè)階段。

Kill Chain Model

Kill Chain的本質(zhì)還是多源異構(gòu)數(shù)據(jù)的關(guān)聯(lián),攻擊路徑上不同層面的數(shù)據(jù)來建立聯(lián)系。我們可以采用很簡單的二步驗(yàn)證,如,一個(gè)Http層出現(xiàn)的SQLi paylaod,相同的payload同時(shí)出現(xiàn)在SQL層的異常,即形成一個(gè)確認(rèn)的SQLi攻擊;同理,一個(gè)Http層的異常相同的payload出現(xiàn)在了命令日志層面的異常中,即形成一個(gè)確認(rèn)的RCE。(對(duì)于其他非Http層數(shù)據(jù)的異常,會(huì)在之后的文章中介紹)

異構(gòu)數(shù)據(jù)關(guān)聯(lián)

相同的思路,我們也可以同安全產(chǎn)品的數(shù)據(jù)來關(guān)聯(lián)。如,關(guān)聯(lián)WAF數(shù)據(jù),關(guān)聯(lián)不上的即為WAF Bypass;成功的攻擊數(shù)據(jù)同掃描器數(shù)據(jù)來關(guān)聯(lián),關(guān)聯(lián)不上的即為掃描器漏報(bào)等等。

2.3 CMS Nday識(shí)別

涉及到Http這一層的數(shù)據(jù),想必大家最感興趣的,就是如何挖掘出一些Web CMS Nday。值得一提的是,如果只是挖出一些「可能」是Nday的請(qǐng)求,意義并不是很大,在大規(guī)模的環(huán)境中這樣的請(qǐng)求每天實(shí)在是太多了,多到讓人力不從心。抽象這個(gè)過程,我們希望能做到兩點(diǎn):1. 明確知道這是一個(gè)Nday;2. 明確知道這是哪個(gè)CMS的Nday。

Nday首先一定是一個(gè)攻擊,所以不需要再從異常數(shù)據(jù)開始,攻擊分類器中出來的數(shù)據(jù)可以直接作為源數(shù)據(jù)。但反過來攻擊卻不一定是Nday,通常情況下,大多數(shù)Nday是帶Exp性質(zhì)而非PoC性質(zhì)的。比如SQLi的CMS Nday多數(shù)是直接讀管理員表數(shù)據(jù)之類的「利用」行為,而非是「and 1=1」之類的「證明」行為。

而對(duì)于第二點(diǎn),「知道這是哪個(gè)CMS」背后對(duì)應(yīng)的其實(shí)是一個(gè)Web應(yīng)用指紋識(shí)別的過程,不過比傳統(tǒng)的應(yīng)用指紋識(shí)別更具挑戰(zhàn)的是,因?yàn)闊o法知道哪個(gè)頁面會(huì)出現(xiàn)Nday,所以只能通過一條Http數(shù)據(jù),就要識(shí)別出對(duì)應(yīng)的CMS。

另外,如果站在攻擊者角度來考慮的話,Nday通常不會(huì)只出現(xiàn)在一個(gè)站點(diǎn)上。這一點(diǎn)很重要,能幫助我們過濾掉很多噪聲數(shù)據(jù)的同時(shí),也能讓我們感知某個(gè)Nday是否在大規(guī)模利用。

Nday 行為

我們先從SQLi Nday嘗試入手,觀察如下這條payload:

SQLi Nday

多數(shù)的SQLi Nday,都會(huì)有一個(gè)「from xxx」的pattern,而xxx為具體某個(gè)CMS數(shù)據(jù)庫的表名,同時(shí)payload中也會(huì)出現(xiàn)CMS數(shù)據(jù)庫的字段名。豁然開朗,我們需要做的,其實(shí)只是建立一個(gè)CMS DB Schema指紋庫,以CMS表名和字段名作為指紋。一舉兩得,既能判定出是Nday,又能同時(shí)找到對(duì)應(yīng)的CMS。

下面再來看看GetShell類型的Nday。多數(shù)的Getshell Nday,都會(huì)有「<? eval」「<? fputs」之類的webshell代碼特征,或者是文件包含特征等等。同時(shí),我們可以取路徑以及參數(shù)名作為uri指紋用來識(shí)別CMS。

GetShell Nday

db指紋很容易建立,相比之下uri指紋就不那么容易建立了,我們需要借力于Web指紋識(shí)別產(chǎn)品。從指紋識(shí)別產(chǎn)品中提取CMS為wordpress的站點(diǎn)top 10000個(gè),然后提取這1w個(gè)站點(diǎn)7天內(nèi)的所有200的請(qǐng)求。去參數(shù)值后,分別對(duì)每條uri提取路徑指紋和參數(shù)值指紋。只有多個(gè)wordpress站點(diǎn)都同時(shí)具有該指紋,并且其他CMS沒有該指紋的,才最終進(jìn)入wordpress的uri指紋庫。同理,其他CMS的建立過程也類似。

CMS Nday 識(shí)別流程

整個(gè)識(shí)別流程如上圖所示。先取出攻擊分類器中出來的攻擊數(shù)據(jù),并且這些uri+payload出現(xiàn)在了多個(gè)站點(diǎn)上。緊接著,滿足SQLi pattern的數(shù)據(jù)同db指紋庫匹配,得到SQLi Nday;滿足GetShell pattern的數(shù)據(jù)同uri指紋庫匹配,得到GetShell Nday。

2.4 Webshell識(shí)別

以上幾個(gè)場景都是基于參數(shù)異常的數(shù)據(jù)的應(yīng)用,而對(duì)于節(jié)點(diǎn)異常數(shù)據(jù),最為直接的應(yīng)用就是識(shí)別Webshell。先來回想一下,安全工程師在做入侵復(fù)盤時(shí)怎么來確認(rèn)一個(gè)url是否為webshell:1.從Http數(shù)據(jù)中發(fā)現(xiàn)一個(gè)url有點(diǎn)「異?!?;2.訪問一下該uri,通過安全經(jīng)驗(yàn)知識(shí)從返回頁面識(shí)別出是webshell(大馬);3.如果返回頁面為空白(疑似一句話),從代碼層面來識(shí)別。

2.4.1 大馬識(shí)別

先來看一下大馬的識(shí)別。對(duì)于第一點(diǎn)節(jié)點(diǎn)異常數(shù)據(jù)已有,而第二點(diǎn),本質(zhì)上其實(shí)是引入response層面信息做網(wǎng)頁相似度計(jì)算。對(duì)于相似度計(jì)算,不妨先將問題退化為「網(wǎng)頁相同計(jì)算」。

webshell phpspy

問題變得非常好解。搜集大量的webshell樣本,訓(xùn)練階段對(duì)response數(shù)據(jù)計(jì)算md5,檢測時(shí)對(duì)待檢測樣本同樣算md5比對(duì)即可。顯而易見,這種方法準(zhǔn)確率極高,同樣缺陷也足夠明顯,嚴(yán)重依賴訓(xùn)練樣本庫,也就是只能檢測已知,不能感知未知。

而人總是貪婪的,一方面我們既想對(duì)已知保持高的檢測精度,同時(shí)又希望能保持一些對(duì)未知的感知能力。自然而然就想到了simhash之類的LSH。類似md5、sha1之類的屬于加密型hash,其設(shè)計(jì)的目的是為了讓整個(gè)分布盡可能地均勻。所以對(duì)輸入極其敏感,輕微變化的輸入,就會(huì)導(dǎo)致輸出大不一樣。而我們更希望對(duì)相似的輸入,產(chǎn)生相似的輸出。從而通過對(duì)輸出做相似計(jì)算,就能反映出輸出的相似性。然而事實(shí)上simhash在這個(gè)場景下效果并不是很好,原因是simhash主要適用于文本內(nèi)容的相似性檢測。

拋開全文hash的想法,有一類方法是去關(guān)注全文中的片段。直觀經(jīng)驗(yàn)告訴我們,如果兩個(gè)全文比較相似,那么全文中的部分全片,也很有可能很相似。反過來我們?nèi)绻苡?jì)算出片段的相似或相同,進(jìn)而就能得到全文的相似性。在網(wǎng)頁判重領(lǐng)域,有一種簡單而又有效的方法叫做最長句子簽名。取網(wǎng)頁內(nèi)容中最長的top3的句子作為簽名,檢測時(shí)對(duì)簽名做比對(duì)或者計(jì)算編輯距離。

webshell特征碼識(shí)別

同樣,殺毒領(lǐng)域的特征碼技術(shù)也是類似的思想。應(yīng)用到webshell檢測的場景下就是,隨機(jī)或特意的選取webshell response中多個(gè)片段作為片段指紋,記錄下偏移位置和特征值,用來表征該webshell。這類方法都具有較高的對(duì)已知的檢測精度,缺點(diǎn)依然是對(duì)新樣本感知能力尚不夠。

回到業(yè)務(wù)場景,一個(gè)網(wǎng)頁主要包含兩大部分:網(wǎng)頁結(jié)構(gòu)和網(wǎng)頁內(nèi)容。通常情況下,黑客對(duì)自己使用的webshell會(huì)做各種修改,但修改的大多都是網(wǎng)頁內(nèi)容,而不會(huì)去動(dòng)網(wǎng)頁結(jié)構(gòu)。所以其實(shí)我們?cè)谠搱鼍跋赂枰P(guān)注結(jié)構(gòu)的相似而不是內(nèi)容的相似。

(注:以下思路和模型均歸屬李景陽先生專利所有[1])要做結(jié)構(gòu)的相似計(jì)算,首先我們需要對(duì)整個(gè)DOM結(jié)構(gòu)找一個(gè)合適的數(shù)學(xué)對(duì)象來描述。常見的適合比較運(yùn)算的數(shù)學(xué)對(duì)象有標(biāo)量、向量、矩陣等,借鑒Vector Space Model的思想,我們選用高維向量來描述DOM結(jié)構(gòu)。VSM中以一個(gè)詞項(xiàng)作為向量空間的一個(gè)維度,詞頻作為權(quán)重,得到高維向量V(d)=(t1,ω1(d),…, (tn, ωn(d))。對(duì)應(yīng)到DOM結(jié)構(gòu)中,我們嘗試用N-gram片段來描述每個(gè)維度的向量。

每個(gè)tag作為一元gram,相鄰兄弟tag和相鄰父子tag作為二元gram,去除掉如html、head、body之類的通用tag。同時(shí),僅僅使用tag名稱會(huì)損失掉很多表達(dá)結(jié)構(gòu)樣式的信息,所以我們?nèi)ag+部分表達(dá)格式的屬性,hash之后映射到某一維度。同時(shí),對(duì)不同的gram賦予不同的權(quán)值,用來體現(xiàn)其表達(dá)結(jié)構(gòu)特點(diǎn)的能力,最終得到一個(gè)高維實(shí)向量。

特征向量抽取

直接計(jì)算高維向量一方面不同網(wǎng)頁結(jié)構(gòu)大小各有不同,形成的向量會(huì)變得很稀疏,另一方面,過高的維度也會(huì)帶來「維數(shù)災(zāi)難」,所以我們還需要做一個(gè)降維處理。但在該場景下,沒必要用太復(fù)雜的降維或projection手法,直接對(duì)M取模,將N維向量折疊壓縮到M維即可。

構(gòu)造好低維實(shí)向量,接下來就該定義相似度計(jì)算了。直觀上,歐式距離和余弦距離是最容易想到的兩種計(jì)算向量相似的距離。但是對(duì)長網(wǎng)頁歐式明顯不公平,而余弦只關(guān)注向量夾角的差異性不關(guān)注絕對(duì)長度上的差異,也就是說只關(guān)注tag之間的比例而非絕對(duì)數(shù)值,又會(huì)存在存在對(duì)長網(wǎng)頁過分抑制。所以綜合考慮,我們借鑒杰卡德相似的思想,定義偽距離如下,表達(dá)的物理意義為兩個(gè)網(wǎng)頁相同部分與不同部分的比值。

定義偽距離

有了向量和相似性計(jì)算,我們就不得不面臨一個(gè)工程問題,這種笛卡爾積式的兩兩比較,在大規(guī)模環(huán)境中來應(yīng)用就是災(zāi)難?;叵胍幌律镏讣y識(shí)別領(lǐng)域中的待識(shí)別指紋同指紋庫中指紋匹配的過程:1.先比對(duì)指紋的模式區(qū)、核心區(qū)等大的總體特征;2.滿足總體特征的,再比對(duì)特征點(diǎn)等局部特征。借鑒此思想,我們可以對(duì)離散的樣本數(shù)據(jù)構(gòu)造一個(gè)網(wǎng)格計(jì)算。

在向量空間中定義一套超立方網(wǎng)格,把空間切割成多個(gè)超網(wǎng)格,以超網(wǎng)格中心座標(biāo)來表示其自身。對(duì)于待檢測樣本,先計(jì)算其會(huì)落到哪個(gè)超網(wǎng)格,然后再同該超網(wǎng)格中的訓(xùn)練樣本進(jìn)行一一比對(duì),最終找到最相似的樣本。但是需要注意的是,一套網(wǎng)格會(huì)出現(xiàn)「區(qū)域隔離」的問題,可以通過構(gòu)造不同的多套網(wǎng)格來避免。

離散樣本網(wǎng)格化

如圖T1是待檢測網(wǎng)頁的特征向量,在紅色網(wǎng)格中,命中了超網(wǎng)格L1,進(jìn)而找到在紅色網(wǎng)格中最相似樣本為S1。而在黑色網(wǎng)格中,同樣的方法找到了樣本S2。最終再來比較與S1、S2的偽距離,得到最相似樣本S2。

2.4.2 一句話webshell識(shí)別

對(duì)于一句話webshell,response層面數(shù)據(jù)不需要做太復(fù)雜的模型,簡單的特征匹配就足夠。或者也可以采用2.2中二步驗(yàn)證的方法來驗(yàn)證。如,聯(lián)合主機(jī)agent做代碼層面的關(guān)聯(lián),或者關(guān)聯(lián)命令日志異常,又或者關(guān)聯(lián)2.3中的GetShell Nday等等。

結(jié)語

在本文的最后,我們想表達(dá)一些對(duì)于數(shù)據(jù)驅(qū)動(dòng)安全的看法。盡管在上文中我們介紹的都是模型在安全業(yè)務(wù)上的應(yīng)用,但我們想強(qiáng)調(diào)的一點(diǎn)是,數(shù)據(jù)驅(qū)動(dòng)的安全,一定不是靠模型來驅(qū)動(dòng)。對(duì)模型的趨之若鶩與過于迷信,掩蓋的是對(duì)數(shù)據(jù)對(duì)威脅的認(rèn)知不足。在安全數(shù)據(jù)科學(xué)領(lǐng)域,只有對(duì)業(yè)務(wù)領(lǐng)域有充分認(rèn)識(shí)的前提下,才有可能將數(shù)學(xué)上的解釋對(duì)應(yīng)到安全上的解釋,從而才有可能產(chǎn)生一些有用的淺層線索。

但是永遠(yuǎn)記得,多數(shù)情況下模型產(chǎn)生的也只是淺層線索,最終數(shù)據(jù)驅(qū)動(dòng)安全的頂層設(shè)計(jì),一定是充分發(fā)揮機(jī)器智能與人的智能,機(jī)器做機(jī)器擅長的計(jì)算而人完成人擅長的分析。有機(jī)的結(jié)合二者,才能成為對(duì)抗威脅不對(duì)稱的強(qiáng)力武器。所以在之后的文章中,我們希望能夠回歸數(shù)據(jù)本身,探索一些數(shù)據(jù)與數(shù)據(jù)之間的聯(lián)系,以及通過這些聯(lián)系我們能感知什么。

本文中提到的這些嘗試永遠(yuǎn)只能覆蓋小部分淺層的Web攻擊,同復(fù)雜而又殘酷的黑產(chǎn)威脅相比,這些都還只能算「溫室里的寶寶,把玩著自己的小玩具」。我們開開心心的在充滿陽光的溫室里搭建著自己的小城堡,以為以此就能抵擋得了小怪獸。但殊不知黑產(chǎn)的攻擊面,大多根本不在溫室里。而溫室的外面,沒有熟悉的陽光,有的只有一無所知的黑暗。需要我們?nèi)ヌ剿鞯倪€有很多,對(duì)于未知,我們都才剛剛起步。

參考

[1] 李景陽 張波. 網(wǎng)頁結(jié)構(gòu)相似性確定方法及裝置

[2] 威脅感知的方法論

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容