padding oracle攻击

密码侧信道分析

0x01 前言

紧接着上一篇文章exchange获取cookie

,通过SSRF与XSS的配合得到了用户的cookie。 cookie中的cadata值就是用户名跟密码经过加密后得到的一串字符串。所以本次任务我们就是通过侧信道分析解密用户名跟密码。

0x11 CBC加密模式

首先我们要了解什么是CBC模式,CBC模式又称为密码分组链接模式(Cipher Block Chaining)。首先将明文分块,分成等长的明文模块。另外还有一个初始化向量IV,IV一般是随机生成。首先将第一块明文与初始化向量IV进行依次异或,然后将异或的结果(initialization value)进行加密得到我们的第一组密文,紧接着进行第二组密文的加密,此时将第一组密文作为第二次加密的IV进行异或以此类推进行剩下分组的加密。
在这里插入图片描述

0x21利用点

​ 看样子CBC每组密文都是互相影响,安全性肯定很高才对,但是这个模式是存在一定的缺陷的,这个缺陷就会导致padding oracle攻击。因为明文加密之前要与IV进行异或,所以每一组IV是与分组明文等长的,那不可能待加密的明文长度都正好是某个数的倍数。所以当明文长度不足时要进行填充,例如加密的分组为8个字节,当不足8个字节时会进行填充,填充的规则就是少几个字节就填充多少个缺失的字节数,例如缺少3个字节就填充3个0x03,从而确保了是8的倍数。所以利用点就在填充上,首先解密的时候会先检查填充是否正确,如果不正确则解密失败,如果填充位错误的时候有回显就是造成padding oracle攻击。

​ CBC的解密过程如下,首先密文经过加密算法解密以后与initialization vector(IV)进行异或的得到明文。

在这里插入图片描述

​ 那怎么利用,例如我们首先将初始化向量IV,定义成如下:

(initialization value:是明文与IV异或后的结果)

initialization value0x210x310x320x990x280x220x200x29
initialization vector(IV)0x000x000x000x000x000x000x000x00
PlainText0x210x310x320x990x280x220x200x29

那么经过异或之后0x29还是它本身,那这时服务端就会报填充位错误,因为填充位不可能超过0x08(ps:因为即使是明文刚刚好是倍数的时候也会有填充,例如填充一个新的模块即填充8个0x08),此时服务器就会报填充错误。那怎样才不会报填充错误当结果为如下:

initialization value0x210x310x320x990x280x220x200x29
initialization vector(IV)0x000x000x000x000x000x000x000x28
PlainText0x210x310x320x990x280x220x200x01

则不会报填充错误。当结果为0x01的时候,那IV我们是知道的,那么不就可以推出initialization value的最后一位了吗。所以经过不断变换使得PlainText

0x21 0x31 0x32 0x99 0x28 0x22 0x02 0x02

0x21 0x31 0x32 0x99 0x28 0x03 0x03 0x03

0x08 0x08 0x08 0x08 0x08 0x08 0x08 0x08

我们就可以推出完整的initialization value,而initialization value是明文与IV异或后的结果,而IV我们是知道的我们再把initialization value与IV异或不就可以得到PlainText了吗!

0x31漏洞复现

在Cookie中,有这么几个值,cadata:用户名与密码的密文,cadataKey:加密的密钥,cadataIV:加密所使用的IV,而cadataIV是使用SSL证书作为私钥使用RSA加密过的,所以我们无法破解。

我们看看加密流程

 @key = GetServerSSLCert().GetPrivateKey()
 cadataSig = RSA(@key).Encrypt("Fba Rocks!")
 cadataIV  = RSA(@key).Encrypt(GetRandomBytes(16))
 cadataKey = RSA(@key).Encrypt(GetRandomBytes(16))

 @timestamp = GetCurrentTimestamp()
 cadataTTL  = AES_CBC(cadataKey, cadataIV).Encrypt(@timestamp)

 @blob  = "Basic " + ToBase64String(UserName + ":" + Password)
 cadata = AES_CBC(cadataKey, cadataIV).Encrypt(@blob)

看到加密的流程即使IV不可控那顶多就是第一个模块解密不出,但是我们可以知道第一个模块的前12个字节
B\x00a\x00s\x00i\x00c\x00 \x00为什么是12个字节因为C#里面会将字符串当作UTF-16。而我们丢失的仅仅是四个字节,即用户名的1.5个字节。
当我们填充位错误时候返回头

Location: /OWA/logon.aspx?url=&reason=0

当填充位正确,而拿着解密错的用户名跟密码进行后续的验证时候返回头有

Location: /OWA/logon.aspx?url=&reason=2

这就是提示错误!
按照上述解密步骤一步一步的破译出全部分组,会得到一串base64编码,这时直接拿去解密要么解密不出要么解密结果出错,前文提到了我们丢失了四个字节,因为base64加密规则是将3个字节编为4个字节,所以我们要补上丢失的四个字节,这四个字节可以随意补上(4个0x00除外)。这时候拿去base64解密会发现用户名丢失两个字符,密码正确。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值