Java 非随机散列函数导致的应用程序漏洞
下面摘录自一篇文章,解释了由于哈希数据结构中使用的非随机哈希函数而导致拒绝服务(DoS)攻击的可能性 […]可以利用底层哈希算法中可预测的冲突来利用该条件 为了验证这一点,我查阅了Oracle Java HashMap的参考实现,并确实发现使用了一个静态哈希函数:Java 非随机散列函数导致的应用程序漏洞,java,security,ddos,Java,Security,Ddos,下面摘录自一篇文章,解释了由于哈希数据结构中使用的非随机哈希函数而导致拒绝服务(DoS)攻击的可能性 […]可以利用底层哈希算法中可预测的冲突来利用该条件 为了验证这一点,我查阅了Oracle Java HashMap的参考实现,并确实发现使用了一个静态哈希函数: static int hash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>>
static int hash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
关于这个话题的另一个例子是:
Tomcat6.0.32服务器在大约10分钟内解析2MB的冲突密钥字符串
44分钟的i7 CPU时间,因此大约6 kbit/s的攻击者可以持续保留一个i7内核
忙碌的。如果攻击者有千兆连接,他可以让大约100.000个i7内核保持忙碌
我们如何防范这种脆弱性。此外,我们使用的许多软件都是开源的(Tomcat等),依赖于此实现。受影响的Tomcat版本是Apache Tomcat=7.0.23作为固定版本。最简单的解决方案是升级到Tomcat的固定版本。然而,我怀疑你想知道tomcat人需要改变的细节 这种攻击的工作原理是利用散列数据结构的一个常见实现细节——使用链表保存散列相同的所有值。由于列表的大小越来越大,向该链接列表添加值的效率很低。攻击者可以创建已知会生成冲突哈希的值列表,从而强制执行这种低效行为。为了防止出现这种情况,您有以下几种选择:
- 防止冲突-通过在哈希函数中包含一些(伪)随机因子,防止攻击者生成冲突值。Perl已经做了很长时间了
- 在你的存储桶中使用链表之外的东西-攻击有效,因为在链表中插入N个项目会增加N^2。如果在插入时使用平衡树或其他具有N logN增长的结构,则问题应该得到缓解。这可能会牺牲一些最佳/平均情况性能,以限制最坏情况的严重程度 理解攻击向量 哈希映射的工作原理 假设博客上的评论表单接受参数–名字、姓氏、评论–作为帖子参数。在内部,Tomcat将这些参数存储为HashMap 此HashMap的逻辑结构如下所示-
"first_name" --> "Sripathi"
"last_name" --> "Krishnan"
"comment" ---> "DoS using poor Hashes"
但是物理结构不同。首先将键转换为哈希代码,然后将哈希代码转换为数组索引
因此,理想的物理结构成为——
0 --> "Sripathi"
1 --> "Krishnan"
2 --> "DoS using poor Hashes"
但可能的钥匙是无限的。因此,在某个时刻,两个键将具有相同的哈希代码。这将成为散列冲突
碰撞时,物理结构变为:
0 --> "Sripathi", "Krishnan"
1 --> Empty
2 --> "DoS using poor hashes"
哈希冲突及其对性能的影响
当您有散列冲突时,插入一个新条目意味着按顺序迭代单个散列“bucket”中的所有元素,以确定它是否已经存在于映射中。如果所有元素都散列为相同的值,则插入一个元素的复杂性接近O(n)。在这种最坏的情况下插入n个元素会使它变得O(n*n)复杂
简而言之:如果插入数千个具有相同哈希代码的密钥,服务器将需要大量CPU周期
如何使用相同的哈希生成密钥?
在Java中,“Aa”和“BB”具有相同的哈希代码
由于名为“等效子字符串”的属性,我们可以使用相同的哈希代码生成其他几个字符串,只需从这两个字符串开始
第一次迭代:“AAAA”、“AABb”、“BbAA”、“bbbbbb”具有相同的哈希代码
现在,我们有4个具有相同哈希代码的字符串。我们可以对它们进行排列,生成16个具有相同哈希代码的字符串。例如:
"AaAaAaAa", "AaAaBBBB", "AaAaAaBB", "AaAaBBAa",
"BBBBAaAa", "BBBBBBBB", "BBBBAaBB", "BBBBBBAa",
"AaBBAaAa", "AaBBBBBB", "AaBBAaBB", "AaBBBBAa",
"BBAaAaAa", "BBAaBBBB", "BBAaAaBB", "BBAaBBAa",
所有这16个字符串都具有相同的哈希代码
您现在可以获取这16个字符串,并生成256个具有相同哈希代码的字符串
简而言之:生成一大组具有精确哈希代码的字符串非常容易
如何攻击服务器?
仅供参考-Tomcat的文档在这里-当填充的条目达到阈值时,Java HashMap/HashTable可以执行“调整大小”操作。很难说有一个固定的bucket HashMap在等着你。因为
#!/usr/bin/python
import sys
alphabet = ["Aa","BB"]
def func(str, length):
global alphabet
if(length != 0):
for x in alphabet:
new_str = str+x
func(new_str, length-1)
else:
sys.stdout.write(str+"=&")
for x in range(1,16):
func("",x)