ホームページ >バックエンド開発 >PHPチュートリアル >PHP プログラムの一般的な脆弱性を攻撃する方法 (パート 1) ページ 1/2_PHP チュートリアル

PHP プログラムの一般的な脆弱性を攻撃する方法 (パート 1) ページ 1/2_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:59:27790ブラウズ

この記事を翻訳した理由は、現在の CGI のセキュリティに関する記事はすべて Perl を例に挙げており、ASP、PHP、JSP のセキュリティについて具体的に紹介している記事が非常に少ないためです。 Shaun Clowes によるこの記事では、PHP のセキュリティ問題についてより包括的に説明しています。元の記事は http://www.securereality.com.au/studyinscarlet.txt にあります。

原文は比較的長く、記事の背景や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」も作成されます。

翻訳者注: これら 2 つのメソッドは、通常「POST」メソッドと「GET」メソッドと呼ばれるものです。
次のユーザー認証コードは、PHP のグローバル変数によって引き起こされるセキュリティ問題を明らかにします:

if ($pass == "hello")
$auth = 1;
...
if ($auth == 1; )
echo "some important information";
?>

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

表面的には正しいように見えますし、多くの人がそうしていますが、このコードは、値が設定されていないときに "$auth" が空であると想定するという誤りを犯しており、攻撃者は空であると考えています。 「http://server/test.php?auth=1」のようなメソッドを通じて、任意のグローバル変数と値を割り当てると、このコードを完全に欺き、認証されたと思わせることができます。

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

一般的な保護方法は、送信方法 (GET または POST) に応じて、配列 HTTP_GET[] または POST_VARS[] 内の変数をチェックすることです。 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
");
?>

上記のスクリプトは、ファイル "$filename" を開こうと試み、失敗するとエラー メッセージが表示されます。明らかに、「$filename」を指定できれば、このスクリプトを使用してシステム内の任意のファイルを参照できます。ただし、このスクリプトにはあまり目立たない機能があります。それは、他の Web またはファイルからアクセスできることです。実際、FTP サイトはファイルを読み取ります。PHP のファイル処理関数のほとんどはリモート ファイルに対して透過的です。例:
「$filename」が「http://target/scripts/..%c1. %1c」と指定されている場合。 ../winnt/system32/cmd.exe?/c+dir”
上記のコードは、実際にホスト ターゲットの Unicode 脆弱性を悪用して dir コマンドを実行します

これにより、リモート ファイル、require() の include() サポートが有効になります。 include_once() と require_once() は、コンテキストでより興味深いものになります。これらの関数の主な機能は、指定されたファイルの内容をインクルードし、主にライブラリ ファイルで使用される PHP コードに従って解釈することです。 php
include($libdir . "/messages.php");
?>

上記の例では、「$libdir」は通常、攻撃者が「$libdir」を実行する前に設定されているパスです。 " が設定されていない場合、このパスを変更できますが、攻撃者は指定したパス (「Perl の Poison null」) にあるファイル language.php にしかアクセスできないため、何もできません。byte" 攻撃は効果がありません。しかし、リモート ファイルのサポートにより、攻撃者はあらゆることを行うことができます。たとえば、攻撃者は、次の内容を含むファイル「langages.php」を配置できます。

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

次に、ターゲット ホストにログインできるように、"$libdir" を "http:///" に設定します。その結果、「/etc」ディレクトリの内容がクライアントのブラウザに返されます。

攻撃サーバー (つまり、evilhost) は PHP コードを実行できないことに注意してください。そうでない場合、特定の技術的な内容を知りたい場合、攻撃コードはターゲット サーバーではなく攻撃サーバーで実行されます。詳細については、http://www.securereality.com.au/sradv00006.txt を参照してください。

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





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

したがって、PHP プログラムがファイルのアップロードを受け入れるかどうかを決定する前に、攻撃者は PHP を実行しているホストに任意のファイルを送信することができます。

ここでは、ファイルのアップロードを使用してサーバー上で DOS 攻撃を実行する可能性については説明しません。

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

しかし、問題は依然として存在しており、ほとんどの PHP プログラムはアップロードされたファイルを処理するために依然として古い方法を使用していると断言できます。PHP は、上記の例のように、アップロードされたファイルを記述するために 4 つのグローバル変数を設定します:

$hello = ローカル マシン上のファイル名 (例: "/tmp/phpxXuoXG")
$hello_size = ファイルのバイト単位のサイズ (例: 1024)
$hello_name = リモート システム上のファイルの元の名前 (例: "c:emphello.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メソッドも Yes (cookie も)):

$hello = "/etc/passwd"
$hello_size = 10240
$hello_type = "text/plain"
$hello_name = "hello.txt"

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

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

ファイル アップロード攻撃手法の変種として、次のコードを見てみましょう:

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

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

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

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/317393.html技術記事この記事を翻訳した理由は、現在の CGI のセキュリティに関する記事はすべて Perl を例に挙げており、ASP、PHP、JSP のセキュリティについて具体的に紹介している記事が非常に少ないためです。 ShaunClowes によるこの記事...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。