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
歡迎關注本站公眾號,獲取更多信息