一種高級的DoS攻擊-Hash碰撞攻擊

原文連接php

這是迄今爲止第一個讓我以爲後怕的攻擊方式,涉及的範圍廣難以防護,攻擊效果立竿見影。大量的網站和Web接口都未作Hash碰撞攻擊的防護,一拿一個準。java

隨着RESTful風格的接口普及,程序員默認都會使用json做爲數據傳遞的方式。json格式的數據冗餘少,兼容性高,從提出到如今已被普遍的使用,能夠說成爲了Web的一種標準。不管咱們服務端使用什麼語言,咱們拿到json格式的數據以後都須要作jsonDecode(),將json串轉換爲json對象,而對象默認會存儲於Hash Table,而Hash Table很容易被碰撞攻擊。我只要將攻擊數據放在json中,服務端程序在作jsonDecode()時一定中招,中招後CPU會馬上飆升至100%。16核的CPU,16個請求就能達到DoS的目的。git

全部測試程序都在Mac Pro下進行,爲了測試方便我只構造了65536條json鍵值對,真正發起攻擊時能夠構造數十萬甚至百萬千萬的數據。程序員

幾個簡單的Demo

攻擊數據我已經轉換爲json格式github

  1. Hash攻擊json數據算法

  2. 普通json數據json

  3. Java版本Hash攻擊數據瀏覽器

一. JavaScript測試bash

//只須要一行代碼就能看到效果 var jsonSrc = '這裏輸入json數據'; 

咱們只須要在js中輸入一行代碼就能看到效果,普通數據和Hash攻擊數據都是65536行鍵值對。我本地測試的效果以下:
經過Chrome自帶的任務管理器能夠看出CPU立刻升到100%,將近1分鐘才執行完成,而普通的數據幾毫秒就能執行完成;服務器

二. PHP測試

$json = file_get_contents("https://raw.githubusercontent.com/laynefyc/php_thread_demo/master/hashNomal.json"); $startTime = microtime(true); $arr = json_decode($json,true); $endTime = microtime(true); echo "Nomal:".($endTime - $startTime)."\r\n"; $json = file_get_contents("https://raw.githubusercontent.com/laynefyc/php_thread_demo/master/hash.json"); $startTime = microtime(true); $arr = json_decode($json,true); $endTime = microtime(true); echo "Attack:".($endTime - $startTime)."\r\n"; 

PHP中咱們經過file_get_contents遠程去拿數據,運行對比一下時間,相差10多秒,php-fpm單進程佔用CPU 100%。

三. Java測試

public String index(){ String jsonStr = ""; try { FileReader fr = new FileReader("t.log");//須要讀取的文件路徑 BufferedReader br = new BufferedReader(fr); jsonStr = br.readLine(); br.close(); fr.close(); //關閉文件流 }catch(IOException e) { System.out.println("指定文件不存在");//處理異常 } Map<String, Object> map = new HashMap<String, Object>(); map = JSONObject.fromObject(jsonStr); return "Hash Collision ~"; } 

Java中咱們經過讀文件的方式作測試,Java的Hash算法與PHP和JavaScript有略微的差異,可是大同小異,咱們一樣構造了6萬行簡單的數據。Spring boot框架中瀏覽器發起一次訪問,26秒以後才返回結果,期間CPU被打滿。

四. 其餘語言還在研究中……

HashTable是很通用的數據結構,數據結構與算法上專門有一節課來講它,因此Hash Collision是廣泛存在的,各語言在實現上只是散列算法和Table存儲上有細微差異。

爲了驗證Java的Hash碰撞攻擊也生效,我整個端午假期都在看Java HashTable相關的文章,通過努力最後仍是成功的生成了攻擊數據。過程很是不簡單,這也驗證了一個思想--全部高個上的東西最後分解出來都是基礎的數據結構知識。

如何攻擊

幾年前PHP的版本仍是5.2,咱們能夠把全部的Hash Key都放在POST請求的Body中,好比:

https://www.test.com/create-account

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風格的接口以下:

https://www.test.com/v1

Data: {"action":"create-account","data":""}

如上接口,咱們直接把攻擊的數據放入data參數中,服務端接收到數據後確定會作jsonDecode(),很方便的就達到了攻擊的目的。

如何防護

要想防護Hash Collision Dos攻擊,行業內已經有不少成熟的方案了,不過都是建議換語言或者重寫HashTable。這裏只說當前json格式解析的問題。首先咱們須要增長權限驗證,最大可能的在jsonDecode()以前把非法用戶拒絕。其次在jsonDecode()以前作數據大小與參數白名單驗證。舊項目的改造與維護成本若是很高,建議本身重寫jsonDecode()方法。

未完待續

寫了這麼多,其實最有樂趣的地方仍是如何生成攻擊數據。以後我會詳細的寫這部分。最後,Golang和Python能躲過Hash Collision Dos測試嗎?敬請期待

原文連接

相關文章
相關標籤/搜索