您的位置:首页 > Web前端 > JavaScript

用 JavaScript 对抗 DDOS 攻击

2016-04-09 09:11 483 查看
继续趣事分享。

上回聊到了大学里用一根网线发起攻击,今天接着往后讲。

不过这次讲的正好相反 —— 不是攻击,而是防御。一个奇葩防火墙的开发经历。

第二学期大家都带了电脑,于是可以用更高端的方法断网了。但设备先进反而没有了 GEEK 的感觉。于是,决定做些其他更有意义的事。

一天,几个好友在吐槽,他们的游戏服务器又被打垮了,接着讨论起各种防护方案。

在过去,每当听到防火墙软件时,就觉得毫无卵用。巨大的流量一来,带宽都堵死了,软件又有何用。

不过,大家仍对其寄以厚望。而且还有不少厂商在做,看来,效果总是有一点的。

讨论讨论着,不免又有些蠢蠢欲动。要不,做个防火墙吧,做一个思路完全不同的!

当然,这不是第一次尝试。

初学那会,没有固定的目标。每看见一个小 demo,就想搞个大程序。比如看了 DirectX 就有做游戏的冲动,但不出几天就不了了之。

有段时间对驱动程序产生了兴趣,琢磨起 Windows DDK 里的 demo。当看见 NDIS 中间件这玩意时,顿时起了精神。这不就是一个最底层的包过滤器吗,用来做防火墙,性能自然是极好的。

于是心血来潮,照着其中的样例,改造出一个最简单的 IP 过滤防火墙。为了凸显高性能,硬着头皮看了本数据结构,依样画葫芦写了个哈希表,来更快查询。

然而快归快,没有实际用途,不过是个玩具罢了。

现实中的防火墙,也不可能这么简单的逻辑。肯定还需更高层的协议分析,复杂的策略判断,大量的数据积累。。。当然还少不了无数次的蓝屏调试。

想到这,立马就没有了继续。

然而这一次,决定不再纠结技术层面,而是做一个“另类”的 —— 用最简单的技术,加上巧妙的想法,配合一些独门绝技,来获得出其不意的效果。

考虑到传统的开发人员,对系统、网络都已经非常熟悉,和他们比拼这些,就毫无优势了。

而当时的我,点满了一个和安全毫不相干的技能 —— 网页脚本特效,以及一堆“前端黑魔法”。

但是。。。这。。和网络防御。。。有什么关系?

没有半点关系~~ 想多了。还是考虑正经的吧。

首先想到的,是改造游戏的服务端程序。

毕竟这是“开源”的,肯定能通过修改程序,来加强那脆弱的网络系统。

然而,当看到那密密麻麻的代码、从未用过的语言、完全不熟的调试器,兴致荡然无存。

没兴趣就没想法,果断放弃。

既然如此,那就从客户端试试。

这一次,抱着探索的心情,打开程序,细细揣摩起来。

正当毫无头绪时,突然传来亲切的嚓嚓声 —— 敏感的神经怎能放过,这不是 ie 的专属声音吗。

这才猛然意识到,登录器中内嵌的,不正是一个大大的网页!



有网页,不就可以运行脚本了!

从没想到,居然打起了这个内嵌框的主意~~ 但总算把脚本扯到一起了。

越想越兴奋。现有的防火墙,几乎都是纯服务端的数据分析,能让客户端参与的,应该还很少吧。

“只要在登录器的网页里引一个脚本,就能...”

大家听了,表示可以接受。

有脚本,就可以尽情发挥了。

我们必须让用户运行脚本,才能连上游戏服务器;没运行过脚本的 IP,就一律阻拦。

于是开始构思、整理:

当脚本运行时,发送一个请求给 “授权服务器”

“授权服务器”验证参数之后,将用户 IP 通知给“游戏服务器”上的防火墙,添加到白名单

“游戏服务器”只允许白名单的 IP 通过(“授权服务器”默认在白名单)



正常用户,这并没影响;但攻击器不会执行脚本,也就无法进入白名单 —— 无论发送什么数据包,都会被拦截。

这样,防火墙的策略,也变得极其简单:仅仅判断数据包的 IP 是否在白名单里。

于是,之前那个简陋的 demo 驱动又被翻了出来。因为功能单一,保证了稳定性。而且是在网卡链路层上拦截,所以有超高的性能。

到此,一个 JavaScript 参与的网络防火墙原型诞生了!

也许你会说,这只是转移了风险而已。把游戏服务器的风险,转移到了网站上。要是网站被打垮,同样无法进游戏。

的确如此。不过相比普通的网络程序,Web 有更多成熟的防御方案,甚至用现成的 CDN,就可以缓解。

因此将普通的 C/S 网络防御,挂靠在了更稳定的 B/S 之上,就无需再造轮子了,节省大量成本。

当然这只是基本雏形。实际应用,还有不少需要考虑的地方。

例如,白名单不能无限增加,得有过期时间;客户端的脚本,也不能只运行一次,得定期触发激活。

....

不过,由于无需考虑兼容性问题,使得开发十分顺利。服务器都是 Win2003;网页运行在 WebBrowser 控件里,都是 ie67 的内核。

几天后功能完成。接着做了个简单的界面程序,将方案进行包装,就开始试用了。

上线后,效果很理想!任何与玩家无关的流量,都进行了拦截。虽然大流量攻击仍无能为力,但各种 CC 攻击就能轻松抵挡住了!

不过,攻击者也绝不会罢休。

况且,前端的一切都是公开的,这个秘密早晚会被发现。


对抗 v1

平静了几个月后,一大波僵尸又来了。

日志显示,短时间内白名单进了大量 IP,这绝不是正常用户的。

显然,已有人发现了这个秘密!

事实上,第一版做的非常简单,甚至连脚本都没混淆。

他们把脚本逻辑,移植到了攻击器里。这样不访问网页,也能变成合法用户了。

至于他们是如何发现的,无从得知。但脑补发现后的心情,一定是这样的:卧槽,原来是在这里,居然这么猥琐~~~~



当然,这是意料之中的事。

新版本早已准备就绪,“前端黑魔法” 也跃跃欲试,决定进行反击。

这次,将脚本进行了加密。

不,不是网上流传的那种加密,而是特殊构造的。虽然看起来差不多:整个程序,套在一个 eval 之中。

懂点 JS 的都知道,把 eval 换成 console.log 之类的,代码就原形毕现了。相信 99% 的人会这么做。

于是,利用大家这个心理,在代码中埋下一陷阱:如果只解密,不 eval,就会出现意外的后果。

eval(
(function() {
...
T = setTimeout(die, 1)
...
code += 'clearTimeout(T)'
...
return code
})()
)


在解密过程中,偷偷开启一个定时器:1 毫秒后,进入自杀模式 —— 死循环内存申请!

正常情况下,这并不会触发 —— 因为随后 eval 的代码里,会解除这个定时器;但如果把 eval 换成其他的,就无法执行解除了 —— 炸弹触发!

当时的主流内存还是 1~2G,这会瞬间被吞光,卡到硬盘吱吱作响。



为满足好奇心,想看看有多少人栽进去,因此在死循环之前,还加了日志上报的功能。

那段时间,正好在琢磨一个短信接口。于是,这日志就成了测试内容。

每当有人试图破解脚本时,手机就立即收到了消息,体验了回“尽在掌控中”的感觉:)



当然,就这样结束了吗?

不,还早着呢。


对抗 v2

之前的那些奇技淫巧,纯属娱乐而已,并不能撑多久。

但简单、好玩,似乎这正是对抗的乐趣。之前从未想过,居然还能把脚本黑科技,用在网络防御上。

于是,又陆陆续续对抗了一段时间。

直到兴致淡却,懒得再频繁升级了,于是换上一个更复杂的脚本。其中打包了大量的算法库,光是代码,就能吓退一些密集恐惧症者。

此外,还暗藏了一些自检功能,干扰脚本的分析破解。

这时,要把脚本逻辑移植出来,就格外困难了。

这迫使攻击者,不得不用另一种方式。。。


对抗 v3

为何要破解脚本,为何要了解其中的细节?直接让攻击器运行脚本,不就可以了!

之前担心的,还是发生了。升级后的攻击器,居然会弹网页了,看起来和正常用户一样。。。

黑盒攻击!加密混淆那些都没用了,只能寻找一些破绽。开始收集区分“真网页”和“内嵌网页”的黑魔法。

例如,有些攻击者为了隐蔽,把网页弹在屏幕之外。因此,分析页面 screenLeft、screenTop 就可以识破。

例如,内嵌网页的尺寸是锁定的。而弹出的网页,没准能调整大小,可以改变一两个像素试试。

.....

于是,光坐标尺寸,就扛了一阵子。

事实上,大多攻击者都不注重细节。所以,破绽还是不少的。

不过,发现破绽后怎么处理?直接在前端中止吗?当然不是,这样太明显。

即使识破,仍会发送请求,仍能进白名单。只是,请求里悄悄做了标记,暗示这是一个可疑用户 —— 最终白名单的有效时间,比正常短得多。

这样,就把测试效果延后了,增加破解时间。

同时,升级了防火墙策略,增加了“黑名单”机制。黑名单的 IP,是永远不能变白的。

因此,某些用户的可疑值积累到一定程度,就直接拉黑了。

随着防火墙装机量增加,将黑名单进行了共享,避免了不少重复分析。


对抗 v4

前端的秘密,早晚会被发现的。

最后,逼迫攻击器也采用了“内嵌网页”!之前的黑魔法,又纷纷失效了。。。

然而,破绽总还是有的。

很多攻击器,程序界面是隐藏的。这,会导致一些渲染上的差异。

例如,Flash 就有这么个机制:当界面不可见时,帧率会降到 2 fps,以节省开销。

例如,复杂的 JS 动画特效,原本跑的并不流畅。但界面挡住后,就能毫无压力的运行。

.....

当然,这些只能用来参考,并非一定正确。

同时,对防火墙的策略也进行了调整:只有当机器压力大时,才开启拦截。尽量降低被“黑科技”误伤的可能。

就这样,修修补补又一年。


对抗 v5

Chrome 浏览器流行后,极大激发了人们研究前端的热情。同时,脚本调试也变得更容易了。

为了不丧失最后的优势,决定“反其道而行之” —— 将脚本的部分逻辑,换成了 VBScript,迫使停留在 IE 上。而正常用户都运行于 WebBrowser,并无影响。

同时还将一些功能,做到了 Flash 里。

整个流程,需要 JS、VBS、Flash、iframe 等交互才能完成,大幅增加了调试复杂度。


对抗 v6

在对抗窘迫时,甚至还尝试了一些下策。例如,弹出一个对话框:
alert('欢迎光临 XXX')


只有点了确定,才能继续运行。于是,一些假人就卡死在了这里。

当然,攻击者很快做出回应 —— 屏蔽了对话框。

我是如何知道的呢?因为每次弹框,都记录了停顿时间:
t = time()
alert(...)
t = time() - t


然而这其中,居然有 0ms 的!!!



这是有多快的手速??即使一直按着 ESC 键,对话框好歹也会闪一下,至少也有几十毫秒了。怎么试不出这么快的~~~

最终,将过短的时间都 XXX


对抗 v7

一段时候后,攻击者也摸索出了规律,不直接屏蔽了。

先让它弹出来,延时几秒,再发送回车键去关闭。。。反正我都想到了,人家也想得到。

于是,改成弹两个、三个、随机个对话框,而对方也许只会点一次。

当然,这都是临时的搞笑方案。

。。。

最后,迫不得己,不再使用系统对话框。而是用 HTML 画一个,并且只能通过鼠标点击关闭。

其实这早已想过,但一直不敢实施 —— 因为这只是个内嵌网页,即使不点,也不影响程序使用。一些用户可能没注意到,就错过了。

系统对话框没有这个问题。因为它会阻塞整个程序的消息,不点就无法其他操作。

为了不让用户错过,这次做了一个格外醒目的浮层,并配上声音和闪烁效果。

回到了 HTML,对抗优势就大幅增加了。

尽管攻击者也能模拟鼠标点击,但是,光点击是远远不够的 —— 鼠标不可能一出来,正好就在关闭按钮上吧,肯定还得先移进去。

因此,还统计了鼠标 move、over、out 等事件。如果次数特别少,也是极其可疑的。

类似的行为分析方式,还有不少。配合独特的思路,陆续更新直到最后。


其他对抗

当然,并非所有攻击,都从脚本着手的。

还是有不少喜欢简单暴力的 —— 网络攻击。尤其那台“授权服务器”,自然成了众矢之的。

使用传统的负载均衡?简单,但不隐蔽。攻击者只需跟踪域名,既可遍历出 IP。

为了隐蔽,于是将 IP 列表写在脚本里,让脚本程序来负载。而脚本,是经过加密混淆的。

这样,又把攻击者带回“前端黑魔法”这个坑里了!

当然,“授权服务器” 的实际 IP,在网页运行时还是能够观察到,只是麻烦一些。

同时,结构上也进行一些策略优化。

例如,在游戏服务器上,也开了一个“授权服务”。

平时拦截未开启时,可直接走这条“绿色通道”;只有走不通时,才通过“授权服务器”中转。



这样,就大幅降低对“授权服务器”的依赖!

当然,这么做也有弊端:授权服务的逻辑泄露了。所以,防火墙的部分模块,也做了一些加壳处理。


结束

随着前端技术日趋成熟,优势大不如从前。而且对黑科技的淡却,以及其他工作,逐渐减少了更新。

到了大学结束前,已彻底放弃了更新。

虽然其中趣事还有不少,但这是最长、最有科技的一段。不,并没有什么高级技术,除非“思路”也算。

前前后后绝大多数的时间,都花在“想”上面,“码”的过程少之又少。

当然,这其中也想过一些其他类型的 “JavaScript 防火墙”,例如“跨站防火墙”、“流量劫持防火墙”等等。后来也都变成了现实,用在了工作之中。

用前端脚本玩转安全防御,从那一刻起,持续至今。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: