How does CloudFlare DDOS protection work?


New version: How does CloudFlare DDOS protection work? – Update 09/2016

I went to some website and saw the CloudFlare DDOS protection, pictured below:

cf ddos protection

I showed the source of that website:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Please wait 5 seconds...</title>
<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('cf-content');a.style.display = 'block';
      setTimeout(function(){
        var t,r,a,f, REbvZoy={"xwS":!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]};
        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');
        ;REbvZoy.xwS+=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=+((!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=!+[]+!![]+!![]+!![]+!![]+!![];REbvZoy.xwS+=+((+!![]+[])+(!+[]+!![]+!![]));REbvZoy.xwS-=+((!+[]+!![]+!![]+[])+(+[]));REbvZoy.xwS-=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS-=+((!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]));a.value = parseInt(REbvZoy.xwS, 10) + t.length;
        f.submit();
      }, 4000);
    }, false);
  })();
  //]]>
</script>

</head>
<body>
<div>
<div style="position: relative; height: 130px;">
<div style="max-width: 635px; margin: 0 auto; z-index: 1000; text-align: center;
                position: relative; margin-top: 150px; width: 100%">
<img id="imgLogo" alt="jadopado" style="display: inline-block;" src="data:image/gif; charset=binary;base64,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"><br />
</div>
</div>
<div>
<div style="text-align: center">
Please wait 5 seconds...<br />Make sure to enable cookies and javascript.<br />This site does not work with "Mini browsers" (e.g. UC mini, Opera mini...)
</div>
<div style="margin: 0 auto; visibility: hidden">
<div class="cf-browser-verification cf-im-under-attack">
  <noscript><h1 data-translate="turn_on_js" style="color:#bd2426;">Please turn JavaScript on and reload the page.</h1></noscript>
  <div id="cf-content" style="display:none">
    <div>
      <div class="bubbles"></div>
      <div class="bubbles"></div>
      <div class="bubbles"></div>
    </div>
    <h1><span data-translate="checking_browser">Checking your browser before accessing</span> kisscartoon.me.</h1>
    <p data-translate="process_is_automatic">This process is automatic. Your browser will redirect to your requested content shortly.</p>
    <p data-translate="allow_5_secs">Please allow up to 5 seconds&hellip;</p>
  </div>
  <form id="challenge-form" action="/cdn-cgi/l/chk_jschl" method="get">
    <input type="hidden" name="jschl_vc" value="a1d81cadad20c51162f1c9609528c657"/>
    <input type="hidden" name="pass" value="1458351408.408-4/QFnXcoqr"/>
    <input type="hidden" id="jschl-answer" name="jschl_answer"/>
  </form>
</div>

</div>
</div>
<div style="padding: 20px;">
</div>
</div>
</body>
</html>

This is interesting. We research how CloudFlare DDOS protection works.

The page consists of two parts, a piece of JavaScript:

(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('cf-content');a.style.display = 'block';
      setTimeout(function(){
        var t,r,a,f, REbvZoy={"xwS":!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]};
        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');
        ;REbvZoy.xwS+=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=+((!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=!+[]+!![]+!![]+!![]+!![]+!![];REbvZoy.xwS+=+((+!![]+[])+(!+[]+!![]+!![]));REbvZoy.xwS-=+((!+[]+!![]+!![]+[])+(+[]));REbvZoy.xwS-=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS-=+((!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]));a.value = parseInt(REbvZoy.xwS, 10) + t.length;
        f.submit();
      }, 4000);
    }, false);
  })();

And a form:

  <form id="challenge-form" action="/cdn-cgi/l/chk_jschl" method="get">
    <input type="hidden" name="jschl_vc" value="a1d81cadad20c51162f1c9609528c657"/>
    <input type="hidden" name="pass" value="1458351408.408-4/QFnXcoqr"/>
    <input type="hidden" id="jschl-answer" name="jschl_answer"/>
  </form>

Step 1: Javascript code has 4 important parts :
Part 01:

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);

The value of t will be the domain name like tutorialspots.com

Part 02:

REbvZoy={"xwS":!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]};

This part will be random, here are some cases:

QzaBtzw={"Rpa":+((!+[]+!![]+!![]+[])+(!+[]+!![]))};
JndYsCC={"FNREDBJbuqs":+((!+[]+!![]+[])+(+!![]))};

I explain this:
!+[] is equivalent 1.
!![] is equivalent 1.
![] is equivalent 0.

So, we can know:

REbvZoy={"xwS":8};
QzaBtzw={"Rpa":32};
JndYsCC={"FNREDBJbuqs":21};

or

REbvZoy.xwS=8;
QzaBtzw.Rpa=32;
JndYsCC.FNREDBJbuqs=21;

Part 03:

REbvZoy.xwS+=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=+((!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=!+[]+!![]+!![]+!![]+!![]+!![];REbvZoy.xwS+=+((+!![]+[])+(!+[]+!![]+!![]));REbvZoy.xwS-=+((!+[]+!![]+!![]+[])+(+[]));REbvZoy.xwS-=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]));REbvZoy.xwS-=+((!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]));REbvZoy.xwS*=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]));

This part will be random, too. I can explain this means:

REbvZoy.xwS+=37;
REbvZoy.xwS*=47;
REbvZoy.xwS*=6;
REbvZoy.xwS+=13;
REbvZoy.xwS-=30;
REbvZoy.xwS-=36;
REbvZoy.xwS-=25;
REbvZoy.xwS*=38;

Part 04:

a.value = parseInt(REbvZoy.xwS, 10) + t.length;

We know that l.length is domainname’s length.

Final, we can evaluate the value of a.value.

Step 2: Form part:
The form has 2 hidden values (jschl_vc), (pass) and an empty hidden value (jschl_answer).

And the value of hidden field (jschl_answer) will be the a.value we evaluated above.

After 4 seconds, the webpage will submit the form #challenge-form and the browse will redirect to the page like

http://tutorialspots.com/cdn-cgi/l/chk_jschl?jschl_vc=ffc0bc3abd267b9e706a8f0ea8a99431&pass=1458315326.907-uKcd4WKn4E&jschl_answer=174

Step 3:
View the response header we will see:

cf cookie

HTTP/1.1 302 Moved Temporarily
Date: Sat, 19 Mar 2016 02:07:31 GMT
Content-Type: text/html
Content-Length: 165
Connection: keep-alive
Set-Cookie: cf_clearance=9f46b603eee6322c0d4090579f962ab80aa3c1fe-1458353251-604800; expires=Sat, 26-Mar-16 03:07:31 GMT; path=/; domain=.tutorialspots.me; HttpOnly
Location: http://tutorialspots.com
Server: cloudflare-nginx
CF-RAY: 285d5f0d0e2f1e65-SJC
X-Frame-Options: SAMEORIGIN

We see a cookie called cf_clearance is created with a unique id that identifies the user as having verified the challenge.

More, the request header:

GET /cdn-cgi/l/chk_jschl?jschl_vc=937a4ff479debe45c1ac5a0fc7f73a09&pass=1458353249.481-6UJ6r2Uxkj&jschl_answer=3724 HTTP/1.1
Host: tutorialspots.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Referer: http://tutorialspots.com/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,vi;q=0.6,und;q=0.4
Cookie: ASP.NET_SessionId=wjqsoalr3zb0aixofpodurxz; __cfduid=ddd28b3724d223f321e3507940ab9f8291458351390

1 Comment

Leave a Reply