[NPUCTF2020]web🐕
1 |
|
我们通过代码审计发现这个题是用php写的AES加密页面
从源码我们可以看出来,AES的密钥长度为128位,加密的iv和密文data可控
AES有两种攻击方法:Padding Oracle和字节反转,这道题刚好都考虑
Padding Oracle适合在我们可以知道iv,不清楚加密Key,能够区分解密成功与否的情况下,直接获得明文
而这题刚好可以判断解密是否成功
https://www.jianshu.com/p/833582b2f560
在Padding Oracle Attack攻击中,攻击者输入的参数是IV+Cipher,我们要通过对IV的”穷举”来请求服务器端对我们指定的Cipher进行解密
因此我们需要知道密文,而那个加密函数刚好把密文显示出来了。
这个攻击类似布尔盲注
既然是爆破初始向量,我们需要知道iv是怎样构成的
我们先来看CBC解密是怎么解的
首先密文和key进行运算得到一个中间值,然后再通过这个中间值与iv值的异或,最后得到密文
上述文章已经讲的很清楚了
由于这题如果解密失败会返False,因此我们只需通过枚举IV,然后得到中间值,然后再中间值和原来真正的IV异或,即可得到明文。
因此需要通过padding值来判断中间值
我们可以知道padding的长度和middle是相等的
看了wp,不知道这个公式怎么来的,记一下
因此IV的构成不难猜了
首先IV肯定是16位的也就是0000000000000000
在进行爆破时他需要还剩下爆破的位数+正在爆破的值,再加上最后的位数要运算后要保证和padding相等,因此iv[N-step+1:] ^ middle = padding 由此这最后一位就是middle和padding进行异或的结果
刚开始middle未知,因此middle要为空值,
如果解密成功那么middle[当前位置]= iv爆破成功的值 ^当前的位置
由此构造exp
1 | import requests |
得到FlagIsHere.php
我们访问FlagIsHere.php
1 | ptdZn+MkBf36SZCFd989dA== |
然后就是cbc字节反转
要求’piapiapiapia’加密的密文,通过可控IV,解密成’weber’,就是要我们把IV给解出来
当遇到明文已经经过IV处理过,然后要你解出来是另一个明文时,就要用到CBC字节反转
由于是128长度,16位为一组
因此
两个明文后面都要补齐,填充模式是PK7模式填充,就是拿16减去最后一位的位数的十六进制来进行填充
1 | 比如:piapiapiapia\0x04\0x04\0x04\0x04 |
然后直接上脚本吧,多说无益,这个看脚本就能理解
方法就是将目标i明文和初始的IV异或后再和原来的明文进行异或。
注意在python3里,一定要传入byte类型,否则将会自动解码hex.
1 | import base64 |
但一开始生成的ptdZn+MkBf36SZCFd989dA==不行,可能因为里面含泪一个+号,我们删掉cookie重新生成,知道iv里没有+号
将得到的iv传过去后得到一个网站
原来正常操作是这个网盘能下载之前那个helloworld.class文件。可能因为链接失效了吧,buu就直接把helloworld.class文件给我们了
我们将helloworld.class放到jd-gui反编译
得到了一串ascii码的东西,我们将其解密出来,得到flag
1 | byte[] var10000 = new byte[]{102, 108, 97, 103, 123, 119, 101, 54, 95, 52, 111, 103, 95, 49, 115, 95, 101, 52, 115, 121, 103, 48, 105, 110, 103, 125}; |