首頁  >  文章  >  Java  >  一種進階的DoS攻擊-Hash碰撞攻擊

一種進階的DoS攻擊-Hash碰撞攻擊

怪我咯
怪我咯原創
2017-06-23 12:01:242255瀏覽

原文連結

這是迄今為止第一個讓我覺得後怕的攻擊方式,涉及的範圍廣難以防禦,攻擊效果立竿見影。大量的網站和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鍵值對,真正發動攻擊時可以建構數十萬甚至百萬千萬的資料。

幾個簡單的Demo

攻擊資料我已經轉換為json格式

  1. #Hash攻擊json資料

  2. 普通json資料

  3. Java版本Hash攻擊資料

#一. JavaScript測試

//只需要一行代码就能看到效果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("指定文件不存在");//处理异常
    }

    Map14bd1badcdee783757181db757c9943f map = new HashMap14bd1badcdee783757181db757c9943f();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中,例如:


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風格的介面如下:


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

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

如何防禦

要想防禦Hash Collision Dos攻擊,業界已經有很多成熟的方案了,不過都是建議換語言或重寫HashTable。這裡只說當前json格式解析的問題。首先我們要增加權限驗證,最大可能的在jsonDecode()之前把非法使用者拒絕。其次在jsonDecode()之前做資料大小與參數白名單驗證。舊專案的改造與維護成本如果很高,建議自己重寫jsonDecode()方法

以上是一種進階的DoS攻擊-Hash碰撞攻擊的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn