K:hash(哈希)碰撞攻击
相關介紹:
?哈希表是一種查找效率極高的數據結構,很多語言都在內部實現了哈希表。理想情況下哈希表插入和查找操作的時間復雜度均為O(1),任何一個數據項可以在一個與哈希表長度無關的時間內計算出一個哈希值(key),然后在常量時間內定位到一個桶(術語bucket,表示哈希表中的一個位置)。當然這是理想情況下,因為任何哈希表的長度都是有限的,所以一定存在不同的數據項具有相同哈希值的情況。此時,不同數據項被定為到同一個桶,稱為碰撞(collision)。哈希表的實現需要解決碰撞問題,碰撞解決大體有兩種思路,第一種是根據某種原則將被碰撞數據定為到其它桶,例如線性探測——如果數據在插入時發生了碰撞,則順序查找這個桶后面的桶,將其放入第一個沒有被使用的桶;第二種策略是每個桶不是一個只能容納單個數據項的位置,而是一個可容納多個數據的數據結構(例如鏈表或紅黑樹),所有碰撞的數據以某種數據結構的形式組織起來。
?不論使用了哪種碰撞解決策略,都導致插入和查找操作的時間復雜度不再是O(1)。以查找為例,不能通過key定位到桶就結束,必須還要比較原始key(即未做哈希之前的key)是否相等,如果不相等,則要使用與插入相同的算法繼續查找,直到找到匹配的值或確認數據不在哈希表中。
?在java中,對于HashMap,hash碰撞的解決是將每個桶轉化為容納多個數據項的數據結構,在一開始時,會采用單鏈表的方式進行組織,而在桶中容量達到一定的程度時,將容納多個數據項的數據結構轉化為紅黑樹。如下圖,其顯示了正常的hash表和退化后的hash表:
?哈希表碰撞攻擊就是通過精心構造數據,使得所有數據全部碰撞,人為將哈希表變成一個退化的單鏈表,此時哈希表各種操作的時間均提升了一個數量級,因此會消耗大量CPU資源,導致系統無法快速響應請求,從而達到拒絕服務攻擊(DoS)的目的。
?從中可知,進行哈希碰撞攻擊的前提是哈希算法特別容易找出碰撞,如果是MD5或者SHA1那基本就沒戲了,幸運的是(也可以說不幸的是)大多數編程語言使用的哈希算法都十分簡單(這是為了效率考慮),因此可以不費吹灰之力之力構造出攻擊數據。
?你可以會覺得這個問題沒有什么大不了的,因為黑客是看不到hash算法的,如果你這么認為,那么你就錯了,這說明對Web編程的了解還不足夠底層。
?無論你用JSP,PHP,Python,Ruby來寫后臺網頁的時候,在處理HTTP POST數據的時候,你的后臺程序可以很容易地以訪問表單字段名來訪問表單值,就像下面這段程序一樣:
String name=request.getParameter("name");這是怎么實現的呢?這后面的東西就是Hash Map啊,所以,我可以給你后臺提交一個有10K字段的表單,這些字段名都被我精心地設計過,他們全是Hash Collision ,于是你的Web Server或語言處理這個表單的時候,就會建造這個hash map,于是在每插入一個表單字段的時候,都會先遍歷一遍你所有已插入的字段,于是你的服務器的CPU一下就100%了,你會覺得這10K沒什么,那么我就發很多個的請求,你的服務器可能一下子就不行了。
?在java中,使用的Hash算法是“非隨機的”,以下是java7中hashMap的hash函數的源碼:
static int hash(int h) {// This function ensures that hashCodes that differ only by// constant multiples at each bit position have a bounded// number of collisions (approximately 8 at default load factor).h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4); }所謂“非隨機的”Hash算法,就可以猜。比如:
在Java里,Aa和BB這兩個字符串的hash code(或hash key)是一樣的,也就是Collision 。
于是,我們就可以通過這兩個種子生成更多的擁有同一個hash key的字符串。如:”AaAa”, “AaBB”, “BBAa”, “BBBB”。這是第一次迭代。其實就是一個排列組合,寫個程序就搞定了。
然后,我們可以用這4個長度的字符串,構造8個長度的字符串,如下所示:
"AaAaAaAa", "AaAaBBBB", "AaAaAaBB", "AaAaBBAa",
"BBBBAaAa", "BBBBBBBB", "BBBBAaBB", "BBBBBBAa",
"AaBBAaAa", "AaBBBBBB", "AaBBAaBB", "AaBBBBAa",
"BBAaAaAa", "BBAaBBBB", "BBAaAaBB", "BBAaBBAa"
在攻擊時,我只需要把這些數據做成一個HTTP POST表單,然后寫一個無限循環的程序,不停地提交這個表單。你用你的瀏覽器就可以了。當然,如果做得更精妙一點的話,把你的這個表單做成一個跨站腳本,然后找一些網站的跨站漏洞,放上去,于是通過SNS的力量就可以找到N多個用戶來幫你從不同的IP來攻擊某服務器。
防守:
要防守這樣的攻擊,有下面幾個招:
不過,對于更底層的或是其它形式的攻擊,可能就有點麻煩了。
@參考自博文:哈希碰撞攻擊是什么? 以及 Hash碰撞的拒絕式服務攻擊
回到目錄|·(工)·)
轉載于:https://www.cnblogs.com/MyStringIsNotNull/p/8241228.html
總結
以上是生活随笔為你收集整理的K:hash(哈希)碰撞攻击的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#的几个学习要点
- 下一篇: js复制功能的有效方法总结新