這是迄今為止第一個讓我覺得後怕的攻擊方式,涉及的範圍廣難以防禦,攻擊效果立竿見影。大量的網站和web接口都未做hash碰撞攻擊的防禦,一拿一個準。
随着restful風格的接口普及,程式員預設都會使用json作為資料傳遞的方式。json格式的資料備援少,相容性高,從提出到現在已被廣泛的使用,可以說成為了web的一種标準。無論我們服務端使用什麼語言,我們拿到json格式的資料之後都需要做jsondecode(),将json串轉換為json對象,而對象預設會存儲于hash table,而hash table很容易被碰撞攻擊。我隻要将攻擊資料放在json中,服務端程式在做jsondecode()時必定中招,中招後cpu會立刻飙升至100%。16核的cpu,16個請求就能達到dos的目的。
所有測試程式都在mac pro下進行,為了測試友善我隻構造了65536條json鍵值對,真正發起攻擊時可以構造數十萬甚至百萬千萬的資料。
攻擊資料我已經轉換為json格式
<a href="https://raw.githubusercontent.com/laynefyc/php_thread_demo/master/hash.json">hash攻擊json資料</a>
<a href="https://raw.githubusercontent.com/laynefyc/php_thread_demo/master/hashnomal.json">普通json資料</a>
<a href="https://raw.githubusercontent.com/laynefyc/php_thread_demo/master/javahash.json">java版本hash攻擊資料</a>
一. javascript測試
我們隻需要在js中輸入一行代碼就能看到效果,普通資料和hash攻擊資料都是65536行鍵值對。我本地測試的效果如下:
通過chrome自帶的任務管理器可以看出cpu馬上升到100%,将近1分鐘才執行完成,而普通的資料幾毫秒就能執行完成;
二. php測試
php中我們通過file_get_contents遠端去拿資料,運作對比一下時間,相差10多秒,php-fpm單程序占用cpu 100%。
三. java測試
四. 其他語言還在研究中……
hashtable是很通用的資料結構,資料結構與算法上專門有一節課來說它,是以hash collision是普遍存在的,各語言在實作上隻是雜湊演算法和table存儲上有細微差别。
為了驗證java的hash碰撞攻擊也生效,我整個端午假期都在看java hashtable相關的文章,經過努力最後還是成功的生成了攻擊資料。過程非常不簡單,這也驗證了一個思想--所有高個上的東西最後分解出來都是基礎的資料結構知識。
幾年前php的版本還是5.2,我們可以把所有的hash key都放在post請求的body中,比如:
<a href="https://www.test.com/create-account">https://www.test.com/create-account</a> post data: k1=0&k2=0&k3=0...k999998=0&k999999=0
服務端拿到資料後會将所有參數存儲到hash table($_post)中,通過這種方式能很友善的實作攻擊。但是現在這種方式行不通了,因為我們很容易就能在nginx層和php層限制http請求的參數個數和大小。php預設隻允許1000個參數,這個量級對伺服器完全沒影響。
現在是2017年,json格式和restful風格的接口已經非常流行。帶給我們便捷編碼的同時,也給hash collision dos提供了新的方式。現在很多restful風格的接口如下:
<a href="https://www.test.com/v1">https://www.test.com/v1</a> data: {"action":"create-account","data":""}
如上接口,我們直接把攻擊的資料放入data參數中,服務端接收到資料後肯定會做jsondecode(),很友善的就達到了攻擊的目的。
要想防禦hash collision dos攻擊,行業内已經有很多成熟的方案了,不過都是建議換語言或者重寫hashtable。這裡隻說目前json格式解析的問題。首先我們需要增權重限驗證,最大可能的在jsondecode()之前把非法使用者拒絕。其次在jsondecode()之前做資料大小與參數白名單驗證。舊項目的改造與維護成本如果很高,建議自己重寫jsondecode()方法。
寫了這麼多,其實最有樂趣的地方還是如何生成攻擊資料。之後我會詳細的寫這部分。最後,golang和python能躲過hash collision dos測試嗎?敬請期待