谈谈反垃圾
由于常年從事用戶產(chǎn)品的開發(fā)工作,工作中難免遇到過各種各樣反垃圾的事,一回生二回熟,在摸爬滾打的對抗中,也摸出了一些門道,此文算是對個人經(jīng)驗的總結(jié),非專業(yè)視角的分享。
這里說的垃圾主要針對諸如垃圾評論,機器注冊,機器刷接口等等。
反垃圾很重要的兩步是:垃圾識別,垃圾處理。
垃圾識別
對于判別垃圾,通常有下面一些方法。
基于內(nèi)容的識別
在基于內(nèi)容的判別上,最直接的是關(guān)鍵詞過濾,比如包含“xxx”、“xxx”這類詞的極有可能是垃圾內(nèi)容,我們通過字符串匹配來判斷是否有這類關(guān)鍵詞。這里有一個難題,如果是檢索一段內(nèi)容是否包含某一個詞還算簡單,有很多算法可以實現(xiàn),比如經(jīng)典的KMP算法,很多語言內(nèi)置的字符串查找方法效率也很高。但是,要判斷一段內(nèi)容是否包含一堆關(guān)鍵詞中的某一個或某幾個,那就有一些難度了,總不能循環(huán)一遍所有關(guān)鍵詞挨個做匹配吧,所以此法必不可取。
這里推薦兩個方法,一個是基于trie樹的關(guān)鍵詞樹,具體有沒有開源實現(xiàn)的不清楚,我們使用中是自己基于Memcached改了一個,保留Memcached的簡單協(xié)議,修改內(nèi)部邏輯為trie樹的查找,簡單來說就是將關(guān)鍵詞做字節(jié)切分,建立一棵trie樹,判斷一段話中是否包含這些關(guān)鍵詞,只需要從根節(jié)點向下檢索即可。
另外一個方法,是利用貝葉斯算法來進行垃圾概率計算。貝葉斯算法這里就不多展開說了,其原理簡單來說就是,收集一組正常內(nèi)容和一組垃圾內(nèi)容,用此內(nèi)容對系統(tǒng)進行訓(xùn)練,讓系統(tǒng)能夠知道每個詞在正常內(nèi)容中和是在垃圾內(nèi)容中的概率。做完訓(xùn)練后,再有一段新內(nèi)容過來,可以直接對其中的詞進行綜合加權(quán)計算,得出整段內(nèi)容是正常或垃圾的概率。
基于特殊內(nèi)容的識別
上面是純粹基于隨機內(nèi)容的識別,而實際上我們可能還有一些省力的方法,比如一般的垃圾內(nèi)容經(jīng)常會有下面一些特征:帶鏈接(因為要把用戶引導(dǎo)到自己的垃圾網(wǎng)站),帶圖片(為了更醒目),帶數(shù)字串(比如QQ號,電話號等等),通過這些特征做字符串匹配也是一個好方法,而且就個人經(jīng)驗來看,還比較奏效。其中需要注意的一點就是,上面的鏈接、數(shù)字串這些,通常攻擊者都會搞一些變體,不會直接寫鏈接和數(shù)字讓你判斷。比如換成中文數(shù)字和字母,你知道,UTF8是很博大精深的。比如:1?2?3?4?5?6?7?8?9?0? 這種。所以判斷規(guī)則上需要多做一些兼容,比如把這種東西先全轉(zhuǎn)成數(shù)字來判斷。
基于請求方式的識別
另外,垃圾畢竟是通過我們暴露給用戶的各種接口進來的,而攻擊者請求我們接口的方法難免與真實用戶有差距。比如說,正常用戶會先進入注冊頁面,再填表單,再提交注冊按鈕。但是惡意注冊程序,很可能是不會先訪問你的注冊頁面的,而是直接請求注冊接口(利用這一點我們就可以作文章,比如對用戶訪問路徑進行記錄,如果未訪問頁面就直接請求接口的,判為惡意請求)。另外就是攻擊者的http頭信息,比如最常見的,UA字段是否是cUrl或者其它非正常瀏覽器。或者像很多前端團隊都有在請求url上添加隨機數(shù)的習(xí)慣,這樣本來是為了避免后端緩存,但有些低水平的垃圾請求會原樣的每次都用同一個隨機數(shù),這就很容易識別他們了。總之,從http請求的層面可識別的東西很多,只要攻擊者偽裝有一點紕漏,咱們就可以抓到他的尾巴。
基于請求主體的識別
如果我們遇到UGC內(nèi)容的垃圾攻擊,那么發(fā)起請求的肯定得是一個正常用戶(如果是匿名社區(qū)請忽略此條)。這時候,內(nèi)容發(fā)送主體的信用級別,就可以轉(zhuǎn)移為對信息質(zhì)量的判別上來。就像我們都懂的,某些大的平臺也會對不同用戶執(zhí)行不同的審核策略(比如都知道的先審后放,還是先放后審),這也需要我們對內(nèi)容發(fā)布主體有充分的信用分級。比如,一個注冊24小時內(nèi)的用戶相對一個注冊三年發(fā)帖無數(shù)的用戶來說,信用等級就低得多。
基于內(nèi)容載體的識別
垃圾內(nèi)容之所以能形成黑色產(chǎn)業(yè)鏈,通常絕不會是惡作劇玩玩而已,所以跟互聯(lián)網(wǎng)最傳統(tǒng)的廣告模式一樣,垃圾也希望能夠多曝光,多賺點擊。那怎么做呢,通常就是選擇在用戶扎堆的地方去發(fā)。比如時下熱門的電視劇,熱點的新聞事件下面就是垃圾流量的公共廁所了。另外,在一些政治軍事內(nèi)容版塊發(fā)xxx言論,在一些娛樂美女內(nèi)容版塊發(fā)成人網(wǎng)站,這些也都是常用的路數(shù)。總的來說就是,同樣一條內(nèi)容,在熱門版塊發(fā)布,更有可能會是垃圾內(nèi)容,需要我們更多的關(guān)注。
垃圾處理
好吧,上面說了一大堆的方法去給內(nèi)容和用戶評級,以便我們能夠?qū)σ粋€用戶或者一段發(fā)布的內(nèi)容進行預(yù)估,那么,在我們了解了一個用戶或者一段內(nèi)容是否可能是垃圾后,我們腦子里首先蹦出來的可能就是:封殺!但實際處理方法可能不僅封殺一種,下面我們就來探討一下對垃圾攻擊的幾種處理方法。
制定封殺方法
如果我們已經(jīng)確切掌握了垃圾流量的規(guī)律,比如某一個IP或一組IP,比如同一組參數(shù),比如內(nèi)容總是包含某網(wǎng)址的變體,那么我們就可以直接大開殺戒,用這些特征直接進行封殺操作。
制定審核級別
順著上面的思路,我們可以對不同的用戶和內(nèi)容施加不同的審核策略,比如是直接放行、先審后放、先放后審還是直接斃掉。我們還可以對用戶施加不同的限制策略,比如新注冊用戶每天只能發(fā)3條內(nèi)容(在審核通過一條后又可以再發(fā))。
工作量證明
工作量證明是一個在反垃圾郵件中的方法,最近火得不得了的比特幣,工作量證明也是其核心理論支柱之一。通過引入工作量證明方法,我們甚至可以不用對垃圾流量進行判別。只要加一道隱形的門檻,就足以讓很多攻擊者卻步。
舉個例子,如果攻擊者原來只需要請求一次接口就能夠發(fā)布一條信息,現(xiàn)在我們需要他在接口請求之前先填一個驗證碼,他就沒那么容易自動狂發(fā)內(nèi)容了。上面這個邏輯大家都能理解,也確實能奏效,但是很抱歉,這樣做很傷用戶體驗,產(chǎn)品經(jīng)理說不行。
那我們換一種做法,我們讓用戶在請求前先做大約10w次的md5運算,普通用戶的機器偶爾進行一次這樣的計算不算什么,但是對攻擊者來說,它需要單機發(fā)布大量內(nèi)容,如果我們要求每條內(nèi)容都需要做10w次md5的話,對的硬件資源是很大的挑戰(zhàn),也是讓他放棄對你網(wǎng)站進行攻擊的一個方法。
當(dāng)然,如果我們直接用上面的10w次md5的方法,我們在服務(wù)端也需要做同樣多的工作才能對傳入的接口進行驗證,對我們服務(wù)器本身也是很大的挑戰(zhàn)。所以上面只是一個為了讓我們理解的例子,通常的做法是,服務(wù)端給定一個隨機字符串 s1,客戶端需要找到一個數(shù) d,這個數(shù)要滿足下面條件:這個數(shù)破加在這個隨機串后同組成一個新串 s2,這個新串進行md5后,前5位都要是0。大家可以想一下,要達到這樣的標(biāo)準(zhǔn),客戶端需要不斷循環(huán)來尋找這個合適的d,而服務(wù)端驗證卻是只需要進行一次md5就可以了。這就是所謂的工作量證明。
請求簽名
請求簽名也是一個省時省力的好方法,前后端約定一種hash算法(最好是自創(chuàng)的),前端對請求內(nèi)容進行簽名,后端驗證簽名。通過對前端代碼進行混淆,讓攻擊者很難實現(xiàn)你的hash算法。增加他的攻擊成本。
查出源頭
發(fā)垃圾內(nèi)容的攻擊者通常都不會用自己機器或服務(wù)器IP(要不你就賺到了,直接封IP就行了),而是用手里控制的肉雞或者掃描來的http代理來做,其實識別肉雞和代理也比較簡單,最直接的方法就是看看開沒開著80、8080、3128等端口。這是一般代理的常用接口,另外一般情況下被拿下的肉雞也都是web接口防范不嚴造成的。如果是普通http代理,很可能會很有良心的通過x-forward-for,或者x-real-ip等http頭信息把源ip傳給你,而對于肉雞找到肉雞,如果你的黑客水平夠,你可以直接也黑上去,看看是哪個IP在控制它,從而查到真實IP。查到攻擊者的真實IP后如何處理就看你的了,是聯(lián)系攻擊方和平解決,直接報案還是把攻擊者給黑了。那就看個人想法和水平了。
策略與戰(zhàn)略
上面說了一堆戰(zhàn)術(shù)層面的東西,下面聊一點戰(zhàn)略上的原則。
1.反垃圾是一場成本的較量
反垃圾,其實不是一項技術(shù)競賽,更不像是個人恩怨,更多的是成本較量。 如果你的網(wǎng)站流量大,但防護措施做得不夠,那垃圾流量過來是必然的。我們所有的反垃圾策略只有一個目的,就是增加攻擊者的成本,當(dāng)成本上升到某一閥值時,攻擊者會發(fā)現(xiàn)在你的網(wǎng)站玩太費勁,投入產(chǎn)出比太低,于是會去找同類型的其它網(wǎng)站。所以就像獅子和羊群一樣,只要不是跑得最慢的那一只,就能逃過獅子的爪牙。
2.多數(shù)攻擊者痛點在IP
無論是用代理,還是肉雞,攻擊者的IP資源總是比較有限的,所以收集到足夠多的IP進行封殺,通常能夠解決大問題。
3.實而示之虛
上面說反垃圾是一場成本較量,但在我們實際操作中,卻要盡量避免真正的較上勁。比如當(dāng)你發(fā)現(xiàn)了惡意請求的規(guī)律,如果你選擇直接對此規(guī)則的請求返回404,那么攻擊者也會馬上知道它的攻擊特征被你發(fā)現(xiàn)了,從而迅速進行升級對抗。但是如果你只是讓他的操作無實際效果,但還照樣返回“注冊成功”、“發(fā)布成功”,那么攻擊者可能會麻痹大意很長時間才會發(fā)現(xiàn)。正如《孫子兵法》中說的:“實而示之虛”。實際上在垃圾與反垃圾的較量中,最忌諱的就是無止境的軍備競賽。
4.發(fā)現(xiàn)特征之釣魚策略
有的攻擊者很高明,能夠?qū)⒆约旱恼埱髠窝b得得正常用戶一模一樣,所有的http頭信息,請求參數(shù),都完全仿真。對于這樣的攻擊者,我們有什么辦法抓到他的尾巴呢。這里給大家介紹一種釣魚策略。首先你修改一下你的網(wǎng)站的前后端邏輯,比如前端增加某一個參數(shù),后端判斷沒有這個參數(shù)請求就會失敗,這時候攻擊者馬上就會發(fā)現(xiàn)自己請求失敗了,通過對正常請求的抓包,他很快發(fā)現(xiàn)你增加了一個參數(shù),那他會跟著進行修改。這時我們讓他爽幾天。然后偷偷地把這個無關(guān)緊要的參數(shù)撤掉。這時候,所有正常用戶請求中都不會有這個參數(shù)了,但是,攻擊者不會時時關(guān)注我們的請求參數(shù),所以還會在一段時間內(nèi),繼續(xù)加上這個參數(shù)請求。這時釣魚成功,正是我們的好機會,在這段時間內(nèi),我們可以盡量收集垃圾的IP,發(fā)布賬號等信息。等收集到一定程度一起封掉(當(dāng)然,這里的封掉也不要暴力封掉,而是讓看起來沒有被封掉)。
總的來說,反垃圾工作其實不是一個技術(shù)活,要求更多的是細致、謹慎與耐心,希望上面東西對你有用。
總結(jié)
- 上一篇: Scheme语言深入
- 下一篇: linux优化deepin启动速度,如何