hashdos_调查HashDoS问题

hashdos

近一个月前,我就如何在不与供应商互动的情况下临时解决 28C3上出现的HashDoS问题或其他代码缺陷发表了一些想法。

现在是时候更深入地研究复杂性攻击并查看源了。 我完全假设java.util.HashMapjava.util.Hashtable是受此攻击影响的最常用的Java数据结构,因此本文仅将代码集中在这些类型的后面。

哈希函数和索引数据结构的简要介绍

哈希索引数据结构因其简单的用法和优点而非常受欢迎:

  • 无需打扰索引表即可找到所需数据的正确位置
  • 通过使用关键字而不是索引号访问数据
  • 添加或删除操作的时间几乎恒定

为了获得这些好处,哈希索引数据结构遵循有关如何索引数据的聪明思想。 索引是通过散列与背后数据关联的关键字来计算的。 考虑以下示例,这是一个类似于代码的简单示例:

myHashIndexedDataStructure [hash(keyword)] =特定数据

听起来很完美,但是它有一个主要缺点:在大多数情况下,使用的哈希函数不是加密函数。

根据Wikipedia的说法,函数本身调用哈希函数的唯一强制特征是

“将可变长度的大型数据集(称为键)映射到固定长度的较小数据集”

与称自己为密码哈希函数(再次是来自Wikipedia的定义)相反,它必须满足更多,甚至更强大的要求:

  • 计算任何给定消息的哈希值很容易(但不一定很快)
  • 生成具有给定哈希值的消息是不可行的
  • 在不更改哈希的情况下修改消息是不可行的
  • 找到两个具有相同哈希值的不同消息是不可行的


长话短说,让我们总结一下我们学到的知识以及用这些知识可以得出的结论:

  1. 哈希索引数据结构利用哈希函数
  2. 哈希函数不一定是抗冲突的,只要它们不是加密的
  3. 缺乏抗碰撞性意味着可以轻松计算具有相同哈希值的多个值

如果关键字冲突,则哈希索引数据结构需要某种计划b)–一种后备算法–关于如何处理具有相同关键字哈希值的多个数据集。

实际上,有几种可行的方法:

  • 探测(转移到固定或可计算的间隔)
  • 多重哈希
  • 条目链接(冲突条目的构建列表)
  • 覆盖现有条目

以下哪种策略需要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 ()函数来计算哈希值。 它遵循ANDing(&运算符),为了将其正确表示为Integer,MODULO(%运算符),将表大小(建立循环环结构:(table.length + 1)mod table.length?1,用余数除法)始终解决标签 []中的条目。
此后,将考虑所有条目 (-ies)并检查哈希值是否相同且对象本身是否相同。 if -clause防止存储同一对象的多个实例-旧的实例仅由新的实例替换。

如果在由key.hashCode ()标识的当前位置上找不到相同的对象(关于哈希值和equals ()方法),则将创建一个新的Entry,并将其放置在当前位置并在该位置处理旧的Entry对象。
到目前为止,看起来java.util.Hashtable在每个tab []之后都使用某种列表作为数据结构。

查看私有内部类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的代码更加复杂,并且表现部分不同(允许使用null值,!不同步!),但是基于相同的思想。 在这里调查代码不会发现任何新内容,除了Entry重新被重新实现的事实…)。

两种实现都依赖于哈希索引数组的每个条目后面的链接列表。

进攻思路

现在我们知道了java.util.Hashtablejava.util.HashMap背后的实现细节,我们可以回到称为HashDoS的攻击。 该攻击实现了Crosby,SA,Wallach,DS的想法: 通过算法复杂性攻击拒绝服务。 在:关于USENIX安全研讨会的第12届会议论文集–第12卷,USENIX协会(2003)
总结一下:散列索引的数据结构会因引发不利的状态而大大减慢速度。 理想的哈希索引数据结构如下所示:

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

在这种情况下,使用具有不同哈希值的关键字更改,删除或添加数据的时间几乎是恒定的。 通过使用关键字的哈希值作为索引,可以轻松找到位置,并且无需迭代列表即可立即显示数据。
让我们看一下哈希索引数据结构的另一种不利状态:

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

像这样的结构,CRUD操作的恒定时间已经结束了……

  1. 计算关键字的哈希值
  2. 遍历链表
  3. 比较每个条目的关键字(如果它与应用程序正在寻找的关键字匹配)

这会大大减慢处理线程的速度。 一个非常快的数据结构已经变成了一个链表,并带有额外的开销(计算哈希值)。 散列索引数据结构的所有好处都将被抹去。 好像还不够糟糕,大多数哈希索引数据结构都启用了称为重新哈希的功能。 当数据结构超过定义的负载(例如在Java中为75%)时,出于优化原因重新整理表。 大多数情况下,绝对希望使用此功能,但在这种特殊情况下,它甚至会减慢整个过程。

利用问题

要利用此行为,有必要计算一大堆冲突关键字。 例如,如果我们假设关键字的类型为java.lang.String ,我们可以看一下其hashCode ()函数:

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的自定义版本,可以在其中轻松发现冲突。
该函数具有一个有趣的属性,将在以下示例中进行演示:

"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 ...

我们看到碰撞值的串联再次导致碰撞值。 我们可以继续做下去,并获得大量碰撞关键字。 这使查找冲突比单纯的暴力破解更加容易。

我们针对本地Web服务对此进行了测试,并且可以通过使用冲突关键字作为标记属性来显着降低正在运行的Web应用程序服务器的速度。
我不确定是否确实可能使计算机崩溃,或者是否存在某种非显而易见的机制来防止服务器自行杀死(我们尚未在服务器端研究处理代码),但是可以肯定地阻止服务器在可接受的时间内正常运行。 对Web服务的请求很容易被延迟。

也许我会在不久的将来付出一些努力来收集测量数据(#colliding keys –系统响应时间)。 如果我这样做,您将在此博客上找到数据…

带你去的拐角点

  • 永远不要单独依赖hashCode() –容易出错
  • 避免像
    if(password.hashCode() == referencePassword.hashCode()) {
    return godMode;
  • 在决定/反对数据类型/结构时,花几秒钟的时间在实现细节上
  • 筛选传入的数据–裁剪其大小,拒绝超长参数等。
  • 小心,并始终注意编码最佳实践!

进一步有趣的观点

在此示例中,我们使用java.lang.String作为关键字对象。 有趣的是还可以使用什么,以及在JRE代码或大量使用的项目中,冲突的哈希值在何处用于数据结构或什至更坏的目的。
可以看看Object.hashCode ()是如何实现的(它是本机代码)–这将是一个不错的目标,因为所有其他对象都扩展了该基类。 如果扩展类没有覆盖hashCode ()函数,而是依赖于正确的,无冲突的输出,则这对于更复杂的攻击可能很有用。 考虑一下如果序列化依赖于相应的代码会发生什么……。

如果有人已经知道一些脆弱的地方,请告诉我们! 我们非常有兴趣,但是由于时间有限,无法达到我们想要的深度。

谢谢

我要再次感谢Juraj Somorovsky所做的丰富的联合研究工作! 此外,我们还要感谢oCERT团队的Andrea Barisani和红帽安全响应团队的 Vincent Danen ,他们与我们讨论了这个问题!

参考:从我们的JCG合作伙伴处 调查HashDoS问题   Java安全和相关主题博客中的Christopher Meyer。


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

hashdos

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ssb门限_画出滤波法ssb信号调制器模型,并说明低通和高通滤波器分别得到哪个边带信号...

匿名用户1级2016-05-25 回答如果输出已调信号的频谱和输入调制信号的频谱之间满足线性搬移关系&#xff0c;则称为线性调制&#xff0c;通常也称为幅度调制。线性调制的主要特征是调制前后的信号频谱从形状上看没有发生根本变化&#xff0c;仅仅是频谱的幅度和位置发生了变化。…

!doctype html报错h5,【Web前端问题】javascript import 报错

初学者, 想知道错误出在哪里&#xff0c;找到的资料都介绍的以下是我精简后的代码内容&#xff0c;错误提示在 main.js import那一行错误提示为&#xff1a;SyntaxError: Unexpected token ‘{‘. import call expects exactly one argumentindex.htmlLearnJavscriptbody{backg…

BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配

1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2375 Solved: 1005[Submit][Status][Discuss]Description Input Output Sample Input 1 3 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0Sample Output ˆ ˆHINT 对于30% 的数据满足1 ≤ n ≤ 12。对于100% 的…

idea 运行单个main方法_IntelliJ IDEA 运行你的第一个Java应用程序 idea运行main方法

打包文件 MANIFEST&period;MF 功能详解最近研究了如何在java工程打包,期间遇到的一些问题进行总结,如打包成test.jar 文件 Manifest-Version: 1.0 Main-Class: windows.VideoWindow ...第七课第四节&#xff0c;T语言流程语句(版本5&period;0)break语句 通常用在循环.遍…

Apache Spark中实现的MapReduce设计模式

该博客是该系列文章的第一篇&#xff0c;讨论了MapReduce设计模式一书中的一些设计模式&#xff0c;并展示了如何在Apache Spark&#xff08;R&#xff09;中实现这些模式。 在编写MapReduce或Spark程序时&#xff0c;考虑执行作业的数据流很有用。 即使Pig&#xff0c;Hive&a…

Token注解防止表单的重复提交

注解的一些基础&#xff1a; 参见http://blog.csdn.net/duo2005duo/article/details/50505884和 http://blog.csdn.net/duo2005duo/article/details/50511476这两篇文章 1&#xff0c;自定义一个注解Token 用来标记需要防止重复提交的方法 1 package com.bjca.framework.util;2…

计算机主机风扇安装方法,电脑机箱怎么安装风扇减震胶钉保护主板cup?

炎炎夏日&#xff0c;是时候给你的爱机清清灰&#xff0c;特别是对于机箱散热不好的朋友就需要给电脑机箱装上几个风力强劲的风扇&#xff0c;这样可以大大减少CPU、主板等的老化时间&#xff0c;延长爱机的寿命。现在机箱风扇大都使用橡胶拉钉(或者叫减震钉、固定钉)安装&…

2个css特效冲突了怎么办_患上类风湿病怎么办?2个方法拿走不谢

类风湿是一种常见的疾病&#xff0c;类风湿关节炎简称为类风湿&#xff0c;是一个累及周围关节为主的多系统性炎症性自身免疫病&#xff0c;患者的关节疼痛、肿胀&#xff0c;而且易反复发作。那么&#xff0c;得了类风湿病怎么办&#xff1f;得了类风湿病怎么办目前&#xff0…

将项目导入eclipse中出现的jsp页面报错

图片摘自百度经验&#xff0c;实在是每次都会忘了步骤&#xff0c;每次都得重新百度&#xff0c;所以索性自己总结到博客中&#xff0c;下次如果还记不住就直接从博客中看。原谅我实在学渣&#xff0c;呜呜~~~~(>_<)~~~~ 转载于:https://www.cnblogs.com/yangyufan/p/600…

怎样让计算机恢复到桌面上,如何把电脑桌面恢复成原样.怎么办?

此方案适用XP\VISTA\WIN7系统【问题描述】&#xff1a;桌面图标太多【原因分析】&#xff1a;1.下载的软件快捷方式放到桌面没有进行整理;2.在桌面上放置太多的文件【简易步骤】&#xff1a;【360安全卫士】—【功能大全】—【桌面管理】—【整理桌面个人资料】【解决方案】&am…

中装订线位置_企业宣传画册、产品目录常用的装订方法

印刷是个专业活&#xff0c;特别是画报、画册这些种类多&#xff0c;要求高。下面介绍一下最常用到的三种装订方法&#xff1a;骑马订骑马订(saddlestitch)英文是马鞍的意思&#xff0c;取其于装订之时&#xff0c;将摺好的页子如同为马匹上鞍一般的动作&#xff0c;配至装订机…

使用Hibernate在CQRS读取模型中进行快速开发

在这篇文章中&#xff0c;我将分享一些在CQRS读取模型中使用Hibernate工具进行快速开发的技巧。 为什么要休眠&#xff1f; 休眠非常流行。 从外观上看&#xff0c;它也很容易&#xff0c;而从内部看&#xff0c;它却相当复杂。 它可以很容易地开始使用&#xff0c;而无需进行…

iOS - Swift NSData 数据

本文目录 前言1、NSData 的创建2、数据的长度3、数据的获取4、NSData 的比较5、NSData 的存储6、NSData 与 字符串 的相互转换7、NSData 与 Base64编码字符串 的相互转换回到顶部前言 public class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding public cla…

美国东北大学khoury计算机学院,2021年美国东北大学计算机研究生专业有哪些?入学要求高吗?...

在“唯才是用”的时代&#xff0c;高新科技行业人才成为了社会的主流&#xff0c;各行各业也都急需计算机相关人才&#xff0c;美国可谓是计算机领域的鼻祖&#xff0c;拥有着非常先进的互联网技术&#xff0c;除此之外&#xff0c;几乎每所大学都开设了计算机专业&#xff0c;…

c++进制转换代码_轻松实现C/C++各种常见进制相互转换,你还不会你就落后了

这篇文章主要介绍了轻松实现C/C各种常见进制相互转换&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧其它进制转为十进制在实现这个需求之前&#xff0c;先简单介绍一…

我的博客是怎么自定义的

第一步&#xff0c;打开设置&#xff0c;一切都在设置里进行&#xff0c;让我们从头到尾&#xff0c;从左到右一步步讲。 1.头像 此头像不是账号头像&#xff0c;是标题那里放图片当头像 <img src"你头像的地址" alt"" /> 步骤&#xff1a;将你喜欢…

2017年计算机三级网络技术试题,2017年计算机三级网络技术考前试题及答案(8)

三、应用题(共20分)请根据下图所示网络结构回答问题。1&#xff0e;填写路由器RG的路由表项(每空2分&#xff0c;共l0分)。2&#xff0e;如果该网络内服务器群的IP地址为58&#xff0e;45&#xff0e;57&#xff0e;11-58&#xff0e;45&#xff0e;57&#xff0e;25&#xff0…

byte数组转为string_String类

API ----StringBufferjava.lang.Object 继承者 java.lang.Stringpublic final class String extends Object implements Serializable, Comparable<String>, CharSequenceYuSLi&#xff1a;String类速查速记​zhuanlan.zhihu.comYuSLi&#xff1a;补充&#xff1a;String…

AngularJS的学习笔记(二)

只给自己看的。 AngularJS 表达式 angularjs 使用表达式将数据绑定到html中。 AngularJS 表达式写在双大括号内&#xff1a;{{ expression }}。 AngularJS 表达式把数据绑定到 HTML&#xff0c;这与 ng-bind 指令有异曲同工之妙。 AngularJS 将在表达式书写的位置"输出&qu…

亚型多态性应用于元组的危险

Java 8具有lambda和stream&#xff0c;但是没有元组&#xff0c;这真是令人遗憾 。 这就是为什么我们在jOOλ中实现了元组-Java 8缺少的部分 。 元组确实是无聊的值类型容器。 本质上&#xff0c;它们只是这些类型的枚举&#xff1a; public class Tuple2<T1, T2> {publ…