一、 CC攻擊的原理:
CC攻擊的原理就是攻擊者控制某些主機不停地發大量數據包給對方服務器造成服務器資源耗盡,一直到宕機崩潰。CC主要是用來消耗服務器資源的,每個人都有這樣的體驗:當一個網頁訪問的人數特別多的時候,打開網頁就慢了,CC就是模擬多個用戶(多少線程就是多少用戶)不停地進行訪問那些需要大量數據操作(就是需要大量CPU時間)的頁面,造成服務器資源的浪費,CPU長時間處于100%,永遠都有處理不完的連接直至就網絡擁塞,正常的訪問被中止。
二、CC攻擊的種類:
CC攻擊的種類有三種,直接攻擊,代理攻擊,僵尸網絡攻擊,直接攻擊主要針對有重要缺陷的 WEB 應用程序,一般說來是程序寫的有問題的時候才會出現這種情況,比較少見。僵尸網絡攻擊有點類似于 DDoS 攻擊了,從 WEB 應用程序層面上已經無法防御,所以代理攻擊是CC 攻擊者一般會操作一批代理服務器,比方說 100 個代理,然后每個代理同時發出 10 個請求,這樣 WEB 服務器同時收到 1000 個并發請求的,并且在發出請求后,立刻斷掉與代理的連接,避免代理返回的數據將本身的帶寬堵死,而不能發動再次請求,這時 WEB 服務器會將響應這些請求的進程進行隊列,數據庫服務器也同樣如此,這樣一來,正常請求將會被排在很后被處理,就象本來你去食堂吃飯時,一般只有不到十個人在排隊,今天前面卻插了一千個人,那么輪到你的機會就很小很小了,這時就出現頁面打開極其緩慢或者白屏。
三、CC攻擊與DDOS的區別
1) 什么是DDoS攻擊?
DDoS攻擊就是分布式的拒絕服務攻擊,DDoS攻擊手段是在傳統的DoS攻擊基礎之上產生的一類攻擊方式。單一的DoS攻擊一般是采用一對一方式的,隨著計算機與網絡技術的發展,DoS攻擊的困難程度加大了。于是就產生了DDoS攻擊,它的原理就很簡單:計算機與網絡的處理能力加大了10倍,用一臺攻擊機來攻擊不再能起作用,那么DDoS就是利用更多的傀儡機來發起進攻,以比從前更大的規模來進攻受害者。常用的DDoS軟件有:LOIC。
在這里補充兩點:第一就是DDOS攻擊不僅能攻擊計算機,還能攻擊路由器,因為路由器是一臺特殊類型的計算機;第二是網速決定攻擊的好和快,比如說,如果你一個被限制網速的環境下,它們的攻擊效果不是很明顯,但是快的網速相比之下更加具有攻擊效果。
2)什么是CC攻擊?
3)兩者區別
DDoS是針對IP的攻擊,而CC攻擊的是服務器資源。
四、CC攻擊的變異品種 慢速攻擊
1)什么是慢速攻擊
一說起慢速攻擊,就要談談它的成名歷史了。HTTP Post慢速DoS攻擊第一次在技術社區被正式披露是2012年的OWASP大會上,由Wong Onn Chee 和 Tom Brennan共同演示了使用這一技術攻擊的威力。
這個攻擊的基本原理如下:對任何一個開放了HTTP訪問的服務器HTTP服務器,先建立了一個連接,指定一個比較大的content-length,然后以非常低的速度發包,比如1-10s發一個字節,然后維持住這個連接不斷開。如果客戶端持續建立這樣的連接,那么服務器上可用的連接將一點一點被占滿,從而導致拒絕服務。
和CC攻擊一樣,只要Web服務器開放了Web服務,那么它就可以是一個靶子,HTTP協議在接收到request之前是不對請求內容作校驗的,所以即使你的Web應用沒有可用的form表單,這個攻擊一樣有效。
在客戶端以單線程方式建立較大數量的無用連接,并保持持續發包的代價非常的低廉。實際試驗中一臺普通PC可以建立的連接在3000個以上。這對一臺普通的Web server,將是致命的打擊。更不用說結合肉雞群做分布式DoS了。
鑒于此攻擊簡單的利用程度、拒絕服務的后果、帶有逃逸特性的攻擊方式,這類攻擊一炮而紅,成為眾多攻擊者的研究和利用對象。
2)慢速攻擊的分類
發展到今天,慢速攻擊也多種多樣,其種類可分為以下幾種:
Slow headers:Web應用在處理HTTP請求之前都要先接收完所有的HTTP頭部,因為HTTP頭部中包含了一些Web應用可能用到的重要的信息。攻擊者利用這點,發起一個HTTP請求,一直不停的發送HTTP頭部,消耗服務器的連接和內存資源。抓包數據可見,攻擊客戶端與服務器建立TCP連接后,每30秒才向服務器發送一個HTTP頭部,而Web服務器再沒接收到2個連續的rn時,會認為客戶端沒有發送完頭部,而持續的等等客戶端發送數據。
Slow body:攻擊者發送一個HTTP POST請求,該請求的Content-Length頭部值很大,使得Web服務器或代理認為客戶端要發送很大的數據。服務器會保持連接準備接收數據,但攻擊客戶端每次只發送很少量的數據,使該連接一直保持存活,消耗服務器的連接和內存資源。抓包數據可見,攻擊客戶端與服務器建立TCP連接后,發送了完整的HTTP頭部,POST方法帶有較大的Content-Length,然后每10s發送一次隨機的參數。服務器因為沒有接收到相應Content-Length的body,而持續的等待客戶端發送數據。
Slow read:客戶端與服務器建立連接并發送了一個HTTP請求,客戶端發送完整的請求給服務器端,然后一直保持這個連接,以很低的速度讀取Response,比如很長一段時間客戶端不讀取任何數據,通過發送Zero Window到服務器,讓服務器誤以為客戶端很忙,直到連接快超時前才讀取一個字節,以消耗服務器的連接和內存資源。抓包數據可見,客戶端把數據發給服務器后,服務器發送響應時,收到了客戶端的ZeroWindow提示(表示自己沒有緩沖區用于接收數據),服務器不得不持續的向客戶端發出ZeroWindowProbe包,詢問客戶端是否可以接收數據。
使用較多的慢速攻擊工具有:Slowhttptest和Slowloris。
3)哪些服務器易被慢速攻擊
慢速攻擊主要利用的是thread-based架構的服務器的特性,這種服務器會為每個新連接打開一個線程,它會等待接收完整個HTTP頭部才會釋放連接。比如Apache會有一個超時時間來等待這種不完全連接(默認是300s),但是一旦接收到客戶端發來的數據,這個超時時間會被重置。正是因為這樣,攻擊者可以很容易保持住一個連接,因為攻擊者只需要在即將超時之前發送一個字符,便可以延長超時時間。而客戶端只需要很少的資源,便可以打開多個連接,進而占用服務器很多的資源。
經驗證,Apache、httpd采用thread-based架構,很容易遭受慢速攻擊。而另外一種event-based架構的服務器,比如Nginx和lighttpd則不容易遭受慢速攻擊。
4)如何防護慢速攻擊
Apache服務器現在使用較多的有三種簡單防護方式。
mod_reqtimeout:Apache2.2.15后,該模塊已經被默認包含,用戶可配置從一個客戶端接收HTTP頭部和HTTPbody的超時時間和最小速率。如果一個客戶端不能在配置時間內發送完頭部或body數據,服務器會返回一個408REQUEST TIME OUT錯誤。配置文件如下:
< IfModule mod_reqtimeout.c > RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500 < /IfModule >
mod_qos:Apache的一個服務質量控制模塊,用戶可配置各種不同粒度的HTTP請求閾值,配置文件如下:
< IfModule mod_qos.c > /# handle connections from up to 100000 different IPs QS_ClientEntries 100000 /# allow only 50 connections per IP QS_SrvMaxConnPerIP 50 /# limit maximum number of active TCP connections limited to 256 MaxClients 256 /# disables keep-alive when 180 (70%) TCP connections are occupied QS_SrvMaxConnClose 180 /# minimum request/response speed (deny slow clients blocking the server, keeping connections open without requesting anything QS_SrvMinDataRate 150 1200 < /IfModule >
mod_security:一個開源的WAF模塊,有專門針對慢速攻擊防護的規則,配置如下:
SecRule RESPONSE_STATUS “@streq 408” “phase:5,t:none,nolog,pass, setvar:ip.slow_dos_counter=+1, expirevar:ip.slow_dos_counter=60, id:’1234123456′”
SecRule IP:SLOW_DOS_COUNTER “@gt 5” “phase:1,t:none,log,drop,
msg:’Client Connection Dropped due to high number of slow DoS alerts’, id:’1234123457′”
傳統的流量清洗設備針對CC攻擊,主要通過閾值的方式來進行防護,某一個客戶在一定的周期內,請求訪問量過大,超過了閾值,清洗設備通過返回驗證碼或者JS代碼的方式。這種防護方式的依據是,攻擊者們使用肉雞上的DDoS工具模擬大量http request,這種工具一般不會解析服務端返回數據,更不會解析JS之類的代碼。因此當清洗設備截獲到HTTP請求時,返回一段特殊JAVAScript代碼,正常用戶的瀏覽器會處理并正常跳轉不影響使用,而攻擊程序會攻擊到空處。
而對于慢速攻擊來說,通過返回驗證碼或者JS代碼的方式依然能達到部分效果。但是根據慢速攻擊的特征,可以輔助以下幾種防護方式:1、周期內統計報文數量。一個TCP連接,HTTP請求的報文中,報文過多或者報文過少都是有問題的,如果一個周期內報文數量非常少,那么它就可能是慢速攻擊;如果一個周期內報文數量非常多,那么它就可能是一個CC攻擊。2、限制HTTP請求頭的最大許可時間。超過最大許可時間,如果數據還沒有傳輸完成,那么它就有可能是一個慢速攻擊。
簡單的Nginx防CC方式
實驗
Nginx配置
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { #限制每ip每秒不超過20個請求,漏桶數burst為5 #brust的意思就是,如果第1秒、2,3,4秒請求為19個, #第5秒的請求為25個是被允許的。 #但是如果你第1秒就25個請求,第2秒超過20的請求返回503錯誤。 #nodelay,如果不設置該選項,嚴格使用平均速率限制請求數, #第1秒25個請求時,5個請求放到第2秒執行, #設置nodelay,25個請求將在第1秒執行。 limit_req zone=one burst=1 nodelay; } }
上面樣本的配置是什么意思呢?
- $binary_remote_addr 表示:客戶端IP地址
- zone 表示漏桶的名字
- rate 表示nginx處理請求的速度有多快
- burst 表示峰值
- nodelay 表示是否延遲處理請求,還是直接503返回給客戶端,如果超出rate設置的情況下。
詳細的可以參考官方說明文檔:Module ngx_http_limit_req_module
模擬請求
這里我們需要Apache Benchmark這個小工具來生成請求
//1個用戶持續100s的時間向服務器發送請求 ab -t 100 -c 1 -vvv http://example.com/
Nginx配置樣本一
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { limit_req zone=one burst=1 nodelay; } }
ab測試結果如下所示:
數據 | 成功的請求數 | 失敗的請求數 | 請求時間 | 每秒成功的請求數 |
---|---|---|---|---|
1 | 100 | 19438 | 101.195 | 0.98 |
2 | 100 | 17651 | 100.655 | 0.99 |
3 | 97 | 25735 | 100.424 | 0.96 |
4 | 101 | 26791 | 100.000 | 1.01 |
5 | 98 | 19051 | 100.514 | 0.98 |
平均 | 99 | 21733.2 | 100.557 | 0.98 |
以上失敗的請求在Nginx上生成的錯誤日志如下顯示
2015/05/09 12:48:57 [error] 6564#0: *2219 limiting requests, excess: 1.273 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com" 2015/05/09 12:48:57 [error] 6564#0: *2220 limiting requests, excess: 1.272 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com" 2015/05/09 12:48:57 [error] 6564#0: *2221 limiting requests, excess: 1.271 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com" 2015/05/09 12:48:57 [error] 6564#0: *2222 limiting requests, excess: 1.270 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com" 2015/05/09 12:48:57 [error] 6564#0: *2223 limiting requests, excess: 1.269 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com" 2015/05/09 12:48:57 [error] 6564#0: *2224 limiting requests, excess: 1.268 by zone "one", client: 10.0.2.2, server: example.com, request: "GET / HTTP/1.0", host: "example.com"
如上ab測試中如果是失敗的請求,nginx的limit_req模塊會統一返回503給客戶端,瀏覽器上面顯示的是這個樣子的。
Nginx配置樣本二
在配置二里面,我把burst(峰值)提高到了10
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { limit_req zone=one burst=10 nodelay; } }
數據 | 成功的請求數 | 失敗的請求數 | 請求時間 | 每秒成功的請求數 |
---|---|---|---|---|
1 | 110 | 19042 | 100.144 | 1.09 |
2 | 111 | 22271 | 101.714 | 1.09 |
3 | 111 | 18466 | 100.504 | 1.10 |
4 | 111 | 16468 | 101.285 | 1.09 |
5 | 111 | 12770 | 100.596 | 1.10 |
平均 | 110 | 17803 | 100.788 |
1.09 |
從數據來看,提高了burst值,明顯nginx成功的請求數上去了。
Nginx配置樣本三
在樣本二的基礎上,我們把nodelay去除掉
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { limit_req zone=one burst=10; } }
數據 | 成功的請求數 | 失敗的請求數 | 請求時間 | 每秒成功的請求數 |
---|---|---|---|---|
1 | 96 | 0 | 100.223 | 1.09 |
2 | 98 | 0 | 100.238 | 0.97 |
3 | 100 | 0 | 100.761 | 0.99 |
4 | 96 | 0 | 100.074 | 0.95 |
5 | 97 | 0 | 100.021 | 0.96 |
平均 | 97.4 | 0 | 100.263 | 0.97 |
從這里的數據可以看到將nodelay的參數去掉的話,成功的請求數在100左右而失敗的請求數變成0了,為什么呢?
- 有nodelay參數的時候,nginx正常是及時處理當前的請求的并響應數據給客戶端,但是如果超過limit_req_module的限制,那么會統一返回503給客戶端。
- 無nodelay參數的時候,nginx正常是及時處理當前的請求的并響應數據給客戶端,但是如果超過limit_req_module的限制,那么會將此此請求緩存「就先這么理解」起來稍后再處理,所以也就不會出現大量的失敗請求數了。
存在的問題
雖然用limit_req_module可以一定上的防止CC攻擊,但是有誤殺概率;國內寬帶用戶的IP地址已經大量內網化,幾百人共享一個IP的可能性是很大的。
五、應用層DDoS的防御理論:
問題模型描述:
每一個頁面,都有其資源消耗權重,靜態資源,權重較低,動態資源,權重較高。對于用戶訪問,有如下:
用戶資源使用頻率=使用的服務器總資源量/s
命題一:對于正常訪問的用戶,資源使用頻率必定位于一個合理的范圍,當然會存在大量正常用戶共享ip的情況,這就需要日常用戶訪問統計,以得到忠實用戶ip白名單。
命題二:資源使用頻率持續異常的,可斷定為訪問異常的用戶。
防御體系狀態機:
1.在系統各項資源非常寬裕時,向所有ip提供服務,每隔一段時間釋放一部分臨時黑名單中的ip成員;
2.在系統資源消耗達到某一閾值時,降低Syn包接受速率,循環:分析最近時間的日志,并將訪問異常的ip加入臨時黑名單;
3.若系統資源消耗慢慢回降至正常水平,則恢復Syn包接受速率,轉到狀態1;若目前策略并未有效地控制住系統資源消耗的增長,情況繼續惡劣至一極限閾值,轉到狀態4;
4.最終防御方案,使用忠實用戶ip白名單、異常訪問ip黑名單策略,其他訪問可慢慢放入,直到系統資源消耗回降至正常水平,轉到狀態1。
上述的防御狀態機,對于單個攻擊IP高并發的DDOS,變化到狀態3時,效果就完全體現出來了,但如果防御狀態機進行到4狀態,則有如下兩種可能:
1.站點遭到了攻擊群龐大的、單個IP低并發的DDOS攻擊;
2.站點突然間有了很多訪問正常的新用戶。
六、建議后續工作:
保守:站點應盡快進行服務能力升級。
積極:盡所能,追溯攻擊者。
追溯攻擊者:
CC:proxy-forward-from-ip
單個IP高并發的DDOS:找到訪問異常的、高度可疑的ip列表,exploit,搜集、分析數據,因為一個傀儡主機可被二次攻占的概率很大(但不建議這種方法)
單個IP低并發的DDOS:以前極少訪問被攻擊站點,但是在攻擊發生時,卻頻繁訪問我們的站點,分析日志得到這一部分ip列表
追溯攻擊者的過程中,snat與web proxy增加了追蹤的難度,如果攻擊者采用多個中繼服務器的方法,追溯將變得極為困難。
防御者:
1.應對當前系統了如指掌,如系統最高負載、最高數據處理能力,以及系統防御體系的強項與弱點
2.歷史日志的保存、分析
3.對當前系統進行嚴格安全審計
4.上報公安相關部分,努力追溯攻擊者
5.網站,能靜態,就一定不要動態,可采取定時從主數據庫生成靜態頁面的方式,對需要訪問主數據庫的服務使用驗證機制。
6.防御者應能從全局的角度,迅速及時地發現系統正在處于什么程度的攻擊、何種攻擊,在平時,應該建立起攻擊應急策略,規范化操作,免得在急中犯下低級錯誤
對歷史日志的分析這時將會非常重要,數據可視化與統計學的方法將會很有益處:
1.分析每個頁面的平均訪問頻率
2.對訪問頻率異常的頁面進行詳細分析 分析得到ip-頁面訪問頻率
3.得到對訪問異常頁面的訪問異常ip列表
4.對日志分析得到忠實用戶IP白名單
5.一般一個頁面會關聯多個資源,一次對于這樣的頁面訪問往往會同時增加多個資源的訪問數,而攻擊程序一般不會加載這些它不感興趣的資源,所以,這也是一個非常好的分析突破點
防御思路
因為CC攻擊通過工具軟件發起,而普通用戶通過瀏覽器訪問,這其中就會有某些區別。想辦法對這二者作出判斷,選擇性的屏蔽來自機器的流量即可。
初級
普通瀏覽器發起請求時,除了要訪問的地址以外,Http頭中還會帶有Referer,UserAgent等多項信息。遇到攻擊時可以通過日志查看訪問信息,看攻擊的流量是否有明顯特征,比如固定的Referer或UserAgent,如果能找到特征,就可以直接屏蔽掉了。
中級
如果攻擊者偽造了Referer和UserAgent等信息,那就需要從其他地方入手。攻擊軟件一般來說功能都比較簡單,只有固定的發包功能,而瀏覽器會完整的支持Http協議,我們可以利用這一點來進行防御。
首先為每個訪問者定義一個字符串,保存在Cookies中作為Token,必須要帶有正確的Token才可以訪問后端服務。當用戶第一次訪問時,會檢測到用戶的Cookies里面并沒有這個Token,則返回一個302重定向,目標地址為當前頁面,同時在返回的Http頭中加入set cookies字段,對Cookies進行設置,使用戶帶有這個Token。
客戶端如果是一個正常的瀏覽器,那么就會支持http頭中的set cookie和302重定向指令,將帶上正確的Token再次訪問頁面,這時候后臺檢測到正確的Token,就會放行,這之后用戶的Http請求都會帶有這個Token,所以并不會受到阻攔。
客戶端如果是CC軟件,那么一般不會支持這些指令,那么就會一直被攔在最外層,并不會對服務器內部造成壓力。
高級
高級一點的,還可以返回一個網頁,在頁面中嵌入JavaScript來設置Cookies并跳轉,這樣被偽造請求的可能性更小
Token生成算法
Token需要滿足以下幾點要求
1,每個IP地址的Token不同
2, 無法偽造
3, 一致性,即對相同的客戶端,每次生成的Token相同
Token隨IP地址變化是為了防止通過一臺機器獲取Token之后,再通過代理服務區進行攻擊。一致性則是為了避免在服務器端需要存儲已經生成的Token。
推薦使用以下算法生成Token,其中Key為服務器獨有的保密字符串,這個算法生成的Token可以滿足以上這些要求。
Token = Hash( UserAgent + client_ip + key )
本文主要講述了DDoS攻擊之一的CC攻擊工具實現,以及如何防御來自應用層的DDoS攻擊的理論總結。接下來的文章,筆者將會實現一個工作于內核態的、具有黑名單功能的防火墻模塊,以對應于上述防御狀態機中的防火墻單元,它實現了自主地動態內存管理,使用hash表管理ip列表,并可以自定義hash表的modular。
七、 簡易CC攻擊防御策略
確定Web服務器正在或者曾經遭受CC攻擊,那如何進行有效的防范呢?
(1).取消域名綁定
一般cc攻擊都是針對網站的域名進行攻擊,比如我們的網站域名是“www.abc.com”,那么攻擊者就在攻擊工具中設定攻擊對象為該域名然后實施攻擊。 對于這樣的攻擊我們的措施是取消這個域名的綁定,讓CC攻擊失去目標。
(2).域名欺騙解析
如果發現針對域名的CC攻擊,我們可以把被攻擊的域名解析到127.0.0.1這個地址上。我們知道127.0.0.1是本地回環IP是用來進行網絡測試的,如果把被攻擊的域名解析到這個IP上,就可以實現攻擊者自己攻擊自己的目的,這樣他再多的肉雞或者代理也會宕機,讓其自作自受。
(3).更改Web端口
一般情況下Web服務器通過80端口對外提供服務,因此攻擊者實施攻擊就以默認的80端口進行攻擊,所以,我們可以修改Web端口達到防CC攻擊的目的。運行IIS管理器,定位到相應站點,打開站點“屬性”面板,在“網站標識”下有個TCP端口默認為80,我們修改為其他的端口就可以了。
(4).屏蔽IP
我們通過命令或在查看日志發現了CC攻擊的源IP,就可以在防火墻中設置屏蔽該IP對Web站點的訪問,從而達到防范攻擊的目的。