之前一直没有机会好好总结下padding oracle, 在LCTF 上水了两天,Simple Blog 这题就看了一天,最后还是没有弄出来, 参考了各位大师傅的wp, 赛后好好总结下这个漏洞, 还是很有意思的
Padding Orlace攻击
这是CBC模式下存在的攻击,与具体的加密算法无关(当然,必须是分组加密)。不过,实际上Padding Oracle不能算CBC模式的问题,它的根源在于应用程序对异常的处理反馈到了用户界面(即服务器对解密后数据Padding规则的校验。若不符合Padding规则,则返回500.其它,返回200),是一种边信道攻击方式
CBC是分组密码的一种模式, 在加解密之前都需要先对明文以及密文进行分组,常见分组方式为8bit,16bit, 如果明文不足8bit或16bit, 那么就会对数据进行填充,填充规则是PKCS#5
简单来说,它在数据填充中,使用缺失的位数长度来统一填充。缺5位就用5个0x05填充,缺2位就用2个0x02填充;如果正好为8位,就需要扩展8个0x08填充。具体如下图所示:
具体填充算法为:
add = length - (count % length)
plaintext = plaintext + ('\0' * add) #填充
对照这上面的图也就大概知道了为什么8bit 必须再次填充8bit了(之前一直不理解)
攻击前提
初始IV 可控
padding oracle异常错误反馈到了页面
攻击过程
因为padding oracle 攻击是针对cbc模式的,我们先来理解cbc字节翻转攻击是如何实现的
CBC 的加密过程我这里就不多说了,可以看下面参数文章师傅们发的详细的图,大概原理是:
加密过程
Ciphertext-0 = Encrypt(Plaintext XOR IV)—只用于第一个组块
Ciphertext-N= Encrypt(Plaintext XOR Ciphertext-N-1)—用于第二及剩下的组块
解密过程:
Plaintext-0 = Decrypt(Ciphertext) XOR IV—只用于第一个组块
Plaintext-N = Decrypt(Ciphertext) XOR Ciphertext-N-1—用于第二及剩下的组块
攻击点
这里有两个攻击点
更改iv向量, 影响第一个明文分组
如果我们更改CiphertextN-1的字节, 其会影响到Ciphertext N块的解密过程, 这个就是cbc比特翻转攻击的原理
我们假设middlecipher 是Ciphertext N块的解密结果,即A = Decrpto(Ciphertext N), old_IV在第一块中的初始化IV, 在第N块中是CipherN-1, evil_IV是我们伪造的恶意IV sourceStr是我们解密后的明文,targetStr是我们希望解密出来的明文
那么由源程序解密的过程为:
middlecipher xor old_IV = sourceStr
但我们希望的解密的过程为:
middlecipher xor evil_IV = targetStr
一般因为key未知,我们不太容易得到middlecipher的内容,我们可以控制的是我们的evil_IV, 我们可以对这两个公式推导下得出
evil_IV = targetStr xor sourceStr xor old_IV
惊奇的发现我们不太容易得到的middlecipher消失了,而我们的sourceStr和targetStr 一般可以在页面中找到(比如登录错误信息位xx不是admin, 无法登录,那么我们就容易猜到xx位sourceStr, admin是我们希望得到的targetStr字符串
这里用一个py的小demo来演示下cbc字节