http80

Web security research

Let's develop a managed module of IIS and run it with Azure App Service / IISの自作モジュール(.dll)を作ってAzure App Serviceで動かしてみよう

 みなさま、おはようございます、こんにちは、こんばんは。年の瀬ですね。近況“やばい”の一言ですが、Tekka Advent Calender 2018の17日目の記事を投稿します。(今日はきっと17日です。)

 Tekkaや個人で何か作った訳ではないですが、ニッチなTipsをご紹介します。

adventar.org  余談ですが、今年を漢字で表すと「決」です。

 

●概要

 Microsoftのパブリッククラウド AzureのApp Serviceで、IISの自作モジュール(Managed Module)を動かしてみよう!という趣旨の記事です。App ServiceのFreeプラン内でできることをご紹介します。Azureについて調査していくと、むしろ、無料プランでここまでできるのか……と驚きました。本番環境向きのプランではないにしても、自由度が高く素晴らしい。

 簡単に補足すると、App ServiceはWindowsのWebサーバ「Internet Information Services」と呼ばれるもので動いており、激安レンタルサーバなどでよく聞くApache等とは違います。軽くWebサーバ機能として利用する分には、IISを深く意識する機会はないかと思いますが、ASP.NET絡みで開発する場合は、ASP.NETのライフサイクルの中身くらいは理解しておくと良さげです。IISの仕組みは奥が深く、魅力があります。ASP.NET/IISの仕組みを語りだすとコミケ用の薄い本が出来てしまうので、今回は割愛します。

 動かすことが目的なので、詳細には取りまとめません。

  • Microsoft/Azureアカウントの取得
  • Azureサブスクリプション契約(無料枠, 無料プラン)
  • App ServiceでWebアプリの作成
  • Webアプリケーションのデプロイ(デフォルトドキュメントのままでも可)

ここまで終わっていることを想定しています。本稿の内容は下記の通りです。

  • サンプルのIISマネージドモジュールのビルドする
  • FTPSで特別なディレクトリへDLLを配置する
  • web.configを作成し配置する

それでは簡単に、IISのマネージドモジュールの作り方、Azure App ServiceへFTPSでの接続方法、IISのモジュールをEnableする方法をご紹介します。

 

 ●サンプルのIISマネージドモジュールのビルド

  ではさっそく、IISマネージドモジュールを作ってみよう

 1. Visual Studioを立ち上げる(2015 or 2017を想定)

 2. 空のプロジェクトを作成する

f:id:reinforchu:20181219124317p:plain

 テンプレート→Visual C# >クラスライブラリ(.NET Framework)

 名前→ここでは「CustomHeader」と命名しました。

 ターゲットフレームワーク→.NET Framework 3.5 (4.xでも可) ※後方互換のため

  3. 「System.Web」を参照に追加する

f:id:reinforchu:20181219125108p:plain

 参照のコンテキストメニューから「参照の追加」をクリックします。

f:id:reinforchu:20181219125235p:plain
 検索ボックスに「System.Web」と入力し、中央のリスト内の左のチェックボックスに該当の「System.Web」にチェックを入れてOKボタンを押下します。

 4. サンプルコードの貼り付け

       Class1.csに下記のコードをそのままぺた貼りします。

CustomHeader

 4. ソリューションのビルドをする

 5. 出来上がったバイナリ(DLL)を取り出す

f:id:reinforchu:20181219132738p:plain

<プロジェクトディレクトリ>\<プロジェクト名>\bin\Debug にDLLがあるので、任意の場所にコピーするか、覚えておきます。(もしくは\Release)

 

・FTPSで特別なディレクトリへDLLを配置する

 1. FTPSでAzure App ServiceのWebアプリのディレクトリにアクセスする(WinSCP)

f:id:reinforchu:20181219205405p:plain

 AzureのPortalから、FTPSの資格情報を取得します。対象のWebアプリのデプロイセンターからFTP/FTPSと遷移すると良いでしょう。スクリーンショットでは、テスト用に「rein.azurewebsites.net」というアプリケーションを作成しました。今回はFTPクライアントとしてWinSCPを使用します。

f:id:reinforchu:20181219204330p:plain

 資格情報をそのままコピペします。

 転送プロトコル→FTP ※SFTPではありません!

 暗号化→暗黙のTLS(Implicit) ※Explicitでもいけますが、Azureでは平文21/tcpを待ち受ける設定もできるので、Implicitが妥当でしょう

 ホスト名およびユーザ名とパスワード→コピペしよう

f:id:reinforchu:20181219135137p:plain

 無事FTPSでログインできると\wwwrootが見えます。これで下準備は完了です。

  2. 特別なディレクトリ「\bin」の作成

f:id:reinforchu:20181219135854p:plain

  wwwroot直下に「bin」というディレクトリを作成します。

 3. 自作モジュール(DLL)のコピー

f:id:reinforchu:20181219140056p:plain

 そのまま普通にコピーしてください。これで、自作モジュールの配置は終わりました。

・web.configを作成し配置する

 1. 下記の内容のweb.configを作成します

web.config

 2.  wwwroot直下に「web.config」を配置する

f:id:reinforchu:20181219141427p:plain

  最終的には上記の画面のようになっているでしょう。以上で、自作モジュールの導入は完了です。

 

●動作確認

 wwwrootのデフォルトドキュメントにアクセスしてみましょう。普通に直下にアクセスするだけです。例えば、https://rein.azurewebsites.net/ です。

 コケてなければ「Your App Service app is up and running」というメッセージのページが出てくると思います。見た目変わってないので、どこを確認するんだ、ということですが、HTTP Response Headerを確認します。Local Proxyを使って通信をInterceptしてみてください。Fiddler, Burp, ZAPなんでもいいです。(見るだけならFiddlerが楽です。)

f:id:reinforchu:20181219200947p:plain

 Burpで見た場合のHTTPレスポンス例です。選択部分に注目してください。「X-Powered-By: CustomHeader/1.0.0.0」というヘッダが追加されていることが分かります。これでちゃんと動作しているか確認できました!

 話が戻りますが、サンプルで作ったモジュールは一体何するものなのかというと、命名通り「X-Powered-By: CustomHeader/1.0.0.0」というヘッダを追加するだけのしろものです。

 

●後片付け

 遊び終わったアプリケーションは停止して吉です。ちなみにデフォルトのままだと平文のFTPが空いてる状態なので、無効にしておきましょう。

 

 ●任意のDLLが動く、ということ

 Azure App Serviceの無料プランでも、モジュールが組み込めるこの柔軟性はわくわくしますね。サンプルコードはヘッダ追加するだけですが、書きようによっては、遊び甲斐がありそうです。これは先出し調査結果情報ですが、Azureは基本的にオンプレミスのIIS(という言い回しは正しいか分かりませんが)と遜色なく使えそうで、VCでコンパイルしたDLLでも見事期待通りに動いてくれました。具体的には、自作・独自で実装ないしバイナリさえ用意すれば、Azure App Serviceが実装していない拡張機能を使うことが出来ました。

 IISが標準提供されている機能をDevelopment用途として使っている理解ですが、中の人判断でまずかったらご一報ください。

azure.microsoft.comここを基準として読みました。

 

●構想、そして振り返り

 雑談です。遡ること4-5年前、オープンソースでセキュリティ系のプロダクト作りたいなと、もやもやして、そういえばIISのApacheでいうmod_security的なのってあったけ、と思い立ち作り始めたのが「NachtWal」です。これがIISのモジュールを作ろうとしたきっかけになりました。

github.com 現在はXSS(Reflected)をなんちゃってブロックする程度で停滞していますが、作り上げたい思いは強くあります。構想や技術的な面はあるのに、リポジトリにコミットまで出来ていないことが多々あり、悔しく思います。例えば、ASP.NETライフサイクルにおいて、精度の課題は別にしてStored-XSSを検知・防御する実装は可能であることを個人で実験・検証済みですし、AzureのApp Serviceで動くことも確認していて、クラウド対応でDLLを放り込んでおけば、勝手に良きに計らってくれるぐらいには作りたいですね。ただ、マネージドモジュールにおいてのHTTPのIntercept行為には致命的な問題があり、ハンドラマッピングに基づき実行されたタイミングで、どうやらNamed pipeでごにょごにょやってるそうなんですが(確証はないです)、マネージドモジュールはBodyを横取りしてしまうIssueにぶちあたってます。この問題について、的確に言及しているブログ記事は1件見つけましたが、それ以上の情報はなく困ってます。

mvolo.com 解決策はあって、「ネイティブモジュール」であれば起こらないということは分かってます。ああ、VC++をやるべき時が来てしまったようだ。もっと早くVC++にステ振りしておけば良かった。次やる言語はVC++だ。

 Microsoft界隈の方々と親睦を深めていきたいお気持ち高まってきた。詳しい人とお話したいし、機会に恵まれれば参画していきたい。お気軽にコンタクトくださいませ。来年のキーワードは、Azure, ASP.NET/IIS, Securityでやっていきたい。

 Twitterで何度も投稿していますが、この本はちょーおすすめ。

f:id:reinforchu:20181219123447j:plain

  それでは、良いお年を。