■ 河南 許紅軍
編者按:從原理上說,CC(Challenge Collapsar)攻擊是DDoS 攻擊的一種,其針對目標(biāo)系統(tǒng)消耗資源較大的頁面不斷發(fā)起連接請求。造成對方服務(wù)器資源耗盡為止。CC 攻擊讓用戶無法查看真實(shí)的源IP,不易察覺到特別大的異常流量,但會造成服務(wù)器無法進(jìn)行正常連接,危害性非常大。
CC 攻擊實(shí)質(zhì)上屬于HTTP Flood 類型的攻擊,專門針對Web 的應(yīng)用層發(fā)起Flood 攻 擊。黑客操縱網(wǎng)絡(luò)上受控制的主機(jī),對目標(biāo)Web 服務(wù)器進(jìn)行巨量的HTTP REQUEST連接請求,直到服務(wù)器帶寬被徹底占滿,造成拒絕服務(wù)。
CC 攻擊在HTTP 層發(fā)起,它極力模仿正常用戶的網(wǎng)頁請求行為,與網(wǎng)站業(yè)務(wù)緊密相關(guān),CC 攻擊不僅會造成網(wǎng)站前端響應(yīng)緩慢,甚至還會間接對后端的Java 等業(yè)務(wù)層邏輯,以及數(shù)據(jù)庫和存儲服務(wù)造成不利影響。
對于采用靜態(tài)頁面的網(wǎng)站來說,正常的訪問是不會消耗過多資源的。但動態(tài)網(wǎng)站情況就不一樣了。例如,對于論壇來說,當(dāng)查看某個條目時,網(wǎng)站程序就需要到數(shù)據(jù)庫中判斷該用戶是否有讀帖子的權(quán)限,如果有就讀取相關(guān)的內(nèi)容并顯示出來,如果沒有則不顯示。這樣,就會多次訪問數(shù)據(jù)庫,并執(zhí)行搜索操作。如果訪問的用戶很多,打開頁面的速度自然會比較慢。
在網(wǎng)站中搜索特定內(nèi)容時,程序往往會對后臺數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行一次遍歷查詢,自然消耗很長的時間。CC 攻擊就是充分利用了上述特點(diǎn),黑客通過一些手段控制了很多網(wǎng)絡(luò)主機(jī),用以模擬真實(shí)用戶,不停地對目標(biāo)網(wǎng)站進(jìn)行訪問,訪問那些需要大量數(shù)據(jù)查詢的操作。這種大量并發(fā)請求操作對網(wǎng)站的正常運(yùn)行威脅很大。
為了判斷是否遭到CC 攻擊,還需進(jìn)一步加以確認(rèn)。對于Web 網(wǎng)站來說,為了維護(hù)其正常運(yùn)行,使用Zabbix等工具對CPU、內(nèi)存、磁盤及帶寬流量等重要指標(biāo)進(jìn)行監(jiān)控是很有必要的,并利用動態(tài)趨勢圖隨時查看其狀態(tài)。當(dāng)出現(xiàn)網(wǎng)站無法訪問時,首先應(yīng)該查看監(jiān)控趨勢圖,了解CPU、內(nèi)存、磁盤以及流量等有無異常。
例如,對于網(wǎng)卡流量來說,當(dāng)遭遇到CC 攻擊時,會導(dǎo)致請求量變大,造成入口流量變大,相應(yīng)地出口流量也會變大。在服務(wù)器上執(zhí)行“sar -n DEV 1 10”命令,在返回信息中對外網(wǎng)網(wǎng)卡進(jìn)行重點(diǎn)分析,其中的“rxpcks”列為入包數(shù)量,“txpck/s”列為出包數(shù)量,“rxKB/s”列為入口流量,入口流量單位是千字節(jié)/秒,“txKB/s”列為出口流量。如果存在CC 攻 擊,那么入口流量會變大。
此外,使用“nload”命令,可實(shí)時查看Linux 網(wǎng)絡(luò)流量狀況,它實(shí)質(zhì)上是一個控制臺應(yīng)用程序,用來實(shí)時監(jiān)測網(wǎng)絡(luò)流量和帶寬使用情況。執(zhí)行“yum install gcc gcc-c++ ncurses-devel”命令,安裝所需的軟件包。執(zhí)行以下命令來安裝該工具:
tar zxvf nload-0.7. 4.tar.gz
cd nload-0.7.4
./configure
make
make install
執(zhí)行“nload”命令,之后點(diǎn)擊向右方向鍵來切換網(wǎng)卡,在“Incoming”欄中顯示入口流量,在“Outgoing”欄中顯示出口流量,并可以顯示出口和入口的當(dāng)前、平均、最大等流量信息。
當(dāng)客戶訪問服務(wù)器時,必然會在服務(wù)器上產(chǎn)生相應(yīng)的日志。CC 攻擊也會被日志完整記錄下來。當(dāng)網(wǎng)站訪問變得緩慢,通過對網(wǎng)卡流量進(jìn)行查看,如果發(fā)現(xiàn)網(wǎng)卡流量變大,則基本上能確定遭到網(wǎng)絡(luò)攻擊。對日志進(jìn)行查看,可以進(jìn)一步加以確定。因?yàn)镃C 攻擊雖然極力模仿正常請求行為,但其來源IP 比較固定,即對同一個IP 地址來說請求量很大,而且其請求的鏈接為固定的一個或幾個,在訪問日志里就顯得格外特殊,另外其客戶端的User-Agent 比較固定。
利用這些特點(diǎn),很容易在訪問日志中獲取相關(guān)線索。例如,執(zhí)行“tail /usr/local/apache2.x/logs/phpems.com-access_log”之類的命令,在日志信息中如果發(fā)現(xiàn)符合上述條件的信息,就需要警惕了。
如果沒有記錄日志的話,也可以利用系統(tǒng)內(nèi)置的“tshark”命令,來執(zhí)行抓包操作,來獲取相關(guān)信息。例如,執(zhí)行“tshark -i em2 -n -t a -R http.request -T fields -e "frame.time" -e "ip.src" -e "http.host" -e "http.request.method" -e "http.request.uri"”命令,在獲取的信息中動態(tài)顯示時間、訪問者源IP、網(wǎng)址、具體路徑等內(nèi)容,從中不難發(fā)現(xiàn)有用的線索。
當(dāng)然,還可以使用“Tcp dump”命令來抓取數(shù)據(jù)包。例如,執(zhí)行“tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F“?!薄畕print $1“?!?2“?!?3“?!?4}’ | sort | uniq -c | sort -nr |head -20”命 令,來探測TCP 80 端口的訪問量,對于訪問量過高的訪問者要加以注意。執(zhí)行“netstat -nat|grep -i "80"|wc -l”命令,查看所有TCP 80 端口的連接數(shù)。執(zhí) 行“netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n10” “netstat -ant |awk '/: 80/{split ($5, ip, ":"); ++A [ip [1] ]}END{for (i in A) print A,i}' | sort -rn|head -n 10”命令,對TCP 80 連接數(shù)量最大的前10 個IP 進(jìn)行排序。執(zhí)行“netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n”命令,對連接的IP 按連接數(shù)量進(jìn)行排序。
然后執(zhí)行諸如“netstat -nat |awk '{print $6}' |sort|uniq -c|sort -rn” “netstat -n | awk '/^tcp/ {++S [$NF] }; END {for (a in S) print a, S [a] }'” “netstat -n | awk '/^tcp/ {++state [$NF] }; END {for(key in state) print key," ",state [key] }'” “netstat -n | awk '/^tcp/ {++arr [$NF] };END {for (k in arr) print k, " ", arr [k] }'” “netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn” “netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c” 等命令,來查看TCP 不同的連接狀態(tài)。
執(zhí)行“netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n10”命令,對狀態(tài)處于“Time_Wait”狀態(tài)的前10 個連接進(jìn)行排序。執(zhí)行“netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more”命令,顯示較多的SYN 連接。
面對狡猾的CC 攻擊,我們需要采取各種方法進(jìn)行防御,最簡單的方法是封鎖攻擊者的IP。利用Linux 自帶的防火墻就可以實(shí)現(xiàn),例如,執(zhí)行“iptables -I INPUT -s x.x.x.x -j DROP”命令,即可封鎖指定為“x.x.x.x”的IP。執(zhí)行“iptables -I INPUT -s x.x.x.0 /16 -j DROP”命令,可以封鎖以“x.x.x”開頭的IP 段。執(zhí)行“iptables -I INPUT -s x.0.0.0/8 -j DROP”命令,可以封鎖指定的整個IP 段。
也可以在Web 服務(wù)器上進(jìn)行封鎖。例如,對于LNMP架構(gòu)來說,可以在Nginx 的虛擬主機(jī)配置文件中增加“deny x.x.x.x;”行,禁止指定的IP 訪問。
當(dāng)然,利用Netfilter 防火墻進(jìn)行攔截效果要好一些,不會對Web 服務(wù)器造成任何壓力。CC 攻擊的特點(diǎn)就是會在短時間內(nèi)發(fā)送大量的請求給服務(wù)器上,請求頻率很快。因此,只需將請求頻率較快用戶進(jìn)行限速,就可以有效的防御CC 攻擊。
例 如,執(zhí) 行“iptables -A INPUT -p tcp --dport 80 -m limit --limit 500/s --limit-burst 1000 -j ACCEPT# iptables -A INPUT -p tcp --dport 80 -j DROP”命令,只允許每秒發(fā)送500 個數(shù)據(jù)包,突發(fā)傳輸最多允許1 000 個數(shù)據(jù)包進(jìn)行傳輸隊(duì)列,超過上述該限制的數(shù)據(jù)包則丟棄掉。
利用Nginx的限制功能也可以有效控制并發(fā)連接的數(shù)量。打開其配置文件“nginx.conf”,在“http{}”部分添加“l(fā)imit_req_zone $binary_remote_addr zone=xsqu:10m rate=1r/s;”,在“server{}”部分輸入“l(fā)imit_req zone= xsqu burst=5;”行,作用是在“l(fā)imit_req_zone”中設(shè)置一塊共享內(nèi)存限制區(qū)域,名稱為“xsqu”,大小為10 MB,用來保存鍵值的狀態(tài)參數(shù),鍵值是客戶端IP。
其中的“rate=1/s”表示限制客戶端每個IP 平均處理的請求頻率為1 秒1 次。這個值可以設(shè)置為每秒處理請求數(shù)或每分鐘處理請求數(shù),所以設(shè)置為“30 r/min”,則表示指定每2 s 處理一個請求?!發(fā)imit_req”參數(shù)用來指定Zone 下被允許放行的請求數(shù),將按照上述速率被限速。這里表示如前5 個請求需要排隊(duì),每秒放行1個,之后請求會被直接拒絕。
如果在此基礎(chǔ)上,只想讓指定的IP 訪問,禁止其他IP 訪問的話,可以在“http{}”部分添加:
geo $good_ip {
default 1;
x.x.x.1/32 0;
x.x.100.0/24 0;
}
map $good_ip $limit {
1 $binary_remote_addr;
0 "";
}
表示允許“x.x.x.1/32” “x.x.100.0/24”等IP 訪問Web 服務(wù)器,其余IP 將拒絕訪問。通過對日志的分析,可以了解到哪些URL 訪問很頻繁,哪個User-Agent 和Referer 比較密集等,針對這些對象進(jìn)行必要限制,可以有效抵御CC 攻擊。
例 如,在Nginx 配 置文件中添加“if ($request_uri ~ 'xxx=')” “{ return 403;}”行,可以限制針對指定的URL 的訪問,其中的“xxx”為具體的URL 地址。添加“if ($http_user_agent ~ '^Mozilla/5.0$|^$')” “{ return 403;}”行,那么當(dāng)用戶的User-Agent 的值為空或?yàn)橹付ǖ念愋蜁r,則禁止訪問。添加“if ($http_referer ~ 'http://xxx'” “{ return 403;}”行,可以限制指定的Referer。
目前針對CC 攻擊的防御主要通過緩存的方式加以處理,即盡量讓緩存數(shù)據(jù)直接返回結(jié)果,這樣可以有效保護(hù)后端業(yè)務(wù)。大型的互聯(lián)網(wǎng)企業(yè)會有龐大的CDN 節(jié)點(diǎn)來緩存內(nèi)容,而當(dāng)攻擊者穿透緩存時,會通過清洗設(shè)備截獲HTTP 請求做特殊處理。最簡單的方法就是對源IP的HTTP 請求頻率做統(tǒng)計(jì),高于一定頻率的IP 地址直接加入黑名單。當(dāng)然該方法過于簡單,很容易造成錯誤攔截。對于來自代理服務(wù)器的攻擊無法進(jìn)行有效屏蔽。
取而代之的是JavaScript跳轉(zhuǎn)人機(jī)識別機(jī)制,因?yàn)镠TTP Flood 是由攻擊程序模擬HTTP 請求,一般不會解析服務(wù)端返回?cái)?shù)據(jù),更不會解析JS 之類代碼。因此,當(dāng)清洗設(shè)備截獲到HTTP 請求時,會返回一段特殊JavaScript代碼,正常用戶的瀏覽器會處理并正常跳轉(zhuǎn)不影響使用,而對于攻擊程序來說,只能是無功而返。
實(shí)際上,CC 等基于DDoS方式的攻擊是比較難于防御的,并沒有很完美的解決方法。對于安全人員來說,早發(fā)現(xiàn)、早預(yù)防是較好的應(yīng)對策略。例如,接入主流CDN,把自己的真實(shí)IP 隱藏起來。如果不接入CDN 的話,可以安裝專業(yè)的防護(hù)盾。此外,還可以配置專業(yè)防火墻設(shè)備,將整個內(nèi)網(wǎng)保護(hù)起來,可以有效防御包括CC 攻擊在內(nèi)的各種安全威脅和安全漏洞。