二重エンコードとは、同じエンコード方式を使用してデータを 2 回続けてエンコードする行為です。これは通常、ユーザー入力を傍受する認証方式やセキュリティ フィルターを回避するための攻撃手法として使用されます。セキュリティ フィルターに対する二重エンコード攻撃では、これらのフィルターによって不正とみなされるペイロードの文字が、二重エンコードされた形式に置き換えられます。
二重 URI エンコーディングは、データが2 回続けてURI エンコードされる特殊なタイプの二重エンコーディングです。これは、コード インジェクション、ディレクトリ トラバーサル、クロスサイト スクリプティング(XSS)、SQL インジェクションに対する認証スキームやセキュリティ フィルターを回避するために使用されています。
説明
二重符号化では、データは同じ符号化方式を使用して2回続けて符号化されます。つまり、二重符号化された形式のデータは、符号化関数でXある。 [1]Encode(Encode(X))Encode
二重エンコードは通常、ユーザー入力を傍受する認証スキームやセキュリティフィルタを回避する攻撃手法として使用されます。[2]セキュリティフィルタに対する二重エンコード攻撃では、フィルタによって不正とみなされるペイロードの文字が、二重エンコードされた形式に置き換えられます。[3]セキュリティフィルタは、データXとそのエンコードされた形式を不正とみなす可能性があります。[4]ただし、Encode(Encode(X))データの二重エンコードされた形式である がXセキュリティフィルタによって不正とみなされずに通過する可能性はありますが、後でターゲットシステムが の二重デコードされた形式Encode(Encode(X))、つまり を使用するXと、フィルタでは不正とみなされる可能性があります。[5]
二重URIエンコーディング
二重 URI エンコードは、二重パーセントエンコードとも呼ばれ、データが 2 回続けて URI エンコードされる特殊なタイプの二重エンコードです。[6]つまり、データの二重 URI エンコード形式Xは ですURI-encode(URI-encode(X))。[7]たとえば、 の二重 URI エンコード形式を計算する場合<、まず が<として URI エンコードされ、%3C次に が として URI エンコードされるため%253C、つまり となりますdouble-URI-encode(<) = URI-encode(URI-encode(<)) = URI-encode(%3C) = %253C。[8]別の例として、 の二重 URI エンコード形式を計算する場合../、まず が として../URI エンコードされ、%2E%2E%2F次に が として URI エンコードされるため%252E%252E%252F、つまり となりますdouble-URI-encode(../) = URI-encode(URI-encode(../)) = URI-encode(%2E%2E%2F) = %252E%252E%252F。[9]
二重 URI エンコードは、通常、Web アプリケーションや Web ブラウザに対する攻撃手法として使用され、ユーザ入力を傍受する認証スキームやセキュリティ フィルタをバイパスします。[10] [11]たとえば.、 とその URI エンコード形式は%2E一部のディレクトリ トラバーサル攻撃で使用されるため、セキュリティ フィルタでは通常不正とみなされます。[12]%252Eただし、の二重 URI エンコード形式である が.セキュリティ フィルタで不正とみなされず、通過する可能性はありますが、後でターゲット システムがディレクトリ トラバーサル攻撃に関連するパスを構築するときに、 の二重 URI デコード形式、%252Eつまり が使用される可能性があり.、この場合、フィルタでは不正とみなされます。[13]
二重URIエンコーディング攻撃は、コードインジェクション、ディレクトリトラバーサル、XSS、SQLインジェクションに対する認証スキームやセキュリティフィルターを回避するために使用されてきました。[14]
防止
一部のユーザー入力を同じデコード方式で2回デコードすると(1回はセキュリティ対策の前、もう1回はセキュリティ対策の後)、二重エンコード攻撃によってセキュリティ対策が回避される可能性があります。[15]したがって、二重エンコード攻撃を防ぐためには、ユーザー入力に対するすべてのデコード操作は、ユーザー入力を傍受する認証方式とセキュリティフィルターの前に行う必要があります。[16]
例
PHP の
$_GETPHPプログラミング言語では、およびのデータ項目は$_REQUEST十分にURIデコードされているため、プログラマーはurldecodeそれらに対して関数を呼び出すことを避ける必要があります。[17]またはurldecodeから読み取られたデータに対して関数を呼び出すと、データは必要以上にURIデコードされるため、二重URIエンコード攻撃を受ける可能性があります。
$_GET$_REQUEST
ディレクトリトラバーサル
次の PHP プログラムでは、 の値$_GET["file"]を使用して、ユーザーに送信されるファイルのパスを構築します。これにより、HTTP GET パラメータにペイロードを組み込むディレクトリ トラバーサル攻撃が発生する可能性がありますfile。ディレクトリ トラバーサル攻撃に対するセキュリティ フィルタとして、このプログラムは から読み取った値で$_GET["file"]ディレクトリ トラバーサル シーケンスを検索し、見つかった場合は終了します。ただし、このフィルタの後、プログラムは から読み取ったデータを URI デコードするため$_GET["file"]、二重 URI エンコード攻撃に対して脆弱になります。
<?php
/* $_GET はすでに URI デコードされていることに注意してください */
$path = $_GET [ "file" ];
/* セキュリティ フィルター */
/* ユーザー入力にディレクトリ トラバーサル シーケンスが含まれている場合は終了します */
if ( strstr ( $path , "../" ) または strstr ( $path , ".. \\ " ))
{
exit ( "ディレクトリ トラバーサルの試行が検出されました。" );
}
/* ユーザー入力をもう一度 URI デコードします */
$path = urldecode ( $path );
/* ユーザー入力を使用して送信するファイル パスを構築します */
echo htmlentities ( file_get_contents ( "uploads/" . $path ));
このフィルタは、../../../../etc/passwdおよびその URI エンコード形式などのペイロードを防止します%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fpasswd。ただし、%252E%252E%252F%252E%252E%252F%252E%252E%252F%252E%252E%252Fetc%252Fpasswdの二重 URI エンコード形式である は../../../../etc/passwdこのフィルタをバイパスします。二重 URI エンコードされたペイロード%252E%252E%252F%252E%252E%252F%252E%252E%252F%252E%252E%252Fetc%252Fpasswdが使用されると、 の値は$_GET["file"]となり、これにはディレクトリ トラバーサル シーケンスが含まれないためフィルタを通過し、を返す関数%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fpasswdに渡され、攻撃が成功します。
urldecode../../../../etc/passwd
クロススレッド
次の PHP プログラムでは、 の値を$_GET["name"]使用して、ユーザーに表示されるメッセージを作成します。これにより、ペイロードを HTTP GET パラメータに組み込む XSS 攻撃の可能性が生まれます。XSS 攻撃に対するセキュリティ フィルターとして、このプログラムは 関数を介してname読み取った値をサニタイズします。ただし、このフィルターの後、プログラムは から読み取ったデータを URI デコードするため、二重 URI エンコード攻撃に対して脆弱になります。
$_GET["name"]htmlentities$_GET["name"]
<?php
/* $_GET はすでに URI デコードされていることに注意してください */
$name = $_GET [ "name" ];
/* セキュリティ フィルター */
/* htmlentity 経由でユーザー入力をサニタイズします */
$name = htmlentities ( $name );
/* ユーザー入力をもう一度 URI デコードします */
$name = urldecode ( $name );
/* ユーザー入力を使用して表示されるメッセージを作成します */
echo "Hello " . $name ;
このフィルタは、<script>alert(1)</script>およびその URI エンコード形式などのペイロードを防止します%3Cscript%3Ealert%281%29%3C%2Fscript%3E。ただし、%253Cscript%253Ealert%25281%2529%253C%252Fscript%253Eの二重 URI エンコード形式である は<script>alert(1)</script>このフィルタをバイパスします。二重 URI エンコードされたペイロード%253Cscript%253Ealert%25281%2529%253C%252Fscript%253Eが使用されると、 の値は$_GET["name"]となり%3Cscript%3Ealert%281%29%3C%2Fscript%3E、これには不正な文字が含まれないため、変更されずに関数を通過し、を返す関数htmlentitiesに渡されるため、攻撃が成功します。
urldecode<script>alert(1)</script>
出典
- CAPEC (2022). 「CAPEC-120: ダブルエンコーディング」. capec.mitre.org . 3.7 . 2022年7月23日閲覧。
- CWE (2022). 「CWE-174: 同一データの二重デコード」cwe.mitre.org . 4.8 . 2022年7月23日閲覧。
- Imperva (2022). 「二重 URL エンコーディング」. docs.imperva.com . 2022 年7 月 23 日閲覧。
- OWASP (2022). 「二重エンコーディング」. owasp.org . 2022年7月23日閲覧。
- PHP (2022). 「urldecode」. php.net . 2022年7月23日閲覧。
- PortSwigger (2022). 「エンコードを使用した攻撃の難読化」. portswigger.net . 二重 URL エンコードによる難読化. 2022 年7 月 23 日閲覧。
- Prasad, Prakhar (2016)。「二重エンコーディング」。現代の Web 侵入テストの習得。Packt Publishing。pp. 11–14。ISBN 978-1785284588。
参考文献
- ^ CAPEC 2022、説明。「攻撃者は、一連の文字のエンコード プロセス (つまり、文字の文字エンコード) を繰り返して、特定のリクエストのペイロードを難読化します。」
- ^ CAPEC 2022、説明、実行フロー。「この[二重エンコード]により、攻撃者は、トラバーサル攻撃やインジェクション攻撃で使用される可能性のある不正な文字や文字列を検出しようとするフィルターを回避できる可能性があります[...]たとえば、URL内の特定の文字(ドットやスラッシュなど)を二重エンコードすることで、攻撃者はWebサーバー上の制限されたリソースにアクセスしようとしたり、保護されたページを強制的に参照しようとしたりする可能性があります(これにより、認証サービスが破壊されます)。攻撃者は、この攻撃パターンを使用して、コマンドインジェクション、SQLインジェクションなどの他のインジェクションスタイルの攻撃を試みる可能性があります。」
- ^ CAPEC 2022、説明、実行フロー。「この[二重エンコード]により、トラバーサル攻撃やインジェクション攻撃で使用される可能性のある不正な文字や文字列を検出しようとするフィルターを攻撃者が回避できる可能性があります。[...] フィルターを突破するために、入力の一部に対して二重エンコードを試みてください。」
- ^ OWASP 2022、説明。「二重エンコーディングを使用すると、ユーザー入力を一度だけデコードするセキュリティ フィルターをバイパスできます。」
- ^ OWASP 2022、説明。「二重エンコーディングを使用すると、ユーザー入力を一度だけデコードするセキュリティ フィルターをバイパスできます。2 回目のデコード プロセスは、エンコードされたデータを適切に処理するが、対応するセキュリティ チェックが実施されていないバックエンド プラットフォームまたはモジュールによって実行されます。」
- ^ Prasad 2016、p. 11。「ダブルパーセントエンコーディングは、各文字が1回ではなく2回エンコードされるというひねりを加えたパーセントエンコーディングと同じです。」
- ^ Prasad 2016、p. 11。「ダブルパーセントエンコーディングは、各文字が1回ではなく2回エンコードされるというひねりを加えたパーセントエンコーディングと同じです。」
- ^ Prasad 2016、11 ページ。「したがって、二重エンコードを使用して < をエンコードする必要がある場合、最初にパーセントエンコードされた形式 (%3c) にエンコードし、次に % 文字を再度パーセントエンコードします。この結果は %253c になります。」
- ^ OWASP 2022、説明。「たとえば、../ (ドット-ドット-スラッシュ) 文字は、16 進数表現で %2E%2E%2F を表します。% 記号が再度エンコードされると、16 進コードでの表現は %25 になります。二重エンコード プロセス ../ (ドット-ドット-スラッシュ) の結果は %252E%252E%252F になります。」
- ^ Prasad 2016、p. 11。「このテクニック[ダブルパーセントエンコーディング]は、特定のエンコードされた文字をブラックリストに登録しようとするフィルターを回避するときに非常に便利です。」
- ^ CAPEC 2022、実行フロー。「たとえば、URL 内の特定の文字 (ドットやスラッシュなど) を二重にエンコードすると、攻撃者は Web サーバー上の制限されたリソースにアクセスしようとしたり、保護されたページを強制的に参照したり (認証サービスを破壊したり) する可能性があります。攻撃者は、この攻撃パターンを使用して、コマンド インジェクション、SQL インジェクションなどの他のインジェクション スタイルの攻撃を試みることも可能です。」
- ^ CAPEC 2022、説明。「たとえば、パストラバーサル攻撃でよく使用され、フィルターによってブロックされることが多いドット (.) は、%2E として URL エンコードされる可能性があります。ただし、多くのフィルターはこのエンコードを認識し、リクエストをブロックします。」
- ^ CAPEC 2022、説明。「二重エンコードでは、上記の URL エンコードの % が %25 として再度エンコードされ、%252E になります。一部のフィルターではキャッチされない可能性がありますが、ターゲットのインタープリターではドット (.) として解釈される可能性があります。」
- ^ CWE 2022、観察された例。
- ^ CWE 2022、説明。「ソフトウェアは同じ入力を 2 回デコードするため、デコード操作の間に行われる保護メカニズムの有効性が制限される可能性があります。」
- ^ CWE 2022、潜在的な緩和策。「入力は、検証される前にデコードされ、アプリケーションの現在の内部表現に正規化される必要があります (CWE-180)。」
- ^ PHP 2022、注記。「警告: スーパーグローバル $_GET と $_REQUEST はすでにデコードされています。$_GET または $_REQUEST 内の要素に urldecode() を使用すると、予期しない危険な結果が生じる可能性があります。」
外部リンク
- 二重エンコード攻撃に関する OWASP エントリ
- 二重エンコード攻撃に対するCAPECエントリ
- 二重エンコード攻撃によって悪用される脆弱性の CWE エントリ
