CC 攻击发生在 TCP/IP 协议的第七层,一般方式是在很短的时间里对网站发起大量请求,消耗目标服务器的资源,使目标网站负载过高而不能访问。
CC 攻击和 UDP Flood, TCP SYN Flood 这类位于 TCP/IP 第四层的攻击相比,对自己的资源消耗更少,对服务器的攻击强度更高,有四两拨千斤的效果。如果防御不好,呵呵,一台笔记本打垮一整个服务器集群也不是不可能。
而一般人对网络攻击是怎样进行的,以及怎样进行防御了解的都不多,这也就给了攻击者可乘之机。我这段时间在开发 VeryNginx ,对这部分正好有所研究。于是写成《 CC 攻击的防御》系列文章,主要探讨 CC 攻击的原理,以及一些可能的防御思路。希望能对大家有所帮助,如同在我无知的时候,互联网上其他无私分享知识给我的人一样。
文中描述的全部方法都已经编写成代码,并实际测试通过,包含在开源项目 VeryNginx 中。开箱即可使用,并且还包含其他诸多强大功能。
传送门: https://github.com/alexazhou/VeryNginx
为了进行防御,我们首先要了解我们对手的攻击方式。
通常发起 CC 攻击是使用专门的攻击工具,同时模拟成多个用户,向目标网站发起多个请求,一般这些软件为了防止地址被屏蔽,还内置通过代理攻击的功能。可以通过多个代理服务器对目标发起攻击,使封 IP 的防御方式变的失效。
因为 CC 攻击通过工具软件发起,而普通用户通过浏览器访问,这其中就会有某些区别。想办法对这二者作出判断,选择性的屏蔽来自机器的流量即可。
普通浏览器发起请求时,除了要访问的地址以外, Http 头中还会带有 Referer , UserAgent 等多项信息。遇到攻击时可以通过日志查看访问信息,看攻击的流量是否有明显特征,比如固定的 Referer 或 UserAgent ,如果能找到特征,就可以直接屏蔽掉了。
如果攻击者伪造了 Referer 和 UserAgent 等信息,那就需要从其他地方入手。攻击软件一般来说功能都比较简单,只有固定的发包功能,而浏览器会完整的支持 Http 协议,我们可以利用这一点来进行防御。
首先为每个访问者定义一个字符串,保存在 Cookies 中作为 Token ,必须要带有正确的 Token 才可以访问后端服务。当用户第一次访问时,会检测到用户的 Cookies 里面并没有这个 Token ,则返回一个 302 重定向,目标地址为当前页面,同时在返回的 Http 头中加入 set cookies 字段,对 Cookies 进行设置,使用户带有这个 Token 。
客户端如果是一个正常的浏览器,那么就会支持 http 头中的 set cookie 和 302 重定向指令,将带上正确的 Token 再次访问页面,这时候后台检测到正确的 Token ,就会放行,这之后用户的 Http 请求都会带有这个 Token ,所以并不会受到阻拦。
客户端如果是 CC 软件,那么一般不会支持这些指令,那么就会一直被拦在最外层,并不会对服务器内部造成压力。
高级一点的,还可以返回一个网页,在页面中嵌入 JavaScript 来设置 Cookies 并跳转,这样被伪造请求的可能性更小
Token 需要满足以下几点要求
Token 随 IP 地址变化是为了防止通过一台机器获取 Token 之后,再通过代理服务来进行攻击。一致性则是为了避免在服务器端需要存储已经生成的 Token 。
推荐使用以下算法生成 Token ,其中 Key 为服务器独有的保密字符串,这个算法生成的 Token 可以满足以上这些要求。
Token = Hash( UserAgent + client_ip + key )
1
Yamade 2016-03-02 09:03:51 +08:00 1
我去.....我抱你大腿...
|
2
qcloud 2016-03-02 09:05:33 +08:00
一般安全软件都可以搞定
|
3
jkjoke 2016-03-02 09:05:34 +08:00 1
学习了
|
4
irainsoft 2016-03-02 09:11:19 +08:00 1
收藏膜拜(;;;;;°∇°)
|
5
c0o1 2016-03-02 09:16:21 +08:00 1
给正常流量打了个标签
|
6
soolby 2016-03-02 09:28:47 +08:00 1
周大神,你好
|
7
tftk 2016-03-02 09:32:18 +08:00 1
Cookie 和 Token 不是用来做防攻击的,只能在攻击力量很弱的时候起一点作用。
|
8
tabris17 2016-03-02 09:33:24 +08:00
useless
|
10
H3x 2016-03-02 09:45:57 +08:00
楼主,提一下我的看法哈,不一定正确
假定攻击者使用一对 useragent 和 clientip 向服务器发起不带 cookie 的请求,然后在返回的应答包中取出 set cookies 中的 token 值,再赋到用于攻击请求的 cookie 中,这样是不是可以符合服务器对 token 的校验? 接着替换 useragent 和 clientip ,获取到 token 后再发起攻击请求,如果循环。 |
11
H3x 2016-03-02 09:51:22 +08:00
相对于传统的 cc 攻击,只发出攻击请求
针对你的防御措施,攻击者只需要多出“获取 token ,再赋到攻击请求”这么一步 |
12
jarlyyn 2016-03-02 10:06:05 +08:00
固定 cookie 就可以了, token 毫无必要。
能获取固定的 cookie,获取你的 token 也不难。 |
13
scarlex 2016-03-02 10:07:01 +08:00 2
文章睇一段, TCP/IP 不是只有四层么?七层那个是 OSI 吧
|
14
AlexaZhou OP @H3x
如果要进行一次 CC 攻击,过程一般是这样,连接一个代理服务器,发送 http 请求,然后立刻断开连接。这里断开是为了避免受到服务器的回包,因为服务器通常带宽很大,回包都过来的话容易把自己堵死。 网上随便就能下载到很多攻击软件,大概行为模式都是这样。 在添加了一次 Token 验证之后,这类攻击软件就基本不可用了,如果想发起攻击,就只能从头开始编写专门的工具,在普通攻击的方式上完成 Cookies 验证这一步。但具体来说,攻击者在编写这个工具的过程中还需要实现多线程(或者异步),以及通过代理服务器进行连接这些特性,才可以发起一定强度的攻击。 对于通过返回一个网页,然后通过 Javascript 设置 cookies 的情况,这样攻击工具可能还需要外挂一个 js 的执行环境... 效果就是发起一次攻击的成本大大增加了。 实际上也并没有绝对的防御方式,我们所能做的也就是不断提高攻击者的成本。 |
15
AlexaZhou OP |
19
lecher 2016-03-02 11:00:14 +08:00 via Android 3
实际上 token 只能挡普通攻击,计算 token 这个事情本身就消耗 CPU 资源,攻击的时候为了省带宽也有只发不收的。
这个 token 的校验有用,只要入口带宽没有被塞满,普通 cc 攻击都可以挡住。 但是如果请求被塞满入口带宽都爆掉的时候,有可能服务器自己算校验就把 CPU 爆掉了。 此外,做太复杂的校验对搜索引擎不够友好,这 token 校验第一波挡住的怕是搜索引擎的爬虫吧。 |
20
AlexaZhou OP @lecher
对的,这个就是针对 CC 攻击的一种防御思路,通过这个手段把不合法流量拦住。 对于暴力发包,只发不收的攻击来说,带宽都满了,并并不能通过这种方式进行防御。 生成 Token 的资源消耗还好,我在单核心的虚拟机中测试 VeryNginx ,同时运行 ab 和 VeryNginx ,性能在 6000 Qps 左右,实际上 nginx 单个 Worker 可能可以跑到 1W Qps 。 |
22
jarlyyn 2016-03-02 11:40:12 +08:00
@AlexaZhou
我用过这个方法,而且是用的带 html 的 js 的。 同时我自己也写过简单的爬虫。用 phantomjs 之类的话,所有无痕的方式基本都没有用。 如果只是普通的 curl 的话,那么 html 静态页+固定 cookie 也足够了。大不了定时修改一下。 http://blog.jarlyyn.com/site/blogi/100 |
23
AlexaZhou OP @jarlyyn
对 CC 攻击者来说,在使用固定或者唯一 Token 的情况下,攻击成本是有差别的。 很多攻击软件是可以设置 http 头的,如果使用固定 Token ,攻击者只需要在本机获取一次 Token ,然后设置好 http 头就可以直接发起攻击了,攻击成本低的可以... 但是如果使用可变 Token ,基本市面上所有 CC 软件全都无法使用了 这样就需要使用 phantomjs 这类的软件,这类工具一般是设计用来作为爬虫的,对攻击来说,速度太慢了 |
24
willis 2016-03-02 13:15:28 +08:00 via iPhone 1
这不就是 opencdn 的做法嘛 nginx +lua
|
26
yanyandenuonuo 2016-03-02 13:44:24 +08:00 1
Token = Hash( UserAgent + client_ip + key )
一个局域网内两台相同配置的机器使用同一版本浏览器访问那 UserAgent 和 client_ip 应该都一样了吧 |
27
woodrat 2016-03-02 13:44:58 +08:00 1
还可以 302 到一个验证码页面
|
28
AlexaZhou OP |
30
Strikeactor 2016-03-02 13:58:24 +08:00 1
和防爬虫一个道理, token 放一部分到前端去生成,同时函数加密,攻击者只有自己实现一遍 token 生成函数和在服务器上跑 JS 两种选择,成本都不小
不过我还是更倾向于 Nginx 限制高并发,结合防火墙直接 ban 掉高并发的 IP 。毕竟 CC 的 IP 一般不会太多,有大量 IP 资源的估计就直接 D 了 |
31
brance 2016-03-02 14:06:08 +08:00 via iPhone 1
666
|
32
AlexaZhou OP @Strikeactor
非常赞同。 Nginx 限制并发也是一种很好的防御方式,实际上我倾向多种防御方式结合使用,单一的防御方式总有被攻击者绕过的可能性,混合策略就很难绕过,防御效果会比较好 PS :后续也打算在 VeryNginx 中加入根据请求频次进行屏蔽的防御方式 |
34
AlexaZhou OP @x14oL
如果自己写一个工具,还需要实现: 1 ,能通过多个代理服务器来发起请求,不然单 IP 很容易被封掉 2 ,对于通过 JavaScript 来设置 cookies 的,需要外挂一个 js 的执行环境,或者读懂 js 的算法,并在 Python 里实现一次 总之成本还是不低 |
36
Yamade 2016-03-02 14:42:36 +08:00 1
我有一个问题:如果 VeryNginx 前面套了一个 cdn 的话,然后攻击者强制使用清除缓存的头,那么 VeryNginx 是不是把 cdn 的节点拦截了?
|
38
AlexaZhou OP @Yamade
会,这种浏览器行为检测会无差别的拦截非浏览器流量, cdn 应该也会被拦截到 如果在有 CDN 的情况下使用这种防御方式,应该需要在逻辑中加入专门的规则来放过来自 CDN 的请求 一种方式是由请求路径来判断,一般来说放在 CDN 的是静态文件,而针对静态文件作 CC 攻击是没有太大意义的,所以可以判断如果是静态文件的路径,就不进行这个检测。此外还可以根据 IP 或者 CDN 服务器特有的请求头(如果有的话)来判断 VeryNginx 的话本身支持定义复合规则来匹配请求,所以简单配置就可以做到这一点,并不需要另外编写代码 最后就是使用强制清除缓存的 Http 请求头,并不一定能使 CDN 服务器发出回源请求吧? |
39
Slienc7 2016-03-02 15:05:02 +08:00 1
很久之前就这么做了,不过我是用来防止蜘蛛的...
|
41
Yamade 2016-03-02 17:16:16 +08:00
@AlexaZhou 谢谢回复.清除缓存的 Http 请求头 百度和 cloudflare 是回源的.我的攻击就是这样.逼得我全部缓存了.
|
42
wujunze 2016-03-02 22:20:44 +08:00
学习了
|
43
xuboying 2016-06-17 16:42:26 +08:00
由于代理不稳定的原因,还是可能在出现普通用户访问的时候切换代理的场景,这种机制最好在受到攻击的时候才开启。
|