CC攻击的基本原理
CC攻击利用代理服务器向网站发送大量需要较长计算时间的URL请求,如数据库查询等,导致服务器进行大量计算而很快达到自身的处理能力而形成DOS。而攻击者一旦发送请求给代理后就主动断开连接,因为代理并不因为客户端这边连接的断开就不去连接目标服务器。因此攻击机的资源消耗相对很小,而从目标服务器看来,来自代理的请求都是合法的。
以前防CC攻击的方法
为防范CC,以前的方法一个是限制每个IP的连接数,这在地址范围很广阔的情况下比较难实现;二是限制代理的访问,因为一般的代理都会在HTTP头中带 X_FORWARDED_FOR字段,但也有局限,有的代理的请求中是不带该字段的,另外有的客户端确实需要代理才能连接目标服务器,这种限制就会拒绝一些正常用户访问。
CC攻击用硬防难防住
CC攻击比DDOS攻击更可怕的就是,CC攻击一般是硬防很难防止住的。 原因有三:
- 因为CC攻击来的IP都是真实的,分散的;
- CC攻击的数据包都是正常的数据包;
- CC攻击的请求,全都是有效的请求,无法拒绝的请求。
防CC攻击思路
- 判断UserAgent是否为刷机黑名单ua,如果是则不响应请求,例如curl的ua是curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2,正常浏览器不会有这种ua
- 防CC有效性在于攻击方不接受服务器回应的数据,发送完请求后就主动断开连接,因此要确认连接是否是CC,服务器端不立即执行URL请求命令,而是简单的返回一个页面转向的回应(示例代码如下),回应中包含新的URL请求地址。如果是正常访问,客户端会主动再次连接到转向页面,对用户来说是透明的;而对于CC攻击者,由于不接收回应数据,因此就不会重新连接,服务器也就不需要继续进行操作。 注意:此操作会影响SEO
具体实现
具体实现的关键在于转向的URL如何构造,kangle设计的方法是增加一个“值”,即在原URL请求的最后面添加一个独一无二的值,文本形式,作为URL的一部分;当包含该值的URL重新返回时,先检查该值是否合法。如果合法,则说明该URL是合法的再次连接,将URL中的值部分抹去,恢复为原始的URL请求再发给服务器进行正常访问;否则拒绝该URL请求。 “值”可以千变万化的设置,非常灵活。用户可以根据需要进行设定。
- 示例代码(腾讯云)
<script>
var a = [];a.push("231367");a.push("9183");a=a.join("");document.cookie="__tst_cookieid="+a+"#;";setTimeout("location.href=location.href.replace(/[?|&]tads/, '')", 1400);
</script>
- 示例代码(金盾)
<html>
<body>
<script>
function decoder() {
var ekt = new Array(23,176,27,140,191,88,47,133,110,99,69,243,180,124,69,112,250,148,98,106,14,116,178);
var fbab=4;
do {
ekt[fbab]=((((ekt[fbab]+133)&0xff)<<6)&0xff)|(((ekt[fbab]+133)&0xff)>>2);
ekt[fbab]=(ekt[fbab]-ekt[20])&0xff;
} while(++fbab<=18);
var fbab=1;
while (fbab<=18) {
ekt[fbab]=(~((ekt[fbab]-ekt[fbab+1])&0xff))&0xff;
fbab++;
}
var fbab=2;
while (true) {
if(fbab>19)
break;
ekt[fbab]=(ekt[fbab]^ekt[22])^94;
ekt[fbab]=(-ekt[fbab])&0xff;
fbab++;
}
return String.fromCharCode(ekt[1],ekt[2],ekt[3],ekt[4],ekt[7],ekt[9],ekt[10],ekt[11],ekt[15],ekt[16],ekt[18],ekt[19],ekt[21]);
}
window.location="http://www.xxx.com/?"+decoder();
</script>
<br><br>
<center><h3>Ҫ֧vaScript</h3></center>
</body>
</html>
- 示例代码(百度云)
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<title>安全检查中...</title>
<style type="text/css">
html, body {width: 100%; height: 100%; margin: 0; padding: 0;}
body {background-color: #ffffff; font-family: Helvetica, Arial, sans-serif; font-size: 100%;}
h1 {font-size: 1.5em; color: #404040; text-align: center;}
p {font-size: 1em; color: #404040; text-align: center; margin: 10px 0 0 0;}
#spinner {margin: 0 auto 30px auto; display: block;}
.attribution {margin-top: 20px;}
@-webkit-keyframes bubbles { 33%: { -webkit-transform: translateY(10px); transform: translateY(10px); } 66% { -webkit-transform: translateY(-10px); transform: translateY(-10px); } 100% { -webkit-transform: translateY(0); transform: translateY(0); } }
@keyframes bubbles { 33%: { -webkit-transform: translateY(10px); transform: translateY(10px); } 66% { -webkit-transform: translateY(-10px); transform: translateY(-10px); } 100% { -webkit-transform: translateY(0); transform: translateY(0); } }
.bubbles { background-color: #404040; width:15px; height: 15px; margin:2px; border-radius:100%; -webkit-animation:bubbles 0.6s 0.07s infinite ease-in-out; animation:bubbles 0.6s 0.07s infinite ease-in-out; -webkit-animation-fill-mode:both; animation-fill-mode:both; display:inline-block; }
</style>
<script type="text/javascript">
//<![CDATA[
(function(){
var a = function() {try{return !!window.addEventListener} catch(e) {return !1} },
b = function(b, c) {a() ? document.addEventListener("DOMContentLoaded", b, c) : document.attachEvent("onreadystatechange", b)};
b(function(){
var a = document.getElementById('yjs-content');a.style.display = 'block';
setTimeout(function(){
var t,r,a,f, OCTRBBd={"WdocSF":+((!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]))};
t = document.createElement('div');
t.innerHTML="<a href='/'>x</a>";
t = t.firstChild.href;r = t.match(/https?:\/\//)[0];
t = t.substr(r.length); t = t.substr(0,t.length-1);
a = document.getElementById('jschl-answer');
f = document.getElementById('challenge-form');
;OCTRBBd.WdocSF*=+((+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]));OCTRBBd.WdocSF*=+((!+[]+!![]+[])+(+[]));OCTRBBd.WdocSF*=!+[]+!![]+!![]+!![];OCTRBBd.WdocSF+=+((!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]));OCTRBBd.WdocSF*=!+[]+!![];a.value = parseInt(OCTRBBd.WdocSF, 10) + t.length;
f.submit();
}, 4000);
}, false);
})();
//]]>
</script>
</head>
<body>
<table width="100%" height="100%" cellpadding="20">
<tr>
<td align="center" valign="middle">
<div class="yjs-browser-verification yjs-im-under-attack">
<noscript><h1 data-translate="turn_on_js" style="color:#bd2426;">请打开游览器的javascript,然后刷新游览器</h1></noscript>
<div id="yjs-content" style="display:none">
<div>
<div class="bubbles"></div>
<div class="bubbles"></div>
<div class="bubbles"></div>
</div>
<h1><span data-translate="checking_browser">浏览器安全检查中…</span> wkhost.cn.</h1>
<p data-translate="process_is_automatic"></p>
<p data-translate="allow_5_secs">还剩 5 秒…</p>
</div>
<form id="challenge-form" action="/cdn-cgi/l/chk_jschl" method="get">
<input type="hidden" name="jschl_vc" value="8849cb50b7f8a83ca8599f8c39a7e871"/>
<input type="hidden" name="pass" value="1436500403.491-OXA9kGzi8b"/>
<input type="hidden" id="jschl-answer" name="jschl_answer"/>
</form>
</div>
<div class="attribution">
<a href="http://yunjiasu.baidu.com/" target="_blank" style="font-size: 12px;">百度云加速防护中</a>
<br>
Event ID: 20395228dba91c40
</div>
</td>
</tr>
</table>
</body>
</html>
- 根据请求量的阈值设定,如果超过阈值,则用iptables封ip,注意:阈值的设定大小,有可能封掉正常访问用户的ip
- 人工干预,发现哪些网站或者IP请求量大的,直接封网站或者iptables封ip