Sep 29

ASP.NET Padding Oracle漏洞修复补丁代码分析

这几天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$这次的反应速度算是不错,漏洞爆出来两个星期左右就放出补丁了,估计是因为影响太大了吧。

Sep 10

神奇的Boolean

   1:  

   2: // "true" or "false"

   3: public static string Bool2Str(bool b)

   4: {

   5:     switch (b)

   6:     {

   7:         case true:

   8:         return System.Boolean.TrueString;

   9:         case false:

  10:         return System.Boolean.FalseString;

  11:         default:

  12:         return "error";

  13:     }

  14: } 

  15:  

  16: Console.WriteLine(Bool2Str(true));

  17: Console.WriteLine(Bool2Str(false)); 

  18: unsafe

  19: {

  20:     bool val;

  21:     *((byte*)&val) = 2;

  22:     Console.WriteLine(val); 

  23:     Console.WriteLine(val==true); 

  24:     Console.WriteLine(Bool2Str(val));

  25: }

  26:  

大家可以猜一下这段代码会输出什么,我也是看了某篇文章的评论才知道会出现这么诡异的情况。。。