非随机哈希函数导致的应用程序漏洞了解攻击媒介预防

2022-09-01 05:15:40

下面的摘录来自一篇文章,该文章解释了由于哈希数据结构中使用的非随机哈希函数而导致的拒绝服务(DoS)攻击的可能性。

[...]可以通过利用基础哈希算法中的可预测冲突来利用该条件。

为了验证它,我浏览了Oracle的Java HashMap的参考实现,确实发现了一个静态哈希函数:

    static int hash(int h) {
       h ^= (h >>> 20) ^ (h >>> 12);
       return h ^ (h >>> 7) ^ (h >>> 4);
    }

另一篇关于这个主题的论文讲述了:

Tomcat 6.0.32 服务器在大约 44 分钟的 i7 CPU 时间内解析出一串 2 MB 的碰撞密钥,因此具有大约 6 kbit/s 的攻击者可以让一个 i7 核心持续忙碌。如果攻击者具有千兆位连接,他可以保持大约100.000个i7内核的忙碌

我们如何防范此漏洞。此外,对于许多依赖于此实现的开源软件(Tomcat等),我们使用的软件也是如此。


答案 1

了解攻击媒介

哈希映射的工作原理

假设博客上的评论表单接受参数 ( first_name、last_name、评论 ) 作为帖子参数。在内部,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"

哈希冲突及其对性能的影响

当您遇到哈希冲突时,插入新条目意味着按顺序迭代单个哈希“存储桶”中的所有元素,只是为了确定它是否已经存在于映射中。如果所有元素都散列到相同的值,则插入一个元素可以接近O(n)复杂性。在这种最坏的情况下插入n个元素会使它变得O(n*n)复杂。

简而言之:如果您插入数千个具有相同哈希码的密钥,则服务器将需要大量的CPU周期。

如何使用相同的哈希生成密钥?

在Java中,“Aa”和“BB”具有相同的哈希代码。

由于一个名为“等效子字符串”的属性,我们可以使用相同的哈希码生成其他几个字符串,只需从这2个字符串开始即可。

第一次迭代:“AAAA”,“AABb”,“BbAA”,“BbBb”具有相同的哈希代码

现在,我们有4个具有相同哈希代码的字符串。我们可以将它们置换以生成16个具有相同哈希代码的字符串。例如:


"AaAaAaAa", "AaAaBBBB", "AaAaAaBB", "AaAaBBAa",
"BBBBAaAa", "BBBBBBBB", "BBBBAaBB", "BBBBBBAa",
"AaBBAaAa", "AaBBBBBB", "AaBBAaBB", "AaBBBBAa",
"BBAaAaAa", "BBAaBBBB", "BBAaAaBB", "BBAaBBAa",

所有这些 16 个字符串都具有相同的哈希代码。

现在,您可以获取这 16 个字符串,并生成 256 个具有相同哈希码的字符串。

简而言之:很容易生成一大组字符串,这些字符串将具有确切的哈希代码。

如何攻击服务器?

  1. 创建数千个具有相同哈希代码的字符串(见上文)
  2. 像这样构造一个 POST 请求 - AaAa=&AaBB=&BBAa=&BBBB= ....
  3. 提交表格
  4. 在循环中重复,并创建多个线程,以便所有服务器资源都用完

由于这只是一个 POST 请求,因此攻击者还可以使用无辜的浏览器来攻击服务器。只需找到一个具有跨站点脚本编写漏洞的网站,嵌入代码以发出POST请求,然后使用社交工程将链接传播给尽可能多的用户即可。

预防

通常,底层平台无法解决此问题。这被认为是一个应用程序框架问题。换句话说,Tomcat必须解决这个问题,而不是Oracle/Sun。

可能的修复包括:

  1. 限制 POST 参数的数量 - Tomcat 6.0.35+ 有一个新参数 maxParameterCount。默认值为 10,000。越低越好,只要它不会破坏你的功能。

  2. 限制 POST 请求的大小 - 要使攻击起作用,有效负载必须很大。Tomcat 允许的默认开机自检为 2MB。将此减少到200KB将降低此攻击的有效性。tomcat 中的参数是 maxPostSize

  3. Web 应用程序防火墙 - 如果您有 Web 应用程序防火墙,则可以将其配置为阻止看起来可疑的请求。这是一个反应性措施,但如果您无法使用上述解决方案之一,那就太好了。

仅供参考 - 雄猫的文档在这里 - http://tomcat.apache.org/tomcat-6.0-doc/config/http.html


答案 2

最简单的解决方案是升级到tomcat的固定版本。但是,我怀疑你想知道雄猫人需要改变的细节。

这种攻击的工作原理是利用哈希数据结构的常见实现细节 - 使用链接列表来保存哈希相同的所有值。向此链接列表添加值效率低下,因为列表的大小会变大。攻击者可以创建已知会生成冲突哈希的值列表,从而强制执行这种低效行为。为了防止这种情况,您有几种选择:

  • 防止冲突 - 通过在哈希函数中使用一些(伪)随机因子来防止攻击者生成冲突值。Perl已经这样做了很长一段时间。

  • 为您的存储桶使用链接列表之外的内容 - 攻击之所以有效,是因为将 N 个项目插入到链接列表中会产生 N^2 的增长。如果在插入时使用平衡树或具有 N logN 增长的其他结构,则应缓解此问题。这可能会牺牲一些最佳/平均案例性能,以限制最坏案例的严重程度。