2014年5月,頗負盛名的搜狐視頻,背負了一起著名的DDoS攻擊事件。
當時,日本CDN服務商Incapsula聲稱,自己的一位客戶的服務器遭遇了搜狐視頻發起的DDoS攻擊,期間總共有超過2萬的網民通過搜狐視頻向這位客戶發起超過2000萬次的HTTP Get請求。然而如此知名的網站,怎么會甘冒不韙,公然向別人發起攻擊呢?原來,搜狐視頻是在未知的情況下被黑客利用,成為了攻擊的源頭。
有句話叫“趁虛而入”,搜狐視頻網站上恰好就有這么一個漏洞給了黑客“打劫”的機會。通過這個漏洞,黑客注冊一個搜狐視頻賬戶,在頭像中注入惡意代碼(JavaScript),然后用這個賬戶在視頻的評論區發布大量的評論。你看,每條評論都帶有用戶頭像,頭像中帶有惡意代碼,這樣,每條評論都附帶着惡意代碼。當任何用戶訪問這個視頻頁面的時候,都會觸發惡意代碼,實際上控制了搜狐視頻用戶的瀏覽器。
那么這段惡意代碼干了什么呢?簡單說,這段代碼就是在用戶不知情的情況下,定時向受害者發起HTTP訪問請求。這個定時器,是1秒。![]()
也就是說,當搜狐視頻用戶觀看視頻時,他的瀏覽器會每秒向受害者發起一次請求。如果用戶觀看30分鍾視頻,那么就會向受害者發起1800次請求。大家可能會覺得,這也沒有多少呀,但是,搜狐視頻這樣的大型視頻網站,同時在線觀看熱門視頻的用戶都是成千上萬級別的,黑客在多個熱門視頻下發布海量評論,輕松獲得無數“肉雞”。眾人拾柴火焰高,如果星火燎原到千家萬戶同時持續地向受害者發送請求,攻擊效果就可想而知了。
HTTP協議,HyperText Transfer Protocol,超文本傳輸協議。我們先來簡單回顧下HTTP協議的基本原理。
HTTP協議最基本的交互流程如下。![]()
完成TCP三次握手后,客戶端向服務器發起HTTP請求。正常情況下,服務器回應200 OK,在應答中添加應答長度,然后開始傳輸數據。
HTTP協議還有一種重定向的交互流程,如下。![]()
完成TCP三次握手后,客戶端向服務器發起HTTP請求。如果客戶端請求的這個URL是過期的,那么服務器就會回應客戶端302重定向報文,並攜帶新的URL地址。然后客戶端再重新向新的URL地址發起請求,服務器回應200 OK,並開始傳輸數據。
HTTP攻擊一般分為GET FLOOD和POST FLOOD攻擊
HTTP GET Flood攻擊的原理很簡單,攻擊者利用攻擊工具或者操縱僵屍主機,向目標服務器發起大量的HTTP GET報文,請求服務器上涉及數據庫操作的URI或其它消耗系統資源的URI,造成服務器資源耗盡,無法響應正常請求。
防御HTTP GET Flood攻擊的常用手段是源認證,這種防御方式適用於客戶端為瀏覽器的場景,因為瀏覽器支持完整的HTTP協議棧,可以正常回應抗DDOS設備發出的探測報文。源認證包括兩種方式,最基本的方式是302重定向認證。
302重定向認證
302重定向認證的原理是抗DDOS設備代替服務器向客戶端響應302狀態碼(針對GET請求方法的重定向),告知客戶端需要重定向到新的URL,以此來驗證客戶端的真實性。真實客戶端的瀏覽器可以自動完成重定向過程,通過認證;而虛假源或者一般的攻擊工具沒有實現完整的HTTP協議棧,不支持自動重定向,無法通過認證。
![]()
1、當連續一段時間內去往目標Web服務器的HTTP GET請求報文超過告警閾值后,抗DDOS設備啟動源認證機制。源認證機制啟動后,抗DDOS設備將會代替服務器與客戶端建立TCP三次握手。
2、抗DDOS設備攔截HTTP請求,代替Web服務器回應302狀態碼,將客戶端的訪問重定向到一個新的URI。
3、如果這個源是虛假源,或者不支持完整HTTP協議棧的攻擊工具,不會向新的URI發起請求。
4、如果這個源是真實客戶端,則會向新的URI發起請求。Anti-DDoS系統收到請求后,將該客戶端的源IP地址加入白名單。然后抗DDOS設備會再次回應302狀態碼,將客戶端的訪問重定向到一開始訪問的URI。
5、后續這個客戶端發出的HTTP請求報文命中白名單直接通過。
我們結合一組抓包信息來看一下交互報文的具體情況。
1、抗DDOS設備代替Web服務器與客戶端建立TCP三次握手,然后客戶端發起訪問請求。
![]()
(author https://www.cnblogs.com/Shepherdzhao/)
2、抗DDOS設備代替Web服務器回應302狀態碼,希望客戶端訪問一個新的URI地址“http://156.*.*.*/?dbiekfcjekngdjec”,然后雙方關閉連接。
![]()
3、真實客戶端會再次與抗DDOS設備建立TCP三次握手,並向新的URI“http://156.*.*.*/?dbiekfcjekngdjec”發起請求。
![]()
4、抗DDOS設備收到請求后,判定該客戶端為真實客戶端,將其IP地址加入白名單。同時抗DDOS設備會再次回應302狀態碼,將客戶端的訪問重定向到一開始訪問的URI,然后雙方關閉連接。后面該客戶端發出的HTTP請求報文就可以命中白名單直接通過了。
![]()
除了302狀態碼重定向方式,還有一種META Refresh重定向方式。META Refresh方式是通過修改HTML頁面來實現重定向,具有局限性;而302狀態碼方式是利用HTTP協議規范來實現重定向,適用性更好。所以302狀態碼方式是目前使用比較廣泛的重定向方式。
另外還有一種情況,網絡中存在HTTP代理服務器時,只要代理服務器IP地址通過源認證加入白名單,僵屍主機就可以利用代理服務器IP地址繞開源認證,導致防御失效。針對這種情況,抗DDOS設備提供了代理檢測功能。開啟該功能后,抗DDOS設備會檢測HTTP請求是不是通過代理服務器發出的。如果是,抗DDOS設備會從HTTP報文中獲取請求者的實際IP地址進行源認證,通過認證后才加入白名單。
302重定向認證利用HTTP響應報文中的302狀態碼來實現對客戶端的源認證功能,但是如果攻擊工具實現了完整的HTTP協議棧,或者像搜狐視頻攻擊事件中攻擊源都是真實的瀏覽器這種情況,會導致302重定向認證方式失效。此時,可以使用源認證中的增強方式,即驗證碼認證。
驗證碼認證
驗證碼認證的原理是抗DDOS設備要求客戶端輸入驗證碼,以此來判斷請求是否由真實的用戶發起,而不是由攻擊工具或僵屍主機發起。因為攻擊工具或僵屍主機無法自動響應隨機變化的驗證碼,所以能夠有效的防御攻擊。
![]()
1、當連續一段時間內去往目標Web服務器的HTTP GET請求報文超過告警閾值后,抗DDOS設備啟動源認證機制。源認證機制啟動后,抗DDOS設備將會代替服務器與客戶端建立TCP三次握手。
2、抗DDOS設備攔截HTTP請求,向客戶端返回驗證碼頁面,要求客戶端輸入驗證碼。
3、如果這個源是攻擊工具或僵屍主機,不會輸入驗證碼。
4、如果這個源是真實客戶端,則會輸入驗證碼並通過認證,抗DDOS設備將該客戶端的源IP地址加入白名單。然后抗DDOS設備會請客戶端繼續訪問一開始的URI。
5、后續這個客戶端發出的HTTP請求報文命中白名單直接通過。
下面給出了抗DDOS設備向客戶端返回的驗證碼頁面的報文,以及對應的實際頁面:
![]()
驗證碼認證方式與302認證方式相比,防御效果更好,但是由於需要人機交互輸入驗證碼,用戶體驗稍差一些。在實際使用驗證碼認證方式時,可以增加源IP統計的環節,即抗DDOS設備先基於目的IP進行統計,當去往某個目的IP的HTTP請求超過閾值時,啟動基於源IP的統計。當來自某個源的HTTP請求也超過閾值時,才啟動驗證碼認證機制。這樣就會精確控制需要進行驗證碼認證的源IP范圍,避免大范圍的源IP都要輸入驗證碼。
302重定向認證和驗證碼認證這兩種源認證方式是防御HTTP GET Flood攻擊的有效手段,但是源認證方式也存在一定的局限,比如機頂盒視頻點播、特定移動網絡等場景中,無法對客戶端使用源認證方式。為此,有的抗D設備還支持URI動態指紋學習和URI行為監測防御方式,作為源認證方式的補充,滿足不同場景的需求。
URI動態指紋學習
URI動態指紋學習方式適用於攻擊源訪問的URI比較固定的情況,因為要形成攻擊效果,攻擊者一般都會以容易消耗系統資源的URI作為攻擊目標。一個攻擊源會發出多個針對該URI的請求,最終呈現為該源對特定的URI發送大量的請求報文。
基於這個原理,抗D設備對客戶端所訪問的URI進行指紋學習,找到攻擊目標URI指紋。在一定的周期內,當同一個源發出的包含同一指紋的請求超過設置的閾值時,就將該源加入黑名單。
URI行為監測
URI行為監測防御方式要先設置需要重點監測的URI,可以將消耗資源多、容易受到攻擊的URI加入到“重點監測URI”列表中。URI行為監測防御方式通過判斷兩個比例是否超過閾值來確定攻擊源。
首先,在特定時間內對某個目的服務器的所有訪問中,對重點監測URI的訪問數與總訪問數的比例超過設置的閾值時,抗D設備啟動針對源的URI檢測。當這個源對某個重點檢測URI的訪問數與總訪問數的比例超過設置的閾值時,就將該源加入黑名單。
攻擊者利用攻擊工具或者操縱僵屍主機,向目標服務器發起大量的HTTP POST報文,消耗服務器資源,使服務器無法響應正常請求,這就是HTTP POST Flood攻擊。
防御HTTP POST Flood攻擊與防御GET Flood攻擊類似,常用手段也是源認證,包括重定向認證和驗證碼認證。
重定向認證
抗D設備代替服務器向客戶端響應307狀態碼(針對POST請求方法的重定向),同時向客戶端的瀏覽器注入Cookie,客戶端再次發起請求時會在HTTP報頭上附加Cookie信息,抗D設備通過驗證Cookie信息的真實性來驗證客戶端。
![]()
1、當連續一段時間內去往目標Web服務器的HTTP POST請求報文超過告警閾值后,抗D設備啟動源認證機制。源認證機制啟動后,抗D設備將會代替服務器與客戶端建立TCP三次握手。
2、抗D設備攔截HTTP請求,代替Web服務器回應307狀態碼,並在響應頭部附加上由客戶端IP生成的Cookie。
3、如果這個源是虛假源,或者不支持完整HTTP協議棧的攻擊工具,不會重新發起請求。
4、如果這個源是真實客戶端,抗D設備生成的Cookie會寫入到瀏覽器中,並且客戶端會重新發起請求,請求頭部就會帶有該Cookie信息。抗D設備收到請求后,驗證Cookie是否正確,如果正確則將該客戶端的源IP地址加入白名單。然后抗D設備會回應408狀態碼,表示請求超時,使客戶端重新發起訪問。
5、后續這個客戶端發出的HTTP請求報文命中白名單直接通過。
我們結合一組抓包信息來看一下交互報文的具體情況。
1、抗D設備代替Web服務器與客戶端建立TCP三次握手,然后客戶端發起訪問請求。
![]()
2、抗D設備代替Web服務器回應307狀態碼,同時在響應頭部附加上由客戶端IP生成的Cookie,然后雙方關閉連接。
![]()
3、真實客戶端會再次與抗D設備建立TCP三次握手,並且會重新發起請求,請求頭部就會帶有Cookie信息。
![]()
4、抗D設備收到請求后,通過驗證Cookie來判定該客戶端為真實客戶端,將其IP地址加入白名單。然后抗D設備會回應408狀態碼,表示請求超時,使客戶端重新發起訪問。
![]()
上面介紹的307重定向認證方式能夠很好地防御HTTP POST Flood攻擊,但是這種方式也具有一定的局限性。其一,依賴於客戶端瀏覽器的Cookie的機制,受安全級別限制。如果客戶端的瀏覽器安全級別較高而無法寫入Cookie,會導致認證不通過;其二,第一階段重定向結束后,需要客戶端再次手動執行提交等操作,才能重新發起POST請求。
同HTTP GET Flood的防御方式相似,HTTP POST Flood的源認證防御也支持增強方式,即驗證碼認證。
驗證碼認證
此處的驗證碼認證與HTTP GET Flood中的驗證碼機制相同,抗D設備要求客戶端輸入驗證碼,以此來判斷請求是否由真實的用戶發起。其弊端也是需要人機交互輸入驗證碼,用戶體驗稍差一些。具體的工作原理請參考HTTP GET Flood攻擊與防御部分中的介紹,此處不再贅述。
URI動態指紋學習和URI行為監測
防御HTTP POST Flood攻擊時,也可以使用URI動態指紋學習和URI行為監測防御方式,作為源認證方式的補充,滿足不同場景的需求。其防御原理我們在上面的HTTP GET Flood攻擊與防御部分中已經介紹過,在此也不贅述了。
HTTP慢速攻擊是利用HTTP協議的正常交互機制,先與目標服務器建立一個連接,然后長時間保持該連接不釋放。如果攻擊者持續與目標服務器建立這樣的連接,就會使目標服務器上的可用資源耗盡,無法提供正常服務。
HTTP慢速攻擊主要包括針對HTTP請求報文頭部結束符的Slow Headers攻擊,以及針對POST請求報文數據長度的Slow POST攻擊。
Slow Headers
HTTP請求頭部的后面會存在一個空行(結束符),其中包括回車符和換行符,告知服務器請求頭部結束,后面不再有請求頭。如果服務器沒有收到這個空行則會一直保持連接。
Slow Headers攻擊正是利用這一點,攻擊者使用GET或POST請求方法與目標服務器建立連接,然后持續發送不包含結束符的HTTP頭部報文,目標服務器會一直等待請求頭部中的結束符而導致連接始終被占用。如果攻擊者控制大量的僵屍主機向目標服務器發起這種攻擊,將會導致服務器資源耗盡,無法正常提供服務。
![]()
如下圖所示,正常的HTTP報文中請求頭部的后面會有結束符0x0d0a(\r\n的十六進制表示方式),而攻擊報文中不包含結束符,並且攻擊者會持續發送不包含結束符的HTTP頭部報文,維持連接狀態,消耗目標服務器的資源。
![]()
Slow Headers攻擊行為的特征比較明顯,解決方案防御Slow Headers攻擊,會對HTTP報文進行檢查。如果發現某個源發出的連續多個HTTP GET/POST請求報文的報文頭中都沒有結束符“\r\n”,則認為發生Slow Headers攻擊,將該源IP地址加入黑名單。
Slow POST
Slow POST攻擊利用的是POST請求方法,攻擊者向目標服務器發送POST請求報文提交數據,數據的長度設置為一個很大的數值,但是在隨后的數據發送中,每次只發送很小的報文,這樣就是導致目標服務器一直等待攻擊者發送數據。如果攻擊者控制大量的僵屍主機向目標服務器發起這種攻擊,將會導致服務器資源耗盡,無法正常提供服務。
![]()
如下圖所示,Slow POST攻擊報文中,POST請求頭部的Content-Length關鍵字的值設置為8192,表示數據長度為8192字節,但是攻擊者后續每次只發送1個字節的報文,導致連接一直被占用,消耗了服務器的資源。
![]()
防御Slow POST攻擊時,防御方法也是對HTTP報文進行檢查。如果發現某個源發出的連續多個HTTP POST請求報文的長度設置的很大,但是實際報文的數據部分長度都很小,則認為發生Slow POST攻擊,將該源IP地址加入黑名單。
