IIS6のWebDAVに脆弱性が発見された(ヤバイよ、ヤバイよ)

NTTデータセキュリティからIIS6でWebDAV認証回避の脆弱性にレポートが公開された。IISで認証付きのページの認証がバイパスされてしまう危険性があるとのこと。以下がレポート。


http://www.nttdata-sec.co.jp/article/vulner/pdf/report20090518.pdf


一応、実証してみたところ超簡単に再現できた。その再現プロセスは後述するとして、この脆弱性は攻撃の容易性と攻撃された場合のインパクトのデカさからかなり要注意だと思われる。WebDAV使ってWebコンテンツの更新をやっているところ(しかも、公開WEB上で)がどの程度存在するのかわからないけど、もし、そのような運用をしているサーバがあったら、即刻、対処すべし。また、WebDAVを使っていないにも関わらず有効にしているサーバがあったら一刻も早く対処すべし。

対処方法はIISマネージャでWebDAVを無効にするだけ。基本、デフォルトでは無効になっているはず。



以前、Windows2000+IIS5の環境において、コンテンツが改ざんされるというインシデントに対応したことがあったが、このときも、WebDAV経由でのコンテンツの改ざんだった。このときの侵害された要因としては使用していないにも関わらず、Front Page Server Extensionsがインストールされており、かつwwwrootに対する認証機構を設定していなかったため起きた。IIS脆弱性をつかれたわけではなく構築側の設定ミスであり認証設定さえしてあれば問題はなかった。今回はIIS自体に脆弱性があるわけで、当然ながらキチンと認証設定されていてもまったく意味をなさなくなる。

結局のところWebDAV文字コード処理に問題があるのだが、ほんとにこの文字コードってやつは厄介だよ。ほんとになんとかならんもんか。


では、今回の脆弱性を再現してみよう。海外のサイトとか見てみると詳しく書いてあるんだけどね。まず、適当に仮想ディレクトリをつくる。ウィザード中のアクセス許可は、とりあえず「読み取り」「書き込み」「参照」にチェック。




次にこの仮想ディレクトリに認証を設定する。



あとはWebDAVを有効にする。



これだけで準備は完了。では、WebDAVリクエストを送信してみよう。まずはGETで先ほどの仮想フォルダの下にあるコンテンツを取得してみよう。以下のようなリクエストを投げてみる。GETはHTTPメソッドではなくWebDAVのGETメソッドであることを示すために「Translate:f」ヘッダを付加する。これは非標準でMS独自の拡張ヘッダ。MSのWebDAVサーバにはこのヘッダを付けて送るらしい。

GET/TEST/test/test.html HTTP/1.1
Translate: f
Connection: close
Host: 192.168.11.180


結果は以下の通り401が返ってきた。認証エラーだ。ちゃんと認証が利いていることを示している。



続いて、以下のようなリクエストを投げてみる。「%c0%af」を要求するコンテンツのパス内の仮想ディレクトリ名の適当な位置に挟む。

GET/TE%c0%afST/test/test.html HTTP/1.1
Translate: f
Connection: close
Host: 192.168.11.180


結果は以下の通り。200で返ってきてコンテンツをGETできてしまった。



同様に「%c0%af」を挟み、PROPFINDメソッドでフォルダ/ファイル構成を見ることもできる。以下がそのリクエストとレスポンスの結果。

PROPFIND /TE%c0%afST/test HTTP/1.1
Host: 192.168.11.180
User-Agent: hogehoge
Connection: TE
TE: trailers
Depth: 1
Content-Length: 298
Content-Type: application/xml











おー。関心している場合ではない。これはやばい。この「%c0%af」問題。確か以前のバージョンのIISでも同じような問題があったと思った。パストラバーサルが可能になってしまうというやつ。「%c0%af」は「/」とデコードされるので、たとえば、「..%c0%af..%c0%af」なんてリクエストを投げると非公開のファイルが覗けてしまうやつ。これに似ている。

ここで、なぜ「%c0%af」が「/」になるかが難しいよね。ここでちょっと簡単に説明してみる。簡単に説明するので正確ではない部分もあるかもしれない。

まず第一に文字コードのお話。コンピュータで扱える文字って、英語圏の人ならアルファベットと記号だけでいいのでそんな数いらない。でも世界中には無数に文字が存在する。んで、どの文字をコンピュータで扱うのかを決めようということで「符号化文字集合」というコンピュータで使う文字を集めた。つまり、一文字一文字にIDを割り振ったようなもんだね。この規定が ASCII とか UNICODE とか。

で、実際にコンピュータに実装するときにどのようなビットパターンにするかは別の話で、これらを「文字符号化方式」という。これらの規定が UTF-8 とか UTF-16 とか SHIFT−JISとかになる。で、UTF-8のビットパターンは以下のようになっている。

0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx


この「x」の部分に Unicode で規定されている符号を右詰に格納するというルール。で、問題になっている「%c0%af」はURLエンコードだ。これをビットにしてみると。

11000000 10101111


これを上のルールにあてはめてみると(上から2つ目のやつ)。Unicode で規定されている符号部分は、

0010 1111


つまり 「%2f」。これは「/」を表す。というわけ。 ということは、だ。ルールに則ると「/」を UTF-8 で書くと何も「%c0%af」だけではないということになる。つまり、以下もすべて「/」になる。

%e0 %80 %af
%f0 %80 %80 %af
%f8 %80 %80 %80 %af
%fc %80 %80 %80 %80 %af

実際に、上の攻撃リクエストで「%c0%af」の部分を「%e0%80%af」にしても攻撃は成功した。なぜか、それよりも長いパターンの場合はBadRequestとして扱われてしまった。では、なぜこのようにUTF-8の「/」を挿入すると、認証機構をバイパスできてしまうのかについてなんだけれども。

とあるサイトによると、WebDAVでは認証チェックの段階でデコードするからだということらしい。つまり、たとえば /TE%c0%afST/test/ へのリクエストがあった場合、まず、デコードするので /TE/ST/test/ となる。そして、このようなフォルダは存在しないので、認証不要と判断され処理が先に進む。そして、コンテンツにアクセスする前にこのUnicode部分が除去されるということらしい。