Hash碰撞致使的denial of service
这种攻击方式最先在03年的时候就被提出来了,可是当初各类攻击的方式太多了,像这种不能拿服务器权限的ddos攻击方式中的一种没有引发你们太多的关注,当时出的pdf文档以下:
http://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec2003.pdf
最近有人又提出了这种攻击方式,而且统计了一下目前大多数的语言都受到了影响
目前已知的受影响的语言以及版本有
:
:
Java, 全部版本、JRuby <= 1.6.五、
PHP
<= 5.3.8, <= 5.4.0RC三、Python, 全部版本、Rubinius, 全部版本、Ruby <= 1.8.7-p35六、Apache Geronimo, 全部版本、Apache Tomcat <= 5.5.34, <= 6.0.34, <= 7.0.2二、Oracle Glassfish <= 3.1.一、Jetty, 全部版本、Plone, 全部版本、Rack, 全部版本、V8
Java
Script Engine, 全部版本
不受此影响的语言或者修复版本的语言有
:
:
PHP >= 5.3.9, >= 5.4.0RC四、JRuby >= 1.6.5.一、Ruby >= 1.8.7-p357, 1.9.x、Apache Tomcat >= 5.5.35, >= 6.0.35, >= 7.0.2三、
Oracle
Glassfish
让咱们了解下这种攻击的主要原理(以java语言为例):
1. HashMap
的工做原理
当客户端提交一个请求并附带参数的时候,web应用服务器会把咱们的参数转化成一个HashMap存储,这个HashMap的逻辑结构以下:
key1-->value1;
key2-->value2;
key3-->value3;
…………
可是物理存储结构是不一样的,key值会被转化成Hashcode,这个hashcode有会被转成数组的下标:
0-->value1;
1-->value2;
2-->value3;
…………
hashcode是一个32位的整数,2^32次方大约在40多亿,就是说总数是必定的,可是key值有无限种可能,因此不一样的string就会产生相同hashcode而致使碰撞,碰撞后的物理存储结构可能以下:
0-->value1-->value2;
1-->空;
2-->value3;
…………
2. Hash
碰撞对性能的影响
当产生一个碰撞的hashcode,须要插入到这个HashMap的时候他回去对应的下标序列顺序查找全部的项,看是否已经存在,因此产生一个新的hashcode碰撞插入到一个已经存在n个相同hashcode的数组下标项中的时候消耗的性能大概为O(n),可是若是是n个相同hashcode插入到已经n个hashcode的数组下标中时,须要比较消耗的性能就是O(n*n)了
3.
怎么生成相同的
hashcode
java中生成hashcode的方法为String.hashCode();
public int hashCode() {
int h=hash;
if(h==0){
int off = offset;
char val[]=value;
int len = count;
for(int i=0;i<len;i++) {
h=31*h+val[off++];
}
hash=h;
}
换成推导公式就是 s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] (注:使用 int 算法,这里 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂)这里的自定义乘数为何要用“31”,这个就是数学上的一些经验吧,具体我也不是很清楚,可是选31这个质数能保证hash碰撞的概率最小。从这个算法中咱们能够看到是没有随机化,也就是说咱们能够本身构造具备相同hashcode的string,甚至能够根据想要的hashcode值来反推出大量咱们想要的string字符串,具体的代码就不放出来了,可是咱们能够根据这个公式获得一些比较简单的具备相同hashcode的string,好比:Aa和BB,两次for循环,Aa的第一次for循环获得h的值为A的asc值65,第二次就是31*65+(a的asc值97)也就是2112一样能够算出BB的hashcode也是2112,这里就有一个碰撞了
根据这两个,咱们能够知道以下4个也具备相同的hashcode: "AAAA", "AABb", "BbAA", "BbBb"进一步,咱们能够知道以下字符串在java里面具备相同的hashcode:"AaAaAaAa","AaAaBBBB","AaAaAaBB","AaAaBBAa",
"BBBBAaAa","BBBBBBBB","BBBBAaBB","BBBBBBAa",
"AaBBAaAa","AaBBBBBB","AaBBAaBB","AaBBBBAa",
"BBAaAaAa","BBAaBBBB","BBAaAaBB","BBAaBBAa",其实Bb和CC、Cc和DD都具备同样的hashcode,他们的组合BbCCCcDD和CCCCCcDD也有同样的hashcode复杂一点的:
8SImjKsEaWZX[Uqp_
a5alI\II=QZglaY`o
pfx>yDOoSL[^mhVck
dEY<A`@FBw[k[c_i`
<>^T;B=4Ss[osjZV]
>KCD?7f[>>Uiqrra_
…………
都具备相同的hashcode:123456
4.
怎么攻击
1. 构造几千个具备相同hashcode的参数名
2. 构造POST表单进行提交(固然GET也能够,就是限制比POST大)像"AaAa=&AaBB=……"
3. 构造多个线程重复提交,单机就能够打死小站
5.
怎么防护
1. 限制post和get的参数个数,越少越好
2. 限制post数据包的大小
3. WAF
欢迎关注本站公众号,获取更多信息