密码混沌:野外比特翻转

admin 2025年5月29日10:01:54评论37 views字数 2913阅读9分42秒阅读模式
密码混沌:野外比特翻转密码混沌:野外比特翻转

大家好,

回答一个长期存在的争议:大多数 CTF 比赛是否与现实世界的渗透测试/漏洞挖掘场景无关?简而言之:是的,它们确实有很大关联,如果没有之前的 CTF 经验,我们很可能不会发现这个漏洞。

现在来看看长答案,但在我们继续我们的 TL;DR 部分之前,要向 Khaled Ibn Al-Waleed 和 Mohamed Bebo 致以最诚挚的谢意,这是团队共同努力的结果,没有他们,这一切都不可能实现。

TL;DR

我们的目标是一款银行应用程序,与大多数银行应用程序一样,加密值的使用几乎无处不在。根据以往经验,依赖如此多加密的应用程序通常不会检查任何IDOR或BAC,因为几乎没有人能够破解如此严格的加密,尤其是在服务器端进行加密的情况下。

该应用程序使用 AES-CBC 模式加密的账户 ID,一种直接的方法是使用另一个账户 ID 测试 IDOR 或 BAC,但这样一来,我们就会面临一个永恒的问题:如何获取该账户 ID?这个问题本身就很有道理,尤其是在无法通过 Wayback Machine 或其他任何方式获取的情况下。这时,我们的比特翻转攻击就应运而生了,它使我们能够使用任何其他客户的账户 ID 伪造自己的加密账户 ID。通过实现这一点,我们就构建了一个完整的攻击场景。

发掘潜力

正常浏览应用程序并检查burp历史记录中发送的请求时,我们注意到所有帐户ID都已加密。我们立即怀疑这是AES加密,因为它们总是相同的,并且是16字节块的倍数(在我们的例子中是48),并且从B64解码它是无用的。我们还注意到它们通过两个请求发送:

  1. 转账请求在fromAccounttoAccount
  2. 返回该帐户详细信息的帐户摘要

通常,当我们看到类似的东西时,我们会尝试改变加密文本中的一个字节,看看服务器如何响应,我们尝试在不同的地方这样做,特别是结尾,因为那是填充存在的地方,所以一个很大的变化是服务器将无法解密密码并抛出错误。

幸运的是,服务器在更改密码中的一个字节时不仅仅抛出错误,它还返回了整个详细错误以及部分解密的明文。

这是来自服务器的有效加密帐户 ID:O4YVUZ/11guQ14A5Pd8j9/6bvdgNJUcaRzw5pODFqjmeJQZRk83lVTPQ0/6deucd

在更改第一个字节(例如将 O 更改为 C)后,我们收到以下错误:

密码混沌:野外比特翻转密码混沌:野外比特翻转
部分明文引发的第一个错误

我们只修改了第一个字节,就得到了实际明文的后半部分,而前半部分则完全是乱码。我们当时怀疑是 AES-CBC 算法,因为每个区块的解密都依赖于前一个区块的密码。然而,我们需要验证我们的猜测,第一步就是提取完整的明文。

这需要进行一些反复试验,通过更改加密文本另一端的字节,因为我们相信其中涉及填充,并且通过更改第 30 个字符,我们也收到了此错误消息。

密码混沌:野外比特翻转密码混沌:野外比特翻转
第一个明文引发的第二个错误

现在我们的怀疑得到了证实。这确实是 AES-CBC 加密的,因为第一部分只有 16 个字节,中间部分是垃圾数据,而第三部分由于我们在第二个区块中的修改而被错误解密。因此,通过将明文放在一起,我们知道加密的账户 ID 令牌解密后会变成:(accountNumber=9894001933~~bankCode=****7912星号只是为了保护客户端的隐私而遮盖了银行代码)

太棒了,我们拿到了加密的账户 ID 及其明文值,还有一个可以验证令牌是否解密成功的端点,它会显示详细的错误信息。接下来该做什么呢?

连接点

首先想到的是位翻转攻击,特别是因为这里没有完整性验证。

这是一篇很棒的文章,用 CTF 示例解释了位翻转攻击,最好先在这里停下来看看,然后再继续阅读:https://zhangzeyu2001.medium.com/attacking-cbc-mode-bit-flipping-7e0a1c185511

然而,也存在一些挑战:

  1. 我们只能更改最后一个块中的位,因为第一个块与 IV 进行异或运算,并且由于我们无法更改/修改 IV,所以我们无法正确获取它,因此我们需要以某种方式控制第一个块。
  2. 解密失败会返回 UTF-16 字符,这会导致执行位翻转攻击的默认方法出现问题。

对于第一个问题,我们需要更改第二个块,因为它包含我们想要操作的账号。

区块1:accountNumber=98

区块2:94001933~~bankCo

区块3:de=****7912

我们认为我们可以添加两个值为 0x00 的控制块,这样当它们被解密并与 IV 进行异或运算时,输出值仍然相同(或者为此目的可以是任何值,不一定是 0x00,但它需要有效才能解密)但这引发了另一个问题,即使我们成功了,解密后的文本中也会有很多乱码,这会破坏明文,而服务器无法理解这一点。

是不是死路一条?直到我们注意到波浪~~号。也许服务器会用它们来分割明文,因为accountNumber和bankCode是串联在一起的,肯定有办法分割它们。幸运的是,这就是第一个问题的解决方案。

所以基本上我们的解密明文是{gibberish}~~accountNumber=123123123~~bankCode=AAAA7912

现在说说第二个问题,我们需要可读的字符,这样我们就可以按照之前提到的公式C1 ^ C2 = P1 ^ P2得到我们指定的字符,假设C2是UTF C2 = C1 ^ P1 ^ P2-16,而解决方案是暴力破解。没错,我们暴力破解不同的值,直到得到一个可读的字符而不是UTF-16的垃圾字符,然后将其与指定的字符进行异或运算,再与得到该字符的C值进行异或运算。

密码混沌:野外比特翻转密码混沌:野外比特翻转
暴力破解脚本输出

因此,正如您在屏幕截图中看到的,我们尝试了密码中的不同字节来获取可读字符而不是ufffdUTF-16 垃圾,一旦我们得到该字符(字母“g”),我们就会打印用于获取该字符“120”的字节,然后应用我们的等式:C1(120) ^ P2(g) ^ P1(a) = C2(The value we want to put in our new cipher)

密码混沌:野外比特翻转密码混沌:野外比特翻转
使用等式进行异或

因此,我们将“126”添加到我们的密码中并继续对前面的字符进行暴力破解,添加后如下所示,它现在可以成功读取帐户。

密码混沌:野外比特翻转密码混沌:野外比特翻转

我们这样做,直到我们得到我们想要的明文,正如提到的{gibberish}~~accountNumber=123123123~~bankCode=AAAA7912

成功完成此操作后,我们就可以破解加密过程,并伪造我们所需accountNumber的任何其他客户的令牌。再加上IDOR或BAC,我们现在就拥有了完整的攻击场景。

密码混沌:野外比特翻转密码混沌:野外比特翻转
带有伪造令牌的最终 POC

奖金部分:

感谢我们的朋友 Islam (zikads),他提到属于同一组织的另一个门户也使用了加密 ID,我们采用相同的方法在受影响的端点中使用该加密 ID,令我们惊讶的是,它也在加密中使用了相同的密钥和 IV,这使我们能够检索该 ID 的纯文本并应用相同的攻击,并且它也在该端点上起作用。

此类漏洞的缓解措施:

  1. 如果没有服务器的详细错误,我们将无法完成任何这些,因为了解纯文本是一个重要的部分,因此适当的错误处理可以解决这个问题。
  2. 加密值没有经过完整性验证(可能是因为它是在服务器端完成的,所以没有人会认为它会被破解),但如果有的话,它也不会被利用。

下次再见^^

原文始发于微信公众号(安全狗的自我修养):密码混沌:野外比特翻转

 

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月29日10:01:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   密码混沌:野外比特翻转https://cn-sec.com/archives/4109828.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息