日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

调查HashDoS问题

發(fā)布時間:2023/12/3 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 调查HashDoS问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
近一個月前,我就如何在不與供應商互動的情況下臨時解決 28C3上出現(xiàn)的HashDoS問題或其他代碼缺陷發(fā)表了一些想法。

現(xiàn)在是時候更深入地研究復雜性攻擊并查看來源了。 我完全假設java.util.HashMapjava.util.Hashtable是受此攻擊影響的最常用的Java數(shù)據(jù)結構,因此本文僅將代碼集中在這些類型的后面。

哈希函數(shù)和索引數(shù)據(jù)結構的簡要介紹

哈希索引數(shù)據(jù)結構因其簡單的用法和優(yōu)點而非常受歡迎:

  • 無需打擾索引表即可找到所需數(shù)據(jù)的正確位置
  • 通過使用關鍵字而不是索引號訪問數(shù)據(jù)
  • 添加或刪除操作的時間幾乎恒定

為了獲得這些好處,哈希索引數(shù)據(jù)結構遵循有關如何對數(shù)據(jù)進行索引的聰明思想。 索引是通過散列與背后數(shù)據(jù)關聯(lián)的關鍵字來計算的。 考慮以下示例,這是一個類似于代碼的簡單示例:

myHashIndexedDataStructure [hash(keyword)] =特定數(shù)據(jù)

聽起來很完美,但是它有一個主要缺點:在大多數(shù)情況下,使用的哈希函數(shù)不是加密函數(shù)。

根據(jù)Wikipedia的說法,函數(shù)自行調用哈希函數(shù)的唯一強制特征是

“將可變長度的大型數(shù)據(jù)集(稱為鍵)映射到固定長度的較小數(shù)據(jù)集”

與稱自己為密碼哈希函數(shù)(再次是來自Wikipedia的定義)相反,它必須滿足更多,甚至更強大的要求:

  • 計算任何給定消息的哈希值很容易(但不一定很快)
  • 生成具有給定哈希值的消息是不可行的
  • 在不更改哈希值的情況下修改消息是不可行的
  • 找到兩個具有相同哈希值的不同消息是不可行的


長話短說,讓我們總結一下我們學到的知識以及用這些知識得出的結論:

  • 哈希索引數(shù)據(jù)結構利用哈希函數(shù)
  • 哈希函數(shù)不一定是抗沖突的,只要它們不是加密的
  • 缺乏抗沖突性意味著可以輕松計算具有相同哈希值的多個值
  • 如果關鍵字沖突,則哈希索引數(shù)據(jù)結構需要某種計劃b)–一種后備算法–關于如何處理具有相同關鍵字哈希值的多個數(shù)據(jù)集。

    實際上,有幾種可行的方法:

    • 探測(轉移到固定或可計算的間隔)
    • 多重哈希
    • 條目鏈接(沖突條目的構建列表)
    • 覆蓋現(xiàn)有條目

    以下哪種策略需要Java? 首先,我們將檢查java.util的代碼。 Hashtable (僅顯示有趣的部分,為清晰起見,其余代碼被省略了:

    public synchronized V put(K key, V value) { ... // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) %tab.length; for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) { if((e.hash == hash) && e.key.equals(key)) { V old = e.value; e.value = value; return old; } } ... // Creates the new entry. Entry<K,V> e = tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; return null; }

    可以看出,此類使用鍵對象( 關鍵字 )的hashCode ()函數(shù)來計算哈希值。 它遵循ANDing(&運算符),為了將其正確表示為Integer,MODULO(%運算符),將表大小(建立循環(huán)環(huán)結構:(table.length + 1)mod table.length?1,除以余數(shù))始終解決標簽 []中的條目。
    此后,將考慮所有條目 (-ies)并檢查哈希值是否相同以及對象本身是否相同。 if -clause防止存儲同一對象的多個實例–舊的實例僅由新的實例替換。

    如果在key.hashCode ()標識的當前位置上找不到相同的對象(關于哈希值和equals ()方法),則將創(chuàng)建一個新的Entry,將其放置在當前位置并在該位置處理舊的Entry對象。
    到目前為止,看起來java.util.Hashtable在每個tab []之后都使用某種列表作為數(shù)據(jù)結構。

    查看私有內部類java.util.Hashtable.Entry <K,V>的代碼時,可以確認此假設。

    private static class Entry<K,V> implements Map.Entry<K,V> { int hash; K key; V value; Entry<K,V> next;

    下一個Entry對象僅指向下一個Entry 。 這代表一個定制的鏈表。
    java.util.HashMap的代碼更加復雜,并且表現(xiàn)部分不同(允許使用null值,!不同步!),但是基于相同的思想。 在這里調查代碼不會發(fā)現(xiàn)任何新內容,除了Entry重新被重新實現(xiàn)的事實…)。

    兩種實現(xiàn)都依賴于哈希索引數(shù)組的每個條目后面的鏈接列表。

    進攻思路

    現(xiàn)在我們知道了java.util.Hashtablejava.util.HashMap背后的實現(xiàn)細節(jié),我們可以回到稱為HashDoS的攻擊。 該攻擊實現(xiàn)了Crosby,SA,Wallach,DS的想法: 通過算法復雜性攻擊拒絕服務。 在:第十二屆USENIX安全研討會的會議記錄–第12卷,USENIX協(xié)會(2003)
    總結一下:散列索引的數(shù)據(jù)結構可能會因引發(fā)不利的狀態(tài)而大大減慢速度。 理想的哈希索引數(shù)據(jù)結構如下所示:

    ... table[hash(keyA)] = dataA table[hash(keyB)] = dataB table[hash(keyC)] = dataC table[hash(keyD)] = dataD ...

    在這種情況下,使用具有不同哈希值的關鍵字更改,刪除或添加數(shù)據(jù)的時間幾乎是恒定的。 通過使用關鍵字的哈希值作為索引,可以輕松找到位置,并且無需迭代列表即可立即顯示數(shù)據(jù)。
    讓我們看一下哈希索引數(shù)據(jù)結構的另一種不利狀態(tài):

    ... hash(keyA) == hash(keyB) == hash(keyC) == hash(keyD)= k table[k] = dataA -> dataB -> dataC -> dataD ...

    像這樣的結構,CRUD操作的恒定時間已經(jīng)結束了……

  • 計算關鍵字的哈希值
  • 遍歷鏈表
  • 比較每個條目的關鍵字(如果它與應用程序正在尋找的關鍵字匹配)
  • 這會大大減慢處理線程的速度。 一個非常快的數(shù)據(jù)結構已變成一個鏈表,并帶有額外的開銷(計算哈希值)。 散列索引數(shù)據(jù)結構的所有好處都將被抹去。 好像還不夠糟糕,大多數(shù)哈希索引數(shù)據(jù)結構都啟用了稱為重新哈希的功能。 當數(shù)據(jù)結構超過定義的負載(例如,在Java中為75%)時,出于優(yōu)化原因,將重新整理表。 大多數(shù)情況下,絕對希望使用此功能,但在這種特殊情況下,它甚至會減慢整個過程。

    利用問題

    要利用此行為,必須計算出一大堆沖突關鍵字。 例如,如果我們假設關鍵字的類型為java.lang.String ,我們可以看一下其hashCode ()函數(shù):

    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; } return h; }

    這似乎是DJ Bernstein設計的功能DJBX33A的自定義版本,可以很容易地發(fā)現(xiàn)沖突。
    該函數(shù)具有一個有趣的屬性,將在以下示例中進行演示:

    "0w".hashCode() = 1607 "1X".hashCode() = 1607 "29".hashCode() = 1607 "0w1X".hashCode() = 1545934 "0w29".hashCode() = 1545934 "1X0w".hashCode() = 1545934 "1X29".hashCode() = 1545934 "290w".hashCode() = 1545934 "291X".hashCode() = 1545934 ...

    我們看到碰撞值的串聯(lián)再次導致碰撞值。 我們可以繼續(xù)做下去,并獲得大量碰撞關鍵字。 這使查找沖突比單純的暴力破解更加容易。

    我們針對本地Web服務對此進行了測試,并且可以通過使用沖突關鍵字作為標記屬性來顯著降低正在運行的Web應用程序服務器的速度。
    我不確定是否真的可能使計算機崩潰,或者是否存在某種非顯而易見的機制來防止服務器自行殺死(我們尚未在服務器端研究處理代碼),但是可以肯定地阻止服務器在可接受的時間內正常運行。 對Web服務的請求很容易被延遲。

    也許我會在不久的將來付出一些努力來收集測量數(shù)據(jù)(#colliding keys –系統(tǒng)響應時間)。 如果我這樣做,您將在此博客上找到數(shù)據(jù)…

    帶你去的拐角點

    • 永遠不要只依賴hashCode() –容易出錯
    • 避免像
      if(password.hashCode() == referencePassword.hashCode()) {
      } else {
    • 在決定/反對數(shù)據(jù)類型/結構時,花幾秒鐘的時間在實現(xiàn)細節(jié)上
    • 篩選傳入的數(shù)據(jù)–裁剪其大小,拒絕超長參數(shù)等。
    • 小心,并始終注意編碼最佳實踐!

    進一步有趣的觀點

    在此示例中,我們使用java.lang.String作為關鍵字對象。 有趣的是還可以使用什么,以及在JRE代碼或大量使用的項目中,沖突的哈希值在何處用于數(shù)據(jù)結構或什至更糟糕的目的。
    可以看看Object.hashCode ()是如何實現(xiàn)的(它是本機代碼)–這將是一個不錯的目標,因為所有其他對象都擴展了該基類。 如果擴展類沒有覆蓋hashCode ()函數(shù),而是依賴于正確的,無沖突的輸出,則這對于更復雜的攻擊可能很有用。 考慮一下如果序列化依賴于相應的代碼會發(fā)生什么……。

    如果有人已經(jīng)知道一些脆弱的地方,請告訴我們! 我們非常有興趣,但是由于時間有限,無法達到我們想要的深度。

    謝謝

    我要再次感謝Juraj Somorovsky所做的豐富的聯(lián)合研究工作! 此外,我們還要感謝oCERT團隊的Andrea Barisani和紅帽安全響應團隊的 Vincent Danen ,他們與我們討論了這個問題!

    參考:從我們的JCG合作伙伴處 調查HashDoS問題 ? Java安全和相關主題博客中的Christopher Meyer。


    翻譯自: https://www.javacodegeeks.com/2012/02/investigating-hashdos-issue.html

    總結

    以上是生活随笔為你收集整理的调查HashDoS问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。