找到了这个系列的原始作者:

http://www.cnblogs.com/rush/archive/2012/02/05/2339037.html

最近网络安全成了一个焦点,除了国内明文密码的安全事件,还有一件事是影响比较大的——Hash Collision DoS(通过Hash碰撞进行的拒绝式服务攻击),
有恶意的人会通过这个安全漏洞让你的服务器运行巨慢无比,那他们是通过什么手段让服务器巨慢无比呢?我们如何防范DoS攻击呢?本文将给出详细的介绍。

这一篇跟Hash关系比较密切。

首先,发生哈希冲突时,我们可以使用冲突解决方法解决冲突,而主要的哈希冲突解决方法如下:

开放地址法:在原hash空间中找位置放。

再哈希法

链地址法:开启新的链表来存储新的内容。

建立一个公共溢出区

上面开放地址法和链地址法的区别,可以查看 http://blog.csdn.net/w_fenghui/article/details/2010387

注意:

.NET是使用第一种策略解决哈希冲突,它根据某种原则将碰撞数据定位到其他槽中。

而PHP是使用单链表存储碰撞的数据,因此实际上PHP哈希表的平均查找复杂度为O(L),其中L为桶链表的平均长度;而最坏复杂度为O(N),此时所有数据全部碰撞,哈希表退化成单链表。下图是PHP中正常哈希表和退化哈希表的示意图。

现在主流编程语言都采用的哈希算法是DJB(DJBX33A),而.NET中的NameValueCollection.GetHashCode()方法就是使用DJB算法。

DJB的算法实现核心是通过给哈希值(Key)乘以33(即左移5位再加上哈希值)计算哈希值,接下来让我们看一下DJB算法的实现吧!
    uint hash = 5381;
for (int i = 0; i < value.Length; i++)
{
// The value of ((hash << 5) + hash) the same as
// the value of hash * 33.
hash = ((hash << 5) + hash) + value[i];
}
 

针对哈希的攻击:

通过前面介绍.NET中GetHashCode()方法,现在我们对于其中的实现算法有了初步的了解,
由于哈希冲突的原理就是针对具体的哈希算法来构造数据,使得所有数据都发生碰撞。

这里我们使用了一个简单方法构造冲突数据——蛮力法。(效率低)

由于蛮力法效率低,所以我们采用更加高效的方法中途相遇攻击(meet-in-the-middle attack)或等效子串(equivalent substrings)来构造冲突数据。

等效子串:

当两个字符串的哈希值发生冲突,例如:hash(“string1”)=hash(“string2”),那么由这两个子串在同一位置上构成的字符串也发生哈希冲突,

假设“EZ”和“FY”在哈希函数中发生冲突,那么字符串“EzEz”,“EzFY”,“FYEz”,“FYFY”两两之间也发生冲突。

示例:
http://koto.github.io/blog-kotowicz-net-examples/hashcollision/kill.html

中途相遇攻击:

分成前后两节,先指定前面,和最终hash,然后构造后面的。

其实没怎么看懂。文中有。

总结:

发post请求时候,发出大量重复hash的post参数,来让对方的hash算法总是冲突,然后崩溃。

以上是我的理解。

关于hash碰撞为什么能够产生DoS攻击,可以结合下面这篇来看:

http://blog.jobbole.com/11516/

哈希表是一种查找效率极高的数据结构,很多语言都在内部实现了哈希表。PHP中的哈希表是一种极为重要的数据结构,不但用于表示Array数据类型,
还在Zend虚拟机内部用于存储上下文环境信息(执行上下文的变量及函数均使用哈希表结构存储)。 PHP哈希表最小容量是8(2^3),最大容量是0×80000000(2^31),并向2的整数次幂圆整(即长度会自动扩展为2的整数次幂,如13个元素的哈希表长度为16;
100个元素的哈希表长度为128)。nTableMask被初始化为哈希表长度(圆整后)减1。 HashTable中的nTableMask是一个掩码,一般被设为nTableSize – 1,与哈希算法有密切关系,后面讨论哈希算法时会详述。

Zend HashTable的哈希算法异常简单:hashKey = key & nTableMask; 如果key是字符串,就先用time33算法,变成整型,然后处理。(time33算法前面也介绍了)

基本攻击

上文提到Zend HashTable的长度nTableSize会被圆整为2的整数次幂,假设我们构造一个2^16的哈希表,
则nTableSize的二进制表示为:1 0000 0000 0000 0000,而nTableMask = nTableSize – 1为:0 1111 1111 1111 1111。
接下来,可以以0为初始值,以2^16为步长,制造足够多的数据,可以得到如下推测: 0000 0000 0000 0000 0000 & 0 1111 1111 1111 1111 = 0 0001 0000 0000 0000 0000 & 0 1111 1111 1111 1111 = 0 0010 0000 0000 0000 0000 & 0 1111 1111 1111 1111 = 0 0011 0000 0000 0000 0000 & 0 1111 1111 1111 1111 = 0 0100 0000 0000 0000 0000 & 0 1111 1111 1111 1111 = 0
概况来说只要保证后16位均为0,则与掩码位于后得到的哈希值全部碰撞在位置0。

攻击代码示例:

<?php

$size = pow(2, 16);

$startTime = microtime(true);

$array = array();
for ($key = 0, $maxKey = ($size - 1) * $size; $key <= $maxKey; $key += $size) {
$array[$key] = 0;
} $endTime = microtime(true); echo $endTime - $startTime, ' seconds', "\n";

作者说用了近88秒才完成,并且在此期间CPU资源几乎被用尽。

而正常的hash插入,如下,仅仅需要0.036秒。

<?php

$size = pow(2, 16);

$startTime = microtime(true);

$array = array();
for ($key = 0, $maxKey = ($size - 1) * $size; $key <= $size; $key += 1) {
$array[$key] = 0;
} $endTime = microtime(true); echo $endTime - $startTime, ' seconds', "\n";

POST攻击

一般情况下很难遇到攻击者可以直接修改PHP代码的情况,但是攻击者仍可以通过一些方法间接构造哈希表来进行攻击。例如PHP会将接收到的HTTP POST请求中的数据构造为$_POST,而这是一个Array,内部就是通过Zend HashTable表示,因此攻击者只要构造一个含有大量碰撞key的post请求,就可以达到攻击的目的。具体做法不再演示。

防御方法

目前PHP的防护措施是控制POST数据的数量。在>=PHP5.3.9的版本中增加了一个配置项max_input_vars,用于标识一次http请求最大接收的参数个数,默认为1000。

另外的防护方法是在Web服务器层面进行处理,例如限制http请求body的大小和参数的数量等,这个是现在用的最多的临时处理方案。具体做法与不同Web服务器相关,不再详述。

上面的防护方法只是限制POST数据的数量,而不能彻底解决这个问题。例如,如果某个POST字段是一个json数据类型,会被PHPjson_decode,那么只要构造一个超大的json攻击数据照样可以达到攻击目的。

理论上,只要PHP代码中某处构造Array的数据依赖于外部输入,则都可能造成这个问题,因此彻底的解决方案要从Zend底层HashTable的实现动手。

一般来说有两种方式,一是限制每个桶链表的最长长度;二是使用其它数据结构如红黑树取代链表组织碰撞哈希(并不解决哈希碰撞,只是减轻攻击影响,
将N个数据的操作时间从O(N^2)降至O(NlogN),代价是普通情况下接近O(1)的操作均变为O(logN))。

目前使用最多的仍然是POST数据攻击,因此建议生产环境的PHP均进行升级或打补丁。至于从数据结构层面修复这个问题,目前还没有任何方面的消息。

其他各种语言针对此类哈希碰撞攻击有漏洞的情况:

除了Perl之外,这个漏洞使得包括Java, JRuby, PHP, Python在内的以下各种开发语言和许多常用软件都纷纷中招:
Java, 所有版本
JRuby <= 1.6.5 (目前fix在 1.6.5.1)
PHP <= 5.3.8, <= 5.4.0RC3 (目前fix在 5.3.9, 5.4.0RC4)
Python, all versions
Rubinius, all versions
Ruby <= 1.8.7-p356 (目前fix在 1.8.7-p357, 1.9.x)
Apache Geronimo, 所有版本
Apache Tomcat <= 5.5.34, <= 6.0.34, <= 7.0.22 (目前fix在 5.5.35, 6.0.35, 7.0.23)
Oracle Glassfish <= 3.1.1 (目前fix在mainline)
Jetty, 所有版本
Plone, 所有版本
Rack <= 1.3.5, <= 1.2.4, <= 1.1.2 (目前fix 在 1.4.0, 1.3.6, 1.2.5, 1.1.3)
V8 JavaScript Engine, 所有版本
ASP.NET 没有打MS11-100补丁

Java相关

这些语言使用的Hash算法都是“非随机的”,比如Java和Oracle使用的Hash函数:

static int hash(inth)

{

h ^= (h >>> 20) ^ (h >>> 12);

return h ^ (h >>> 7) ^ (h >>> 4);

}

所谓“非随机的” Hash算法,就可以猜。比如:

1)在Java里, Aa和BB这两个字符串的hash code(或hash key) 是一样的,也就是Collision 。
2)于是,可以通过这两个种子生成更多的拥有同一个hash key的字符串。如:”AaAa”, “AaBB”, “BBAa”, “BBBB”。这是第一次迭代。
其实就是一个排列组合,写个程序就搞定了。
3)然后,可以用这4个长度的字符串,构造8个长度的字符串。 在攻击时,只需要把这些数据做成一个HTTP POST 表单,然后写一个无限循环的程序,不停地提交这个表单。用浏览器就可以实现。
当然,如果做得更精妙一点的话,把这个表单做成一个跨站脚本,然后找一些网站的跨站漏洞,放上去,于是能过SNS的力量就可以找到N多个用户从不同的IP来攻击某服务器。

要防守这样的攻击,有下面几招:

打补丁,把hash算法改了。

限制POST的参数个数,限制POST的请求长度。

最好还有防火墙检测异常的请求。

Nodejs也有类似问题:

使用 connect.limit 限制 request-body-size,直接上 connect.limit 模块解决。

防范 http header 攻击

请求的 http header 也会导致hash冲突,在V8层面未修复hash算法之前,可以通过简单的 http_patch.js 修复此问题:

if (this.__headerCount__ >= 100) {
return;
}

也有业内人士说:

目前暂无完美的解决方法。

【转载】网络攻击技术(三)——Denial Of Service & 哈希相关 & PHP语言 & Java语言的更多相关文章

  1. java语言体系的技术简介之JSP、Servlet、JDBC、JavaBean(Application)

    转自:https://zhangkunnan.iteye.com/blog/2040462 前言 Java语言 Java语言体系比较庞大,包括多个模块.从WEB项目应用角度讲有JSP.Servlet. ...

  2. 分布式拒绝服务攻击(DDoS:Distributed Denial of Service)

    DDoS攻击通过大量合法的请求占用大量网络资源,以达到瘫痪网络的目的. 指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力. ...

  3. 【安全研究】Domain fronting域名前置网络攻击技术

    出品|MS08067实验室(www.ms08067.com) 千里百科 Domain Fronting基于HTTPS通用规避技术,也被称为域前端网络攻击技术.这是一种用来隐藏Metasploit,Co ...

  4. DDoS(Distributed Denial of Service,分布式拒绝服务)

    DDoS:Distributed Denial of Service,即分布式拒绝服务攻击. 借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高 ...

  5. Distributed Denial of Service

    Distributed Denial of Service https://www.cnblogs.com/163yun/p/10030890.html 全称Distributed Denial of ...

  6. Slow HTTP Denial of Service Attack

    整改建议 1.中断使用URL不支持HTTP方法访问的会话 2.限制HTTP头及包长至一个合理数值 3.设置一个绝对的会话超时时间 4.服务器支持backlog的情况下,需设置一个合理的大小 5.设置一 ...

  7. Slow HTTP Denial of Service Attack漏洞整改方法

    前期现场反馈系统扫描出Slow HTTP Denial of Service Attack漏洞,根据以往经验提供了更改建议,居然没有生效,深入研究了一下WebLogic下该漏洞的修复方法,现记录如下: ...

  8. 网络攻击技术:SQL Injection(sql注入)

    网络攻击技术开篇——SQL Injection   1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库被黑客公开发布,600万用户的登录名及密码被公开泄露,随后又有多家网站的用户密码 ...

  9. WebGoat系列实验Denial of Service & Insecure Communication

    WebGoat系列实验Denial of Service & Insecure Communication ZipBomb 服务器仅接收ZIP文件,将上传的文件解压,进行操作之后删除.已知服务 ...

随机推荐

  1. vscode Python 运行环境配置

    { "git.ignoreMissingGitWarning": true, "window.zoomLevel": 1, "[python]&quo ...

  2. objc_msgSend arm64 崩溃问题

    http://blog.csdn.net/chenyong05314/article/details/42121001 2014-12-24 10:49 878人阅读 评论(0) 收藏 举报 转载自: ...

  3. KVM基本概念

    在kvm技术中,应用到的两个东西:qemu和kvm.其中kvm负责cpu虚拟化和内存虚拟化,但是kvm不能模拟其他设备,qemu是模拟IO设备(网卡,磁盘),kvm加上qemu之后就能实现真正意义上的 ...

  4. golang写一个简单的爬虫

    package main import( "fmt" "io/ioutil" "net/http" ) func gethtml(url s ...

  5. 【洛谷】xht模拟赛 题解

    前言 大家期待已久并没有的题解终于来啦~ 这次的T1和HAOI2016撞题了...深表歉意...表示自己真的不知情... 天下的水题总是水得相似,神题各有各的神法.--<安娜·卡列妮娜> ...

  6. WPF拖放功能实现

    写在前面:本文为即兴而作,因此难免有疏漏和词不达意的地方.在这里,非常期望您提供评论,分享您的想法和建议. 这是一篇介绍如何在WPF中实现拖放功能的短文. 首先要读者清楚的一件事情是:拖放主要分为拖放 ...

  7. pytest学习(2)

    可以把多个test放在一个class里, class TestClass(object): def test_one(self): x = "this" assert 'h' in ...

  8. Java多态机制和继承中重写重载

    关于Java中多态机制 http://www.cnblogs.com/chenssy/p/3372798.html 这篇博文讲的很透彻 大体意思是 多态定义: 多态就是指程序中定义的引用变量所指向的具 ...

  9. Python 进阶 之 lambda 匿名函数

    lambda 是个匿名函数,通常用于简单判断或者处理,例如判断一个数的奇偶性,过滤字符串,逻辑运算等等. lambda表达式: >>>lambda x:x*x >>> ...

  10. Codeforces 1023 A.Single Wildcard Pattern Matching-匹配字符 (Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Fi)

    Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Patter ...