这几天ASP.NET的Padding Oracle漏洞(视频)闹得是沸沸扬扬,M$刚刚发布了修复补丁,EP起来于是研究下M$是怎么样修复的。
Reflector跟踪一下,很容易能找到关键方法是System.Web.Configuration.MachineKeySection.EncryptOrDecryptData,对比补丁前和补丁后的方法主体发现补丁后的版本主要是添加了Hash签名检测:
1: // ... snip ...
2:
3: if (!fEncrypt && signData)
4: {
5: if ((start != 0) || (length != buf.Length))
6: {
7: byte[] dst = new byte[length];
8: Buffer.BlockCopy(buf, start, dst, 0, length);
9: buf = dst;
10: start = 0;
11: }
12: buf = GetUnHashedData(buf);
13: if (buf == null)
14: {
15: throw new HttpException(SR.GetString("Unable_to_validate_data"));
16: }
17: length = buf.Length;
18: }
19: // ... snip ...
(hash函数内部使用validationKey作为salt或者HMAC的key,这里略过)
另外整个方法体也被一个try catch块包了起来,遇到异常直接抛出统一的异常:
1: try
2: {
3: // ... snip ...
4: }
5: catch
6: {
7: throw new HttpException(SR.GetString("Unable_to_validate_data"));
8: }
从这两点看来,理论上Padding Oracle攻击的漏洞已经被堵上了。首先,因为加上了数据签名,攻击者没办法随意修改已知的数据;另外抛出的异常内部把有关错误原因的信息都消除了,攻击者没办法区分Padding错误和解密错误,攻击自然没办法进行了。
M$这次的反应速度算是不错,漏洞爆出来两个星期左右就放出补丁了,估计是因为影响太大了吧。
Leave a Reply