2016/10/07

Anniversary Update後のReferrerを使ったXSS

English version is here: http://mksben.l0.cm/2016/10/xss-via-referrer.html

今日はXSSのテクニックを紹介する簡単なポストです!

Windows 10のAnniversary UpdateからIE/Edgeの細かい動作が変わっているようです。
XSSと関係の深い動作もいくつか変更されています。その中の1つに、リファラ文字列に含まれる一部の文字が常にエンコードされるようになった動作があります。以下に具体的に示します。

次のような、リファラ文字列を書き出すページがあるとします。

https://vulnerabledoma.in/xss_referrer

以前までのIE/Edgeでは、過去のブログでも取り上げたように、次のようにスクリプト文字列を含んだURLからのリファラを送信することで、XSSが可能でした。

https://l0.cm/xss_referrer_oldpoc.html?<script>alert("1")</script>

ところがAnniversary Updateを適用したEdgeやIEで確認すると、"<>といったXSSのカギとなる文字列が次のようにエンコードされてしまいます。
HTTP_REFERER: https://l0.cm/xss_referrer_oldpoc.html?%3Cscript%3Ealert(%221%22)%3C/script%3E
document.referrer: https://l0.cm/xss_referrer_oldpoc.html?%3Cscript%3Ealert(%221%22)%3C/script%3E
このせいで、単純に書き出すようなケースでXSSができなくなってしまいました。

今のところ、現役のWindows 8.1や7のIE11はリファラ文字列をエンコードしないので、XSSが可能なことの証明には困らないのですが、やっぱりWin10でもリファラでXSSしたいですよね!

今日は、そんな人達に朗報です。
Win10でリファラ経由でXSSする方法を発見したので、ご紹介したいと思います。

説明は一言で終わります。FlashのnavigateToURL()を使ってナビゲーションすればまだRefererヘッダに"<>がエンコードされずに入ってくれます。

以下にPoCを置きました。Anniversary Update適用済みのWin10のIE/Edgeでアクセスしてみてください。

https://l0.cm/xss_referrer.swf?<script>alert(1)</script>

ActionScriptのソースコードはこんなかんじです:
package {
 import flash.display.Sprite;
 import flash.net.URLRequest;
 import flash.net.navigateToURL;
 public class xss_referrer extends Sprite{
  public function xss_referrer() {
  var url:URLRequest = new URLRequest("https://vulnerabledoma.in/xss_referrer");
  navigateToURL(url, "_self");
  }
 }
}
ただ、残念ながら、アクセスしてわかる通り、この方法でうまくいくのは Refererリクエストヘッダを書き出す場合のみで、JavaScriptのdocument.referrerプロパティはFlash経由のナビゲーションの場合はなぜか空になってしまうようです。残念。

ちなみに、Adobe Readerの submitForm() というJavaScript API経由でもRefererリクエストヘッダにタグ文字を含めることができました。
以下にPoCがあります。Adobe ReaderプラグインがインストールされたWin10のIE11で動作を確認済みです。

https://l0.cm/xss_referrer.pdf?<script>alert(1)</script>

どうも、プラグイン経由のリクエストが考慮されていないみたいですね。


以上、Anniversary Update以後でも使えるReferrer文字列のXSS手法の紹介でした!
今月はもう1つか2つブログを書くつもりです。