云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

分布式数据库_船长偏头痛txt百度云_代金券

小七 141 0

OpenSSL CBC密码套件中的另一个填充Oracle

昨天,OpenSSL/LibreSSL中宣布了一个新的漏洞。准确地说,是CBC模式解密中的填充甲骨文。就像幸运13。实际上,它是在代码中修复幸运13。它是由尤拉杰·索莫罗夫斯基使用他开发的名为TLS攻击者的工具发现的。和"旧时代"一样,除了CVE-2016-2107之外,它没有名字。(我称之为幸运消极20[1])这是一个在恒定时间代码中填充甲骨文的很好的例子,所以我们将深入研究它。但首先,两个简短的背景段落。如果您已经了解了Lucky13的所有信息,以及它在OpenSSL中是如何减轻的,那么请跳到"Off by 20"这一热门和新版本。如果在阅读之前,你想检查你的服务器是否安全,你可以用这个一键式在线测试。然后TLS、CBC和Mac加密长话短说,TLS中的CBC密码套件有一个设计缺陷:它们首先计算明文的HMAC,然后使用CBC模式加密明文| | HMAC | | padding | | padding length。然后,接收端的任务就是解密消息,检查HMAC和padding,而不以任何方式显示填充长度。如果是这样的话,我们称之为padding oracle,MitM可以使用它来学习任何块的最后一个字节的值,并且通常通过迭代来学习整个消息。![CBC MtE图](https://单击以放大图表。换言之,CBC模式密码套件是由密码末日原理注定的。不过,遗憾的是,在1.2版之前,TLS是唯一可以与TLS一起使用的"安全"密码套件,而且它们占到CloudFlare edge的26%的连接,因此像这样针对TLS的攻击仍然非常相关。我的同事尼克·沙利文在这个博客上更详细地解释了CBC填充神谕及其历史。如果你不明白我的粗略总结,请花点时间阅读他的文章,因为这需要了解下一步出了什么问题。固定时间编程速成课程对于泄漏填充长度值信息问题的"解决方案"是编写完整的HMAC和padding检查代码,以便在完全恒定的时间内运行。我曾经听丹尼尔J.伯恩斯坦称之为"把双手绑在背后,看看你能用鼻子做什么"。正如你所想象的那样这并不容易。我的想法是你不能使用ifs。因此,相反,通过对结果变量执行按位and来存储检查结果,在开始之前将该变量设置为1,在该变量下只查看整个操作的结尾。如果任何检查返回0,则结果为0,否则为1。这样攻击者只会学习"包括填充和HMAC在内的一切都是好的"或"不"。不仅如此,循环迭代只能依赖于公共数据:例如,如果消息的长度是32字节,那么填充最多可以是32-1-20=11字节,因此必须检查20(HMAC-SHA1)+11字节。为了忽略实际上不需要检查的字节,可以使用一个掩码:一个由常量时间操作生成的值,当字节应该匹配时,该值为0xff,而不匹配时为0x00。通过将掩码与位差相加,可以得到一个值,当值匹配或不匹配时,该值为0。![遮罩图](https://bl这种技术对于这种脆弱性是至关重要的,因为正是它的持续时间、无怨言的本性使错误成为可能。OpenSSL检查代码是在Lucky13发现之后编写的,adamlangley写了一篇很长的博文来解释通用版本是如何工作的。我在这里忽略了很多细节,特别是在恒定时间内生成可变长度消息的HMAC的不可思议的痛苦(幸运13和幸运微秒就发生在这里),所以去读他难以置信的文章来了解更多。在20分钟前关闭像任何值得尊敬的漏洞分析一样,让我们从补丁开始。为了简单起见,我们将重点讨论SHA1部分,但是SHA256部分是完全相同的。LuckyMinus20的补丁是OpenSSL函数中的一行代码,它执行AES-CBC解密并检查HMAC和padding。如果填充长度值大于可能的最大值,它所做的就是将检查标记为失败。pad=明文[长度-1];maxpad=len-(SHA_DIGEST_长度+1);maxpad |=(255-maxpad)>>(sizeof(maxpad)*8-8);最大值&=255;+ret&=恒定时间(maxpad,pad);+这个补丁直接指向如何触发漏洞,因为它不会有任何副作用:毕竟这是恒定时间的代码!这意味着,如果我们使用补丁来检测发送比maxpad高的填充长度字节,我们有时可以通过HMAC/padding检查(!!)把这个事实当作预言。maxpad很容易计算:明文的长度减去1个字节的有效负载长度,再减去20个字节的HMAC-SHA1(SHA_DIGEST_length),上限为255。因为它只依赖于加密数据的长度。它还涉及决定循环HMAC/padding检查的次数,因为我们不想超出消息缓冲区的范围,也不想浪费时间检查不可能是padding/HMAC的消息字节。那么,pad>maxpad怎么能让我们欺诈地通过HMAC检查呢?让我们回到我们的面具,这次想想如果我们发送:衬垫=最大衬垫+1=(长度-20-1)+1=(32-20-1)+1=12![按一个图表关闭](https哦哦。发生什么事了!?HMAC检查掩码的一个字节超出了我们实际检查的范围!没有什么会崩溃,因为这是恒定时间代码,它必须在没有任何外部提示的情况下容忍这些情况。所以,如果我们再往前推一点…![off-by-20图表](https:在那里。HMAC掩码现在对于所有检查循环迭代都是0,因此我们根本不必再担心是否有有效的签名,如果消息中的所有字节都是有效的填充字节,也就是说,等于填充长度字节,我们将无条件地通过MAC/填充检查。[我喜欢将这些类型的"密码分析函数"装箱并加上标签,称之为能力。这是我们的能力:我们可以通过将消息发送到服务器并观察与BAD\MAC不同的错误来发现消息是否完全由值为n的字节组成,其中n>=maxpad+20。这只适用于短于256-20=236字节的消息,因为pad最多可以是255,是一个8位的值。注意:正如Juraj澄清的那样,没有必要像幸运13那样进行精确的定时统计,因为如果在发送完成的消息时发送了被篡改的消息,那么服务器响应(BAD_MAC or not)将被解密。我们可以将此功能用作甲骨文。换言之,整个技巧是使计算的有效负载长度至少为DIGEST_length的"负",这样HMAC掩码的计算位置完全"在"消息之外,MAC最终根本不会被检查。顺便说一句,受影响的函数名为aesni_cbc_hmac_sha1_cipher这一事实解释了为什么只有具有AES-NI指令的服务器才易受攻击。如果您想自己使用调试器,可以在此处找到易受攻击函数的独立简化版本。从那里开始解密好吧,我们有"能力"。但我们如何从那里解密呢?"经典"的方法是关注一个我们不知道的字节,前面是我们控制的字节(在本例中,是31个字符串)。然后我们用一个值n对前一个块中对应的密文字节进行异或运算来猜测未知字节。我们对许多n都这样做。当服务器回复"check passed"时,我们知道神秘字节是31xor n。记住,这是CBC模式,所以我们可以去掉任何连续的块序列并将其表示为它自己的密文,然后将给定密文字节的值XOR'd结束为下一个块中相应的明文字节。下面的图表应该能让这一点更清楚。在这个场景中,我们将JavaScript注入用户在不同选项卡中加载的纯HTTP页面,并向目标域发送任意数量的AJAX请求。通常我们使用GET路径作为已知的受控字节,并将头作为解密目标。但是,这种方法在这种情况下不起作用,因为我们需要两个连续相等的明文字节块,并且如果我们触摸块x中的密文来帮助解密块x+1,那么我们将无法修复地损坏块x的明文。[我想让你停一下,让你意识到这是可能的,因为我们:允许未经验证的(纯HTTP)网站和任何MitM在我们的机器上运行代码。允许JavaScript将请求发送到携带我们的私有cookie的第三方来源(即其他网站)。顺便说一句,这也是CSRF得以实现的原因。回到我们的甲骨文,我们可以让它以另一种方式工作:我们在由31组成的两个块的开头对齐一个未知字节(我们可以将其作为POST body发送),然后将n值与IV中的第一个字节进行异或运算。同样,当MAC检查通过时,我们知道目标字节是31xor n。[我们重复这个过程,将所有字节向右移动一个位置(例如,通过使POST路径变长一个字符),然后用我们的n个猜测对IV的第一个字节进行异或运算,第二个字节用我们现在知道的数字将其变成31。以此类推。这使我们能够解密任何16个字节,这些字节总是出现在至少31个攻击者控制的字节序列之前,以及一个攻击者控制的长度字符串之后(为了对齐)。通过谨慎地暂停客户机请求并使用早期反馈,可以将解密扩展到两个受控块之前的所有块,但我不确定它是否有效。(考虑到一个OpenSSL团队成员说他们不知道这种技术,我在完全解密功能上出错的可能性很高。)更新:我们与Juraj聊了一会儿,不,它不起作用。但不能再往前走了有人可能会认为,由于这归结为MAC检查绕过,我们可以使用它将未经验证的消息注入到连接中。然而,由于我们依赖于使pad高于maxpad+DIGEST_长度,我们无法避免m