经验总结
深入PHP源代码解决实际问题
2019-04-19 15:34

01 PaddingOracle Attack 原理剖析

(一)PaddingOracle Attack
Padding OracleAttack是在Eurocrypt2002大会上,Vaudenay所介绍的一种针对CBC模式的攻击方法。它可以在不知道密钥的情况下,通过对paddingbytes的尝试,获取加密过程中的IntermediaryValue,从而还原明文或构造出任意明文的密文。

(二)加解密原理

分组加密算法在实现加解密时,需要把消息进行分组,分组(block)的大小一般有64bit,128bit,256bit等。

本文以CBC模式为例,对攻击原理进行简单的阐述。

48820-e77417a5efeaf02e.png

图一:CBC加密模式

我们以8个字节一个block为例,首先将第一组的明文与初始iv进行异或之后进行相应的加密算法运算。计算完第一组后,将第一组获得的密文作为第二组的iv进行运算,如此类推,得到所有明文加密的结果。

如果在这个加密的过程中,最后一个分组的消息长度(明文长度)没有达到block的大小,则需要对其填充一些字节(padding)。

微信图片_20190419161346.jpg

图二 padding标准PKCS5

上图padding例子使用现行最常见的padding标准PKCS#5。当需要填充1个字节时,填充值为0x01;当需要填充2个字节时,其填充值为0x02,0x02;当需要填充3个字节时,其填充值为0x03,0x03,0x03……

48820-129b75e5ba8f6ddb.png

图三 CBC解密方式

类似的,解密过程与加密过程类似。首先将第一分组的密文进行解密运算,之后与初始iv进行异或,得出对应的明文。计算完第一分组后,将第一分组的密文作为第二分组的iv参与运算,如此类推得到所有分组密文的解密结果。

加解密原理大致阐述了一下,读者还记得上面提到的PaddingOracleAttack的特点吗?即在不知道密钥的情况下,还原明文或构造出任意明文的密文。所以下面请将注意力转移到解密部分,我们来仔细分析解密部分的一些特点,想办法做出PaddingOracle Attack的功能。

(三)攻击原理

在密钥一定的情况下,对密文进行解密算法运算,我们是可以得出一个与明文唯一对应的密文。在上文所说的解密过程中,进行解密算法运算只是每一组运算中的一个步骤,接下来是另一个步骤,即异或出结果。在这个过程中,使用解密算法运算得出的密文我们将其称为Intermediary Value。

小结一:每组密文解密所得到的IntermediaryValue都是固定的(因为与明文唯一对应),而我们暂时不知道它的值(因为我们不知道密钥)

接下来我们来分析异或部分

微信图片_20190419161638.jpg

图四 CBC解密细节

可以看到,IntermediaryValue ⊕ iv = 明文。

请再次仔细想一想,在不知道密钥的情况下,还原明文或构造出任意明文的密文。所以,我们可以认为明文已知。

又因为Intermediary虽然未知,但是它的值是固定的,因此我们可以将上面这个表达式转换为

明文 =Intermediary Value ⊕ iv

所以,我们慢慢调整iv的值,以期得到与我们想要的明文一致的iv值,并一个字节一个字节的尝试,直到得出分组所使用的iv值。(iv每一个字节从0x00到0xFF进行尝试)

小结二:通过上面的推断,我们已经获取到了iv和明文值

继续看这个公式明文 = Intermediary Value ⊕ iv

我们继续做一下转换 Intermediary Value = 明文⊕ iv

因为明文和iv都已知了,因此我们可以通过异或得到IntermediaryValue的值。IntermediaryValue已知,那么我们就可以通过IntermediaryValue ⊕ 我们想要的明文=> 得到对应的iv

推导出最后一个分组使用的iv后,将此iv作为第一个分组的密文,再次进行推导,以此类推,便可以找到解密为任意明文的密文和iv对了

总结:明文 =Intermediary Value ⊕ iv

通过推导,我们可以得到解密为任意明文的密文和iv对,达成了既定目标。这里值得注意的是,需要对密文进行解密才能得出对应的IntermediaryValue,因此如果我们在没有密钥的情况下,需要通过一定的办法,触发app的解密程序,获取IntermediaryValue,从而继续我们上面对iv的推导。


02 PaddingOracle Attack 攻击实例(CTF题目)

(一)题目来源

常见的一道基础CBC翻转字节攻击

(二)题目关键代码(伪代码)

做题步骤

* 1.源码泄露

* 2.代码审计

题目核心逻辑伪代码如下图所示

48820-a3b3b3d18d27f015 (1).jpg

图五 题目核心逻辑伪代码

所以我们可以知道,考点在于使用服务器为用户设置的密文和iv,进行某些操作,使得密文解密后的用户名为admin

(三)解题方法

1.利用网上到处都是的CBC翻转字节攻击代码进行

2.利用《白帽子讲web安全》内的PaddingOracle Attack的示例代码进行攻击(修改过的脚本代码附后)

我们在这里使用第二种方法进行,由于存在源码泄露,我在源码中找到了加密密钥,因此我不需要对触发app的解密代码来获取IntermediaryValue。可以直接使用密钥进行解密运算,从而获取解题所需的密文和iv对。

48820-932499e3cbe1ffd9.jpg

图六 攻击脚本运行结果

获取到密文和iv对之后,我们替换掉原先设置的密文和iv对,即可getflag。

48820-8d449a5b1a551cc7.png

 图七 getflag截图

(四)章节小结

实际上这里取巧了,获得了题目加密的密钥。如果题目不能获取到密钥的话(实际攻击场景中常见),需要对脚本进行一些修改,触发攻击对象的解密程序,获取IntermediaryValue。


03 PaddingOracle Attack 脚本修改中的一些思考

实际上写下这篇博文也是因为这个思考,最近所在的实验室办校内ctf比赛。作为客服的我无聊看了一下web题,又无意中突然发现题目的密钥长度没有达到算法预期,不禁产生了疑问。所以下面部分是对PHP的openssl_encrypt/openssl_decrypt中对key处理的研究

(一)问题来源

微信图片_20190419162615.jpg

图八 问题来源

(二)源码跟进分析

48820-e2cbaad50bc8ff6b.jpg

图九 openssl_encrypt()源代码

可以看到,我们在使用openssl_encrypt函数时,输入的key(密钥)即是图中的参数password,而在第6624行中,密钥作为形参传到了一个名为"php_openssl_cipher_init"的函数中,我们继续跟进。

48820-96a88834aceaae2f.jpg

图十php_openssl_cipher_init( )源码

可以看到在函数中的第6511和第6512两行中,分别获取了用户输入的密钥长度和加密算法对应的规定密钥长度,显然,我们想要找到处理就在这个地方,继续往下看。

微信图片_20190419162848.jpg

图十一 密钥处理部分分析

图片上我加了注释,解释应该十分清晰了。

(三)脚本修改

48820-19d439e25042bcb1.png

图十二 脚本修改

根据上面得出的处理结果,对攻击脚本进行修改(主要增加密钥处理功能)

相关操作学习:密码学原理:http://www.hetianlab.com/cour.do?w=1&c=c990c65e-108f-4d10-9efa-4aad77fc852b

本文脚本源码:https://github.com/Porlockzzz/attackScript/blob/master/padding_oracle_attack.py

上一篇:APP漏洞挖掘之捡漏技巧
下一篇:无文件攻击的各种姿势
版权所有 合天智汇信息技术有限公司 2013-2021 湘ICP备14001562号-6
Copyright © 2013-2020 Heetian Corporation, All rights reserved
4006-123-731