【转载】网络攻击技术(三)——Denial Of Service & 哈希相关 & PHP语言 & Java语言
找到了这个系列的原始作者:
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语言的更多相关文章
- java语言体系的技术简介之JSP、Servlet、JDBC、JavaBean(Application)
转自:https://zhangkunnan.iteye.com/blog/2040462 前言 Java语言 Java语言体系比较庞大,包括多个模块.从WEB项目应用角度讲有JSP.Servlet. ...
- 分布式拒绝服务攻击(DDoS:Distributed Denial of Service)
DDoS攻击通过大量合法的请求占用大量网络资源,以达到瘫痪网络的目的. 指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力. ...
- 【安全研究】Domain fronting域名前置网络攻击技术
出品|MS08067实验室(www.ms08067.com) 千里百科 Domain Fronting基于HTTPS通用规避技术,也被称为域前端网络攻击技术.这是一种用来隐藏Metasploit,Co ...
- DDoS(Distributed Denial of Service,分布式拒绝服务)
DDoS:Distributed Denial of Service,即分布式拒绝服务攻击. 借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高 ...
- Distributed Denial of Service
Distributed Denial of Service https://www.cnblogs.com/163yun/p/10030890.html 全称Distributed Denial of ...
- Slow HTTP Denial of Service Attack
整改建议 1.中断使用URL不支持HTTP方法访问的会话 2.限制HTTP头及包长至一个合理数值 3.设置一个绝对的会话超时时间 4.服务器支持backlog的情况下,需设置一个合理的大小 5.设置一 ...
- Slow HTTP Denial of Service Attack漏洞整改方法
前期现场反馈系统扫描出Slow HTTP Denial of Service Attack漏洞,根据以往经验提供了更改建议,居然没有生效,深入研究了一下WebLogic下该漏洞的修复方法,现记录如下: ...
- 网络攻击技术:SQL Injection(sql注入)
网络攻击技术开篇——SQL Injection 1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库被黑客公开发布,600万用户的登录名及密码被公开泄露,随后又有多家网站的用户密码 ...
- WebGoat系列实验Denial of Service & Insecure Communication
WebGoat系列实验Denial of Service & Insecure Communication ZipBomb 服务器仅接收ZIP文件,将上传的文件解压,进行操作之后删除.已知服务 ...
随机推荐
- bzoj 2190 线性生成欧拉函数表
首先我们知道,正方形内个是对称的,关于y=x对称,所以只需要算出来一半的人数 然后乘2+1就行了,+1是(1,1)这个点 开始我先想的递推 那么我们对于一半的三角形,一列一列的看,假设已经求好了第I- ...
- linux驱动学习(八) i2c驱动架构(史上最全) davinc dm368 i2c驱动分析【转】
转自:http://blog.csdn.net/ghostyu/article/details/8094049 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 预备知识 lin ...
- 关于might_sleep的一点说明---CONFIG_DEBUG_ATOMIC_SLEEP【转】
转自:http://blog.chinaunix.net/uid-23769728-id-3157536.html 这个函数我在看代码时基本上是直接忽略的(因为我知道它实际上不干什么事),不过因为内核 ...
- 【反演复习计划】【51nod1594】Gcd and Phi
现在感觉反演好多都是套路QAQ…… #include<bits/stdc++.h> using namespace std; ; typedef long long ll; int n,c ...
- jQuery插件--zTree中点击节点实现页面跳转时弹出两个页面的问题
这是第一次使用zTree,所以在使用之前我要先写一个demo来学习一下.我们要注意的是,zTree是一个jQuery插件,所以我们在导入zTree的js文件之前要先导入jQuery的js文件. 我们先 ...
- 【C++】指针和new相关
看黄邦勇帅的笔记. 指针和new之前觉得已经掌握的很好了,可是看了资料还是get到了新知识.记录一下. 1.指针只支持 4 种算术运算符:++,――,+,-.指针只能与整数加减.指针运算的原则是:每当 ...
- 2017/3/7 值得"纪念"的错误
使用viewpager和fragment做个能左右滑动的效果,结果怎么弄怎么有问题,先是怀疑什么viewPager维护刷新内部fragment什么的,又是在FragmentPageAdapter的ge ...
- css行高line-height的用法
一.line-height语法 line-height属性的具体定义列表如下: 语法: line-height : normal | <实数> | <长度> | <百分比 ...
- radio和label关联问题,点击label改变颜色
$(function () { $("#fangan :radio[name='price']").bind('click', function (event) { //$(thi ...
- HDU 1015 Safecracker【数值型DFS】
Safecracker Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...