ホームページ >バックエンド開発 >PHPチュートリアル >PHP プログラミングの一般的な脆弱性とコード例、PHP プログラミングの脆弱性の例_PHP チュートリアル

PHP プログラミングの一般的な脆弱性とコード例、PHP プログラミングの脆弱性の例_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:21:26738ブラウズ

PHP プログラミングの一般的な脆弱性とコード例、PHP プログラミングの脆弱性の例

PHP が普及するにつれ、一部のハッカーは PHP プログラムの脆弱性を利用した攻撃を常に行っています。このセクションでは、グローバル変数、リモート ファイル、ファイル アップロード、ライブラリ ファイル、セッション ファイル、データ型、エラーが発生しやすい関数の側面から PHP のセキュリティを分析します。

グローバル変数を介して攻撃するにはどうすればよいですか?

PHP の変数は事前に宣言する必要はなく、初めて使用するときに自動的に作成され、その型はコンテキストに基づいて自動的に決定されます。プログラマの観点から見ると、これは間違いなく非常に便利なアプローチです。変数を作成したら、プログラム内のどこでも使用できます。この機能の結果、プログラマは変数を初期化することがほとんどなくなります。

明らかに、PHP ベースのアプリケーションの main 関数は通常、ユーザー入力 (主にフォーム変数、アップロードされたファイル、Cookie など) を受け入れ、入力データを処理して、結果をクライアントのブラウザーに返します。 PHP コードがユーザー入力にできるだけ簡単にアクセスできるようにするために、PHP は実際にこの入力データをグローバル変数として扱います。

例:

コードをコピーします コードは次のとおりです:

<入力タイプ="送信">


これにより、テキストボックスと送信ボタンが表示されます。ユーザーが送信ボタンをクリックすると、「test.php」がユーザーの入力を処理します。「test.php」が実行されると、ユーザーがテキスト ボックスに入力したデータが「$hello」に含まれます。ここから、攻撃者が自分の希望に応じて任意のグローバル変数を作成できることがわかります。攻撃者がフォーム入力を通じて「test.php」を呼び出すのではなく、ブラウザのアドレスバーに http://server/test.php?hello=hi&setup=no を直接入力すると、「$hello」だけでなく、 「$setup」も作成されます。
次のユーザー認証コードは、PHP のグローバル変数によって引き起こされるセキュリティ問題を明らかにします: PHPコード


コードをコピーします

コードは次のとおりです: if ($pass == "こんにちは")
$認証 = 1; ...
if ($auth == 1)
「重要な情報」をエコーし​​ます
?>



上記のコードは、最初にユーザーのパスワードが「hello」であるかどうかを確認し、一致する場合は、「$auth」を「1」に設定します。これは、認証が成功したことを意味します。その後、「$suth」が「1」の場合、いくつかの重要な情報が表示されます。

このコードは、値が設定されていない場合は「$auth」が空であると想定していますが、攻撃者は「http://server/test.php?auth=1」のようなメソッドを通じて、任意のグローバル変数を作成し、値を割り当てることができます。このコードを完全に騙して、自分が認証されていると信じ込ませることができます。

したがって、PHP プログラムのセキュリティを向上させるために、明確に定義されていない変数は信頼できません。プログラム内に多くの変数がある場合、これは非常に困難な作業になる可能性があります。

一般的な保護方法は、配列 HTTP_GET[] または POST_VARS[] 内の変数をチェックすることです。これは送信方法 (GET または POST) に応じて異なります。 PHP が「track_vars」オプションをオンにして構成されている場合 (これがデフォルトです)、ユーザーが送信した変数はグローバル変数と上記の配列で使用できます。

ただし、PHP にはユーザー入力の処理に使用される 4 つの異なる配列変数があることに言及する価値があります。 HTTP_GET_VARS 配列は GET モードで送信された変数の処理に使用され、HTTP_POST_VARS 配列は POST モードで送信された変数の処理に使用され、HTTP_COOKIE_VARS 配列は Cookie ヘッダーとして送信された変数の処理に使用され、HTTP_POST_FILES 配列 (比較的新しい PHP によって提供される) に使用されます。 )、これはユーザーが変数を送信するための完全にオプションの方法です。ユーザーリクエストは変数をこれら 4 つの配列に簡単に保存できるため、安全な PHP プログラムはこれら 4 つの配列をチェックする必要があります。

リモートファイル経由で攻撃するには?

PHP は、プログラマーが特定の関数を簡単に実装できるようにするための多数の関数を提供する機能豊富な言語です。しかし、セキュリティの観点から見ると、機能が多ければ多いほど、安全に保つことが難しくなり、リモート ファイルはこの問題の好例です:

コードをコピーします


コードは次のとおりです:

if (!($fd = fopen("$filename", "r")) echo("ファイルを開けませんでした: $filename<BR>n"); ?>

上記のスクリプトは、ファイル「$filename」を開こうとしますが、失敗するとエラー メッセージが表示されます。明らかに、「$filename」を指定できれば、このスクリプトを使用してシステム上の任意のファイルを参照できます。ただし、このスクリプトのあまり明らかではない機能は、他の WEB サイトまたは FTP サイトからファイルを読み取ることができることです。実際、PHP のファイル処理関数のほとんどは、リモート ファイルを透過的に処理します。

例:
「$filename」が「http://target/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir」と指定されている場合

上記のコードは、実際にはホスト ターゲットの Unicode 脆弱性を悪用して dir コマンドを実行します。これにより、リモート ファイルの include()、require()、include_once()、require_once() のサポートがコンテキストでより興味深いものになります。これらの関数の主な機能は、指定されたファイルの内容を組み込み、PHP コードに従って解釈することです。これらは主にライブラリ ファイルで使用されます。

例:

コードをコピーします コードは次のとおりです:

include($libdir . "/messages.php"); ?>

上記の例では、「$libdir」は通常、コードの実行前に設定されているパスです。攻撃者が「$libdir」の設定を阻止できれば、このパスを変更できます。しかし、攻撃者は指定したパスにあるファイル language.php にしかアクセスできないため、何もできません (Perl の「Poisonnull バイト」攻撃は PHP には影響しません)。しかし、リモート ファイルのサポートにより、攻撃者は何でもできるようになります。たとえば、攻撃者は次の内容を含むファイル language.php をサーバーに配置する可能性があります:


コードをコピーします コードは次のとおりです:
パススルー("/bin/ls /etc"); ?>


次に、「$libdir」を「http:///」に設定します。これにより、ターゲット ホスト上で上記の攻撃コードを実行できるようになり、「/etc」ディレクトリの内容が顧客のブラウザに返されます。結果的には真ん中。

攻撃コードは、それが配置されているサーバー (つまり、evilhost) 上では独自の PHP プログラムを実行しないことに注意してください。それ以外の場合、攻撃コードは、ターゲット サーバー上で実行されるのではなく、配置されているサーバーを攻撃します。 。

ファイルアップロード経由で攻撃するには?

PHP は RFC 1867 に基づいてファイルのアップロードを自動的にサポートします。次の例を見てみましょう:


コードをコピーします コードは次のとおりです:
<入力タイプ="送信">



上記のコードにより、ユーザーはローカル マシンからファイルを選択でき、[送信] をクリックすると、ファイルがサーバーにアップロードされます。これは明らかに便利な機能ですが、PHP の応答方法により、この機能は安全ではなくなります。 PHP がそのようなリクエストを初めて受信すると、呼び出された PHP コードの解析を開始する前でも、まずリモート ユーザーからファイルを受け入れ、ファイルの長さが「$MAX_FILE_SIZE 変数」で定義された値を超えているかどうかを確認します。テスト用に、ファイルはローカルの一時ディレクトリに保存されます。
したがって、攻撃者は PHP を実行しているホストに任意のファイルを送信することができ、PHP プログラムがファイルのアップロードを受け入れるかどうかを決定する前に、ファイルはすでにサーバーに保存されています。

ファイルのアップロードを処理する PHP プログラムを考えてみましょう。ファイルは受信され、サーバーに保存されます (場所は構成ファイルで指定されており、通常は /tmp)。拡張子は通常、「」のようなランダムです。 phpxXuoXG」フォーム。 PHP プログラムはファイルを処理するためにファイルの情報をアップロードする必要があります。これには 2 つの方法があります。1 つは PHP3 ですでに使用されており、もう 1 つは以前の方法に関するセキュリティ アドバイザリを作成した後に導入されました。
ほとんどの PHP プログラムは、アップロードされたファイルを処理するために依然として古い方法を使用しています。 PHP は、上記の例のように、アップロードされたファイルを記述する 4 つのグローバル変数を設定します。


コードをコピーします

コードは次のとおりです:

$hello = ローカルマシン上のファイル名 (例: "/tmp/phpxXuoXG") $hello_size = ファイルのバイト単位のサイズ (例: 1024) $hello_name = リモート システム上のファイルの元の名前 (例:"c:\temp\hello.txt") $hello_type = アップロードされたファイルの MIME タイプ (例: "text/plain")

その後、PHPプログラムは「$hello」に従って指定されたファイルの処理を開始します。問題は、「$hello」が必ずしも PHP によって設定される変数ではなく、リモート ユーザーであれば誰でも指定できることです。以下を使用すると:

http://vulnhost/vuln.php?hello=/etc/passwd&hello_size=10240&hello_type=text/plain&hello_name=hello.txt

これにより、次の PHP グローバル変数が生成されます (もちろん POST メソッドも (Cookie も) 可能です):

コードをコピーします コードは次のとおりです:

$hello = "/etc/passwd"
$hello_size = 10240
$hello_type = "テキスト/プレーン"
$hello_name = "hello.txt"

上記のフォームデータは、PHP プログラムが期待する変数を満たしていますが、現時点では、PHP プログラムはアップローダーのローカルマシン上にあるはずのアップロードされたファイルを処理せず、サーバー上で "/etc/passwd" を処理します (通常はコンテンツの公開につながります) ファイル。この攻撃を使用すると、機密ファイルの内容が暴露される可能性があります。

新しいバージョンの PHP は、アップロードされたファイルを判断するために HTTP_POST_FILES[] を使用し、この問題を解決するための多くの関数も提供します。たとえば、ファイルが実際にアップロードされたかどうかを判断するために使用される関数があります。しかし実際には、依然として古い方法を使用している PHP プログラムが多数あるはずなので、それらもこの攻撃に対して脆弱です。

ファイル アップロード攻撃手法のバリエーションとして、次のコードを見てみましょう:

コードをコピーします コードは次のとおりです:

if (file_exists($theme)) // ファイルがローカル システムに存在することを確認します (リモート ファイルではありません)
include("$テーマ"); ?>

攻撃者が「$theme」を制御できる場合、「$theme」を使用してリモート システム上の任意のファイルを読み取ることができることは明らかです。攻撃者の最終的な目標は、リモート サーバー上で任意の命令を実行することですが、リモート ファイルを使用できないため、リモート サーバー上に PHP ファイルを作成する必要があります。これは最初は不可能に思えるかもしれませんが、攻撃者が最初に PHP コードを含むファイルをローカル マシン上に作成し、次に "theme" という名前のファイル フィールドを含むフォームを作成し、最後にこのフォームを使用すると、これが行われます。作成した PHP コードを含むファイルをファイルアップロードを通じて上記のコードに送信すると、PHP は攻撃者が送信したファイルを保存し、file_exists() 関数を攻撃者が送信したファイルに設定します。チェックに合格し、攻撃者のコードが実行されます。

任意の命令を実行できるようになった攻撃者は、明らかに権限を昇格したり、結果を拡張したりすることを望んでいますが、そのためにはサーバー上で利用できないいくつかのツールセットが必要となり、ファイルのアップロードが再び攻撃者を助けます。攻撃者は、ファイル アップロード機能を使用してツールをアップロードし、サーバーに保存してからコマンドを実行し、chmod() を使用してファイルのアクセス許可を変更し、それを実行する可能性があります。たとえば、攻撃者はファイアウォールまたは IDS をバイパスして、ローカルの root 攻撃プログラムをアップロードして実行し、root 権限を取得する可能性があります。

ライブラリファイルを介して攻撃するにはどうすればよいですか?

前に説明したように、include() と require() は主にコード ベースをサポートするためのものです。これは、通常、この独立したファイルがコード ベースであり、必要に応じて関数を使用するためです。このコード ライブラリを現在のファイルに含める必要があるだけです。

当初、PHP プログラムを開発してリリースするとき、コード ベースとメインのプログラム コードを区別するために、通常はコード ベース ファイルに「.inc」拡張子を設定していましたが、すぐにこれが間違いであることがわかりました。このように、PHP インタープリターによってファイルを PHP コードに正しく解析できません。このようなファイルをサーバー上で直接リクエストすると、そのファイルのソースコードが取得されます。これは、PHP が Apache モジュールとして使用される場合、PHP インタープリターがファイルの拡張子に基づいて PHP に解析するかどうかを決定するためです。コードの。拡張子はサイト管理者によって指定されます。通常は「.php」、「.php3」、「.php4」です。重要な構成データが適切な拡張子なしで PHP ファイルに含まれている場合、リモート攻撃者がこの情報を簡単に入手できます。

最も簡単な解決策は、各ファイルに PHP ファイル拡張子を指定することです。これにより、ソース コードの漏洩を十分に防ぐことができますが、攻撃者がこのファイルを要求することにより、コンテキスト内で実行されるはずのコードを使用する可能性もあります。独立して実行されるため、前述したすべての攻撃につながる可能性があります。

これが明白な例です:


コードをコピーします コードは次のとおりです:

main.php 内:
$libDir = "/libdir"; $langDir = "$libdir/言語"; ...
include("$libdir/load language.php":
?>

libdir/load language.php:

...

include("$langDir/$userLang"); ?>



「libdir/load language.php」は、「main.php」から呼び出される場合には非常に安全ですが、「libdir/load language」には「.php」拡張子が付いているため、リモート攻撃者がこのファイルを直接リクエストし、任意の値を指定することができます。 「$langDir」と「$userLang」の場合。

セッションファイルを介して攻撃するには?

PHP 4 以降のバージョンはセッションのサポートを提供します。セッションの主な機能は、PHP プログラムのページ間のステータス情報を保存することです。たとえば、ユーザーが Web サイトにログインすると、ログインしたという事実と Web サイトにログインしたユーザーに関する情報がセッションに保存され、Web サイトを閲覧すると、すべての PHP コードがこの状態を取得できます。情報。

実際、セッションが開始されると(実際には最初のリクエストで自動的に開始するように構成ファイルで設定されます)、リモートブラウザが常にリクエストを送信する場合、ランダムな「セッションID」が生成されます。この「セッションID」を送信すると、 、セッションは永久に維持されます。これは、Cookie を使用するか、各ページでフォーム変数 (「セッション ID」を含む) を送信することで簡単に実現できます。 PHP プログラムはセッションを使用して特別な変数を登録でき、その値は各 PHP スクリプトの終了後にセッション ファイルに保存され、各 PHP スクリプトの開始前にも変数にロードされます。簡単な例を次に示します:

コードをコピーします

コードは次のとおりです: session_destroy(); // 現在セッション内のデータをすべて削除します
$session_auth = "ショーン"; session_register("session_auth"); // $session_auth をセッション変数として登録します
?>



PHP の新しいバージョンでは、「$session_auth」の値が自動的に「shaun」に設定され、変更された場合、将来のスクリプトは自動的に変更された値を受け入れるようになります。これはステートレス Web ツールにとって非常に良いことですが、私たちもそうする必要があります。注意深い。
明らかな疑問は、変数がセッションから取得されたものであることを確認することです。たとえば、上記のコードの場合、後続のスクリプトは次のようになります。

コードをコピーします


コードは次のとおりです:

if (!emptyempty($session_auth)) // ここでサイトへのアクセスを許可します
?>

上記のコードは、「$session_auth」に値が割り当てられている場合、その値はユーザー入力ではなくセッションから割り当てられていると想定しています。攻撃者がフォーム入力を通じて値を割り当てた場合、攻撃者はサイトにアクセスできるようになります。攻撃者は、この攻撃方法を使用する前に変数をセッションに登録する必要があることに注意してください。変数がセッションに配置されると、フォーム入力はすべて上書きされます。

セッション データは通常、ファイルに保存されます (場所は設定可能で、通常は「/tmp」)。このファイルには、変数名、変数タイプ、および変数が含まれます。値やその他のデータ。マルチホスト システムでは、ファイルが Web サーバーを実行しているユーザー (通常は誰も) として保存されるため、悪意のあるサイト所有者がセッション ファイルを作成して他のサイトにアクセスしたり、セッション ファイルの機密情報を検査したりする可能性があります。 。

セッション メカニズムは、攻撃者が自分の入力をリモート システム上のファイルに保存するための別の利便性も提供します。上記の例では、攻撃者は PHP コードを含むファイルをリモート システムに配置する必要がありますが、ファイル アップロードを使用してこれを実行できない場合は、通常、セッションを使用して自分の希望に従って変数に値を割り当て、その後、その値を推測します。セッション ファイルの場所を指定すると、ファイル名が「php」であることがわかっているため、ディレクトリを推測するだけで済み、通常はディレクトリは「/tmp」になります。

さらに、攻撃者は任意に「セッション ID」(「hello」など)を指定し、この「セッション ID」を使用してセッション ファイル(「/tmp/sess_hello」など)を作成することもできますが、「セッション ID」 id」には文字と数字の組み合わせのみを使用できます。

データタイプごとに攻撃するには?

PHP には緩いデータ型があり、変数の型は変数が配置されているコンテキストによって異なります。例: "$hello" は値 "" を持つ文字列変数として開始されますが、評価中に整数変数 "0" になり、予期しない結果が生じる場合があります。 "$hello" の値が "000" と "0" の間で異なる場合、empty() によって返される結果は true ではありません。

PHP の配列は連想配列です。つまり、配列のインデックスは文字列型です。これは、「$hello["000"]」と「$hello[0]」も異なることを意味します。

プログラムを開発する際には、上記の問題を注意深く考慮する必要があります。たとえば、ある場所で変数が「0」であるかどうかをテストし、別の場所でそれを検証するために empty() を使用するべきではありません。

エラーが発生しやすい機能を介して攻撃するにはどうすればよいですか?以下は、エラーが発生しやすい関数の詳細なリストです:

コードをコピーします コードは次のとおりです:

1.
2. require(): 指定されたファイルの内容を読み取り、PHP コードとして解釈します
3. include(): 上記と同じ
4. eval(): 指定された文字列を PHP コードとして実行します
5. preg_replace(): 「/e」スイッチと一緒に使用すると、置換文字列は PHP コードとして解釈されます
6.
7. <コマンド実行>
8. exec(): 指定されたコマンドを実行し、実行結果の最後の行を返します
9. passthru(): 指定されたコマンドを実行し、すべての結果を顧客のブラウザに返します
10. ``: 指定されたコマンドを実行し、すべての結果を配列に返します
11. system(): passthru() と同じですが、バイナリデータを処理しません
12. Popen(): 指定されたコマンドを実行し、入力または出力を PHP ファイル記述子に接続します
13.
14. <ファイル漏洩>
15. fopen(): ファイルを開き、PHP ファイル記述子に対応します
16. readfile(): ファイルの内容を読み取り、クライアントのブラウザに出力します
17. file(): ファイルの内容全体を配列に読み取ります

PHP のセキュリティを強化するにはどうすればよいですか?

上記で紹介した攻撃はすべて、デフォルトでインストールされている PHP4 に対して適切に実装できますが、PHP の構成は非常に柔軟であり、いくつかの PHP オプションを構成することで、これらの攻撃の一部に対抗することが完全に可能です。以下では、実装の難易度に応じていくつかの構成を分類します。

コードをコピーします コードは次のとおりです:

※難易度低め
**低から中程度の難易度
***中~高難易度
****高難易度

PHP が提供するすべてのオプションを使用すると、サードパーティのコードを使用する場合でも、PHP の機能の多くが使用できなくなるため、PHP は非常に安全になります。

****「register_globals」を「off」に設定します

このオプションは、PHP によるユーザー入力のグローバル変数の作成を無効にします。つまり、ユーザーがフォーム変数「hello」を送信した場合、PHP は「$hello」を作成せず、「HTTP_GET/POST_VARS['hello']」のみを作成します。 」。これは PHP では非常に重要なオプションです。このオプションをオフにすると、プログラミングに大きな不便が生じます。

*** 「セーフモード」を「オン」に設定します

このオプションを開くと、次の制限が追加されます:

1. 実行できるコマンドを制限する
2. 使用できる機能を制限する
3. スクリプトの所有権とターゲットファイルの所有権に基づくファイルアクセス制限
4. ファイルアップロード機能を無効にする

これは ISP にとって「素晴らしい」オプションであり、PHP のセキュリティも大幅に向上します。

** 「open_basedir」を設定します

このオプションは、指定されたディレクトリ外でのファイル操作を禁止し、ローカル ファイルまたはリモート ファイルに対する include() による攻撃を効果的に排除できますが、ファイル アップロードやセッション ファイルに対する攻撃には依然として注意する必要があります。

** 「display_errors」を「off」に設定し、「log_errors」を「on」に設定します

このオプションは、エラー メッセージが Web ページに表示されないようにし、代わりにログ ファイルに記録します。これにより、攻撃者がターゲット スクリプト内の関数を検出するのを効果的に阻止できます。

* 「allow_url_fopen」を「off」に設定します

このオプションはリモートファイル機能を無効にすることができます。

コードをコピーします コードは次のとおりです:

//ここにallow_url_fopen 注、jncブログで見たので使えます

include('\myiptest.php'); ?>

include('//myiptest.php'); ?>


予備に来ますか?


phpネットワークプログラミングテクノロジーとサンプルコード

あなたのメールアドレスに送信されました。まだ受け取っていない場合は、私のメールアドレス qsf.zzia@qq.com に手紙を送って再度リクエストしてください。


代表的なモジュールのソースコードのコピーと、PHP ネットワークプログラミングの例を送っていただけます

www.w3school.com.cn/php/
この Web サイトはよくこの Web サイトで関連情報を検索します。

お役に立てば幸いです。


http://www.bkjia.com/PHPjc/859710.html

tru​​ehttp://www.bkjia.com/PHPjc/859710.html技術記事 PHP プログラミングの一般的な脆弱性とコード例 PHP プログラミングの脆弱性の例は、PHP の普及に伴い、常に PHP のトラブルを探しており、PHP プログラムを通じて漏洩しています...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。