Skip to content

Instantly share code, notes, and snippets.

@yonjah
Last active February 10, 2023 19:25
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save yonjah/5082855 to your computer and use it in GitHub Desktop.
Save yonjah/5082855 to your computer and use it in GitHub Desktop.
Blocking DDOS bots with JavaScript for fun and profit! Or how easy it is to break the current protection methods and how to make it better.
TL;DR - jump to the challenge at the end
====ON BLOCKING EVIL BOTS=====
On a resent job interview I had for "Incapsula" a few days ago I was put to the challenge to break
their bot protection mechanism. Apparently node.js is not that common among bot writes and most bots
are not able to run javascript.
The challenge had two parts -
1. find what the code does.
2. implement a bot that will break the code without using js.
3. think how to make this code unbreakable
The first part was really easy and should take the average js programmer no more then 5 minutes to get
the real source code. The second part took little more than an hour to code in php but if your very
keen on your server side might even take much less. The last part was the hardest, and my first instinct
was that it was impossible.
Don't get me wrong, I know the current code has a lot of improvements, and can be easily be made
10 times harder to break. But even if it was 100 times harder to break it would still be breakable
by a novice programmer with a debugger. And no matter how hard your going to obfuscate it will still
be easy to reverse. So I left it at that.
A few days later during a hard session of scuba diving in the red I had a bit of epiphany.
what if we could make a code that will be undebuggable, and then make it use any bad practice of js
known to man that only the very best javaScript pros will be able to understand what it does ?
we will get a code that just understanding what it does will take an experienced programmers hours
or even days. writing the decryption code will probably take the same time but most people wont
be able to get pass the first step.
It took me almost 10 hours to write the basic proof of concept (most of it debugging a undebuggable code).
and I hope it as robust as I think.
so here's your chance to try and break it -
=====THE CHALENGE=====
What the code does -
the code decrypts an encrypted scripts and redirect the user to a web site.
if the code senses some one is not running js properly it will redirect you to a diffrent site.
How to prove I can broke it -
simple :-) the encrypted string also contains a short text that is not part of the url.
if you got the text post it on the comments and please write how long it took you.
Rules -
Do what ever you want as long as your not just brute forcing the encryption (thats cheating)
I can think of one more method you might be able to get the string without knowing the encryption key
I tried to protect against this methods just for this challenge but the real point is having the key
Final notes -
I want to allow people to try and break it without any prior knowlege, but if it as hard as I hope it
will not be easy. But in a week or so I will write another post explaining in a more technical way what
I did, and I hope that even then getting the key will be hard. of course I could be missing something
so if you find it too easy let me know.
The general idea of this code should work on any browser but the encryption algorithm I used rewuires
base64 encoding. I didn't want to include any external base64 libraries so it will only work on normal
browsers and apparently also IE10 (but I havent tested it).
This code was written intentionally with every js bad practice I could think (good practice are meant to
help writing a more understandable code which is the opposite of our goal here) and it might be a great
source for learning about what is consider bad practice. but if you are just learning js do yourself
a favour and don't learn how to code form this script.
++ if your trying the challenge please write a comment or follow this gist
++ so I'll know how many people are trying
Good Luck
Yoni Jah.
<html>
<head>
<title>try me</title>
</head>
<body>
<script type="text/javascript">
var dec=function (code) {
var e=['for','eval','callee','with','substring','new'],o=["+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],aa=
function(n){var t,s='';n=''+n;for(var i=0;i<n.length;i+=3){t = (+(n[i]+n[i+1]+n[i+2])%48);if (t >= 0) s+=o[t];}return s;}, a=(function () {var a = function(s) {var l = new Array(Math.ceil(s.length/4));for (var i=0; i<l.length; i++) {l[i] = s.charCodeAt(i*4) +
(s.charCodeAt(i*4+1)<<8)+(s.charCodeAt(i*4+2)<<16)+(s.charCodeAt(i*4+3)<<24);}return l;}, b = function(l) {var a = new Array(l.length);for (var i=0; i<l.length; i++) {a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF,l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);}
return a.join('');};return function(c, w) {var v, k, n, z, y, d, mx, e, q, s, f;if (c.length === 0) return(''); v = a(window.atob(c));k = a(w.slice(0,16));n = v.length;z = v[n-1]; y = v[0]; d = 0x9E3779B9;q = Math.floor(6 + 52/n); s = q*d;while (s !== 0) {e = s>>>2 & 3;
for (var p = n-1; p >= 0; p--) {z = v[p>0 ? p-1 : n-1];mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (s^y) + (k[p&3 ^ e] ^ z);y = v[p] -= mx;}s -= d;}f = b(v);f = f.replace(/\0+$/,'');return f;};}()),f = e[2],q = function(a){var b,c,d,e,f;for(b=65521,c=1,d=e=0;(f=a.charCodeAt(e++));d=(d+c)%b)c=(c+f)%b;return(d<<16)|c;},
c = function(a,c,d) {if (d){return d%2?(function(h,n){var t,i=0,a = [''];for (t=0;t<h.length;t++){if (h[t] !== n) {a[i] += h[t];}else {i+=1;a.push('');}}return a;}):(function(a,g){var t,m='';for (t=0;t<a.length;t++){m+=t?g:'';m+=a[t];}return m;});}
var b=function(){var a=new Date().getTime();debugger;return a;};switch(a) {case 1:return b;case 2:return function(){debugger;return new Date().getTime();};case 3:b = c;default:return b?function(a,d,c){return ((a-d)>2 || (d-a)>2)?a/d:b>9?c+b:c;}:function(a,b){debugger; return ((a-b)<=1 && (b-a)<=1)?0/0:(a-b)/(b-a);};}},
d={a:this,b:arguments,c:window},g,h,i,b=d.b[f].toString();var k={a: c(1,2)(),b: c(2,3)(),j: 11,l: 13,f: c(3,3)(c(1,2)(),c(2,0)(),null),h: 29,c: c(3,2)(c(1,2)(),c(2,3)()),m: 83,g: c(3,0)(2,0),y: 127,e: c(3,0)(c(1,2)(),c(2,0)(),8),i: 47,k: b,d: c(3,5)(c(1,0)(),c(2,4)(),1)};debugger;
var s=(function(){var a=0, b=[], z = 0;return function(r,x,u){var n,w,v=0,j=2,t=0;z = (x === u) ? z : x;while (r) {w='';a++;b=[a, 0-a, a/2];with(k){y=((a-b)*(a-b)/(h*m))|0;n=z?t+z*2:k.length;
for(t+=z;t<n;t+=1){w+=k[t];}t=z?t:z;v+=aa(q(w));z+=y;z=z>3000?i:z;if(((a-b)>2||(b-a)>2)||c==c){z+=h;}else{z+=i;}if(((a-b)<=1&&(b-a)<=1)&&(d == e)){z+=l;}
else if(g){z+=j;}if(f==u&&r%2){z=z>m?z-m:m-z;}g=e;y=c;c=f;f=g;g=d;d=y;e=g;}r--;}return v;};}());e=''; g = a(code,s(6));for(f=0;f<25;f+=1){e+=g[f];}e=e.indexOf('http')>=0?e:'http://www.google.com';return e;
};
window.location = dec("OZlLn5zeBBa1Y9b+BrqxUe3zC0V4KhahRuoPb3LyoufWcpCfU482QMxk79c=");
</script>
</body>
</html>
@rubtoa
Copy link

rubtoa commented Mar 12, 2013

Cool challenge - i'm in

@colbeseder
Copy link

Nice trick.

But as soon as you make a tiny edit to the code and watch the results, you understand what the encryption key is and then you're basically done. I'll try to think of a way to hide it a little better.

@infandrew
Copy link

did you get it?

Took almost 2-3 days to understand. Found 2 new nice techniques for myself.

@aalfiann
Copy link

aalfiann commented Feb 1, 2018

Before I going to try to break this script, I have several question:

  1. What is benefit to use this? Is this script for blocking bots that run DDOS to my website?
  2. Is this will affect for my SEO? Because crawler maybe can't accessed your page.

Thanks

@saibhargavtech
Copy link

I have simillar type of problem can you help??

@saibhargavtech
Copy link

I am redirecting the user to redirection page to check for js cookies and verifying js data (i.e inline javascript), now when i verify the js data, i send him back to the original webpage , i want solution if he disables js now in the original page, how can i know?.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment