PHP プログラムの一般的な脆弱性を攻撃する方法 (パート 2)
翻訳:analyst (アナリスト)
出典: http://www.china4lert.org
PHP プログラムの一般的な脆弱性を攻撃する方法 (パート 2)
原著者: Shaun Clowes
翻訳:analyzet
[ライブラリ ファイル]
先ほど説明したようにinclude() と require() は主にコード ベースをサポートするためのものです。通常、この独立したファイルがコード ベースであり、その中の関数を使用する必要があります。このコードベースを現在のファイルに含めます。
当初、PHP プログラムを開発してリリースするとき、コード ベースとメインのプログラム コードを区別するために、通常はコード ベース ファイルに拡張子「.inc」を設定していましたが、すぐにこれは間違いであることがわかりました。 PHP インタープリターによってファイルを PHP コードに正しく解析できないためです。このようなファイルをサーバー上で直接リクエストすると、そのファイルのソースコードが取得されます。これは、PHP が Apache モジュールとして使用される場合、PHP インタープリターがファイルの拡張子に基づいて PHP に解析するかどうかを決定するためです。コードの。拡張子はサイト管理者によって指定されます。通常は「.php」、「.php3」、「.php4」です。重要な構成データが適切な拡張子なしで PHP ファイルに含まれている場合、リモート攻撃者がこの情報を簡単に入手できます。
最も簡単な解決策は、各ファイルに PHP ファイル拡張子を指定することです。これにより、ソース コードの漏洩を十分に防ぐことができますが、このファイルを要求することにより、攻撃者がそのファイル内で実行されるはずのコードを使用する可能性もあります。コンテキストは独立して実行されるため、前述したすべての攻撃につながる可能性があります。
以下は明白な例です:
main.php:
$libDir = "/libdir";
$langDir = "$libdir/langages";
include ( "$libdir/load language.php":
?>
"libdir/load language.php" は、"main.php" によって呼び出される場合には非常に安全ですが、"libdir/load language" には ".php" 拡張子があるため、リモート攻撃者によって攻撃されます。このファイルを直接リクエストでき、「$langDir」と「$userLang」の値を任意に指定できます。
[セッションファイル]
PHP 4 以降のバージョンでは、ページ間の状態を保存することが主な機能です。たとえば、ユーザーが Web サイトにログインすると、そのユーザーがログインしたことと、誰が Web サイトにログインしたかがセッションに保存され、すべての PHP コードがこのステータス情報を取得できます。
実際、リモートブラウザが常にリクエストを送信する場合、セッションが開始されると(実際には最初のリクエストで自動的に開始するように設定ファイルに設定されます)、ランダムな「セッションID」が生成されます。この「セッション ID」を使用すると、セッションが維持されます。これは、Cookie を使用するか、各ページでフォーム変数 (「セッション ID」を含む) を送信することで簡単に実現できます。その値は、PHP プログラムによって異なります。各 PHP スクリプトの終了後にセッション ファイルに保存され、各 PHP スクリプトの開始前に変数にもロードされます。 以下に簡単な例を示します。
session_destroy(); // session
$session_auth = "shaun";
session_register("session_auth"); // $session_auth をセッション変数として登録します
?>
新しいバージョンでは "$session_auth" の値が "shaun" に設定されます"。変更された場合、今後のスクリプトは変更された値を自動的に受け入れます。これは確かにステートレス Web にとって非常に優れたツールですが、注意する必要もあります。
明らかな問題は、変数がセッションから取得されることを確認することです。たとえば、後続のスクリプトが次の場合、
if (!empty($session_auth))
// ここでサイトへのアクセスを許可します
?>
上記のコードは、「$session_auth」が設定されている場合、ユーザー入力ではなくセッションから設定されることを前提としています。サイトへのアクセスを取得します。攻撃者は、この攻撃方法を使用する前に変数をセッションに登録する必要があることに注意してください。変数がセッションに配置されると、フォーム入力はすべて上書きされます。
セッション データは通常、ファイルに保存されます (場所は設定可能で、通常は「/tmp」)。このファイルには、変数名、変数タイプ、変数が含まれます。値とその他のデータ。マルチホスト システムでは、ファイルが Web サーバーを実行しているユーザー (通常は誰も) として保存されるため、悪意のあるサイト所有者がセッション ファイルを作成して他のサイトにアクセスしたり、セッション ファイルの機密情報を検査したりする可能性があります。 。
セッション メカニズムは、攻撃者が入力をリモート システム上のファイルに保存するための別の便利な場所も提供します。これが不可能な場合、攻撃者は PHP コードを含むファイルをリモート システムに配置する必要があります。ファイルをアップロードすることでこれを行います。彼は通常、セッションを使用して自分の希望に従って変数に値を割り当て、次にセッション ファイルの場所を推測します。ファイル名は「php
さらに、攻撃者は任意に「セッション ID」(「hello」など)を指定し、この「セッション ID」を使用してセッション ファイル(「/tmp/sess_hello」など)を作成することもできますが、「セッション ID」には文字と数字の組み合わせのみを使用できます。
[データ型]
PHP には緩いデータ型があり、変数の型は変数が配置されているコンテキストによって異なります。例: "$hello" は値 "" を持つ文字列変数として開始されますが、評価されると整数変数 "0" になり、予期しない結果が生じる場合があります。 "$hello" の値が "000" と "0" の間で異なる場合、empty() によって返される結果は true ではありません。
PHP の配列は連想配列です。つまり、配列のインデックスは文字列型です。これは、「$hello["000"]」と「$hello[0]」も異なることを意味します。
プログラムを開発する際には、上記の問題を注意深く考慮する必要があります。たとえば、ある場所で変数が「0」であるかどうかをテストし、別の場所でそれを検証するために empty() を使用するべきではありません。
[エラーが発生しやすい関数]
PHP プログラムの脆弱性を分析する場合、ソース コードが入手できれば、エラーが発生しやすい関数のリストが非常に必要になります。これらの関数のパラメータをリモートで変更できれば、脆弱性が見つかる可能性が高くなります。以下は、エラーが発生しやすい関数の詳細なリストです:
require(): 指定されたファイルの内容を読み取り、PHP コードとして解釈します
include(): 上記と同じ
eval( ): 指定された文字列は PHP コードとして実行されます
preg_replace(): 「/e」スイッチと一緒に使用すると、置換文字列は PHP コードとして解釈されます
<コマンド実行>
exec(): 指定されたコマンドを実行します、実行結果の最後の行を返します
passthru(): 指定されたコマンドを実行し、すべての結果をクライアントのブラウザに返します
``: 指定されたコマンドを実行し、すべての結果を配列に返します
system(): passthru(と同じ) ) ですが、異なります バイナリデータを処理します
popen(): 指定されたコマンドを実行し、入力または出力を PHP ファイル記述子に接続します
fopen(): ファイルを開き、PHP ファイル記述子に対応します
readfile() : ファイルの内容を読み取り、クライアントのブラウザに出力します
file() : ファイルの内容全体を配列に読み取ります
翻訳者注: 実際、このリストは完全ではありません。 ()」などのコマンドを実行する場合もあるので、自分で追加する必要があります。
[PHP のセキュリティを強化する方法]
上で紹介したすべての攻撃は、PHP 4 のデフォルトのインストールでもうまく実装できますが、何度も繰り返しましたが、PHP の設定は、いくつかの PHP オプションを設定することで非常に柔軟になります。これらの攻撃の一部に抵抗することは十分に可能です。以下に、実装の難易度に応じていくつかの構成を分類しました。
*低難易度
**中低難易度
***中高難易度
****高難易度
上記の分類は単なる個人的な意見です。ただし、PHP が提供するすべてのオプションを使用すると、サードパーティのコードを使用した場合でも、PHP は非常に安全になることは保証できます。これらの機能の多くはもう利用できないためです。
**** 「register_globals」を「off」に設定します
このオプションは、PHP がユーザー入力用のグローバル変数を作成することを無効にします。つまり、ユーザーがフォーム変数「hello」を送信した場合、PHP は「$hello」を作成しませんただし、「HTTP_GET/POST_VARS['hello']」のみが作成されます。これは PHP では非常に重要なオプションです。このオプションをオフにすると、プログラミングに大きな不便が生じます。
*** 「safe_mode」を「on」に設定します
このオプションをオンにすると、次の制限が追加されます:
1.実行できるコマンドを制限する
2.使用できる機能を制限する
3.スクリプトの所有権とターゲット ファイルの所有権に基づくファイル アクセス制限
4.ファイルアップロード機能を無効にする
これは ISP にとって優れたオプションであり、PHP のセキュリティも大幅に向上します。
** "open_basedir" を設定します
このオプションは、指定されたディレクトリ外でのファイル操作を禁止し、ローカル ファイルまたはリモート ファイルに対する include() による攻撃を効果的に排除できますが、ファイル アップロードやセッション ファイルへの攻撃には依然として注意する必要があります。
** "display_errors" を "off" に設定し、"log_errors" を "on" に設定します
このオプションは、エラー メッセージが Web ページに表示されることを禁止しますが、ログ ファイルに記録されるため、攻撃者による攻撃を効果的に防ぐことができます。ターゲット スクリプト内の関数の検出。
* 「allow_url_fopen」を「off」に設定します
このオプションはリモート ファイル機能を無効にすることができます。強くお勧めします。
それでは、この記事はここで終わります。その他の関連情報を知りたい場合は、元の記事 http://www.securereality.com.au/studyinscarlet.txt を参照してください。
<全文終了>