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