美文网首页网络安全实验室
深入PHP源代码解决实际问题

深入PHP源代码解决实际问题

作者: 蚁景科技 | 来源:发表于2019-04-19 13:46 被阅读0次

    01 PaddingOracle Attack 原理剖析

    (一)PaddingOracle Attack

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

    (二)加解密原理

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

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

    图一:CBC加密模式

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

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

    图二 padding标准PKCS5

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

    图三 CBC解密方式

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

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

    (三)攻击原理

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

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

    图四 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.代码审计

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

    图五 题目核心逻辑伪代码

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

    (三)解题方法

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

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

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

    图六 攻击脚本运行结果

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

    图七 getflag截图

    (四)章节小结

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

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

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

    (一)问题来源

    图八 问题来源

    (二)源码跟进分析

    图九 openssl_encrypt()源代码

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

    图十php_openssl_cipher_init( )源码

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

    图十一 密钥处理部分分析

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

    (三)脚本修改

    图十二 脚本修改

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

    相关操作学习:

    密码学原理:复制如下链接打开网页,开始操作!

    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

    相关文章

      网友评论

        本文标题:深入PHP源代码解决实际问题

        本文链接:https://www.haomeiwen.com/subject/royqgqtx.html