あなたのサイトではすべてをアップロードすることもできますか?

今年の夏、フランスのある「セキュリティ研究者」は、さまざまな「ひざに書かれた」ファイルに任意のファイルをアップロードするなど、前例のないほど多くの脆弱性を公開しました。 小さなフォーラム、ブログ、オンラインストアの作成者や管理者がどれほど無謀であることは驚くべきことです。 原則として、アバター、履歴書、顔文字、およびユーザーがサイトにアップロードできるその他のリソースがダウンロードされるディレクトリでは、PHPコードの実行が許可されます。 つまり、写真を装ってPHPスクリプトをロードすると、攻撃者がサーバー上で任意のコードを実行できるようになります。



もちろん、Apache権限でコードを実行することはサーバーを完全に制御することではありませんが、攻撃者が開く可能性を過小評価しないでください。サイトのすべてのスクリプトと構成ファイルにアクセスし、使用するデータベースにアクセスします。 彼はあなたに代わってスパムを送信したり、あなたからの違法なコンテンツをホストしたりすることができます。 多分、支払いシステムへの拘束力のパラメーターを見つけて、すべての注文を払い戻し、先月全体の収入を失ってしまうかもしれません。 残念ですよね?



彼はどのように成功しますか?



ダウンロードをまったくチェックしませんか?



臨床例:PHPマニュアルから行をコピーした

move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);





そして彼女は製品コードに残されていました。



だから、私は一般に、アップロードディレクトリだけでなく、どこにでもファイルをアップロードできます-ファイル名として../index.htmlを指定し、メインページを自分のページに置き換えることができます。 残念ですよね?



少なくともbasename()呼び出しを$_FILES["file"]["name"]



追加し$_FILES["file"]["name"]



。 PHPの最新バージョンでは、私の実験から判断すると、 $_FILES["file"]["name"]



はHTTPリクエストで渡されたファイル名から$_FILES["file"]["name"]



basenameのみを返します。 ただし、ここでは注意は不要です。



ファイルが写真かどうかを確認していますか?



ダウンロードしたファイルをアップロード/に保存する前に、 getimagesize()を呼び出して、写真がアップロードされていることを確認します。 「セキュリティ研究者」を喜ばせてくれるのは、PHPを使用すると、<?にないものを無視して、任意のファイルの任意の場所に実行可能コードを埋め込むことができるということです。 ?>。 愛する猫の写真を撮って、最後に<?php passthru($_GET['c']); ?>



ようなものを追加でき<?php passthru($_GET['c']); ?>



<?php passthru($_GET['c']); ?>



pwn.phpという名前で入力します。 次に、 getimagesize()は 、ヘッダーのみを分析するため、ファイルにJPEGイメージがあることを確認します。 私の「ポストスクリプト付き写真」はテストに合格します。



MIMEタイプをチェックしていますか?



getimagesize()によって返される「mime」フィールドを信頼できない理由は明らかです。これは、ファイルヘッダーに基づいて取得されます。 さらに、 $_FILES["file"]["type"]



信頼することはできません。HTTPリクエストのPHPスクリプトの前に "Content-Type:image / jpeg"を渡すことを妨げるものは何もありません。 それは当たり前のように見えますが、 人々は本当にそれに依存しています。 だからif(substr($_FILES["file"]["type"], 0, 6)=="image/") {/* */}



1つの自信のあるプロジェクトのチェックを見ました。 彼らは一回のチェックですべての可能なタイプの写真をカバーできたことをエレガントでcだと考えています! しかし、彼らからこの「ベストプラクティス」を借りないでください。



拡張機能を確認していますか?



別の自信のあるプロジェクトでは、私はちょうどチェックを見ました

if(substr($_FILES["file"]["name"], -3)=="jpg" || substr($_FILES["file"]["name"], -3)=="gif" || substr($_FILES["file"]["name"], -3)=="png") {/* */}





Apacheの機能は 、なじみのない拡張子を持つファイルに遭遇すると、これらの拡張子を「食い止め」、それらの前にあるなじみのある拡張子を探します。 したがって、pwn.php.omgifファイルをアップロードすると、テストに合格しますが、mime-typeもハンドラモジュールもomgif拡張に登録されていないため、ApacheにはPHPスクリプトが表示されます。



「悪い」拡張機能をチェックしていますか?



3番目の自信のあるプロジェクトでは、 if(strpos($_FILES["file"]["name"], ".php")===FALSE) {/* */}



-少なくともどこかで.php拡張子が一致した場合、ファイルは適切ではありません。 ただし、デフォルトでは、PHPインタープリターは.phtmlおよび.php3拡張子に対しても呼び出されることを忘れないでください。 一部のホスティング事業者は 、静的に埋め込むために他の拡張子 (場合によっては.html、.js、.jpgなど)にもそれを含めますある種のSEOコードのリソース、またはヒット統計の追跡。 (Googleが「PHPコードがJPEGファイルで実行されていることを確認するにはどうすればよいか」という質問を見つけた数を確認できます。)さらに、攻撃者が.htaccessダウンロードした場合、任意の拡張子のファイルでPHPコードを実行できます-この.htaccessファイル自体にも。 一般的に、用心してください。



拡張機能を正しくチェックしていますか?



ファイル名が.jpgで終わると確信していると仮定します(ドットが付いています!)PHPコードがその中で実行されないことを確認できますか? 前の段落を考える-最も可能性が高いが、保証はありません。 攻撃者(または不正な管理者)が/etc/mime.typesを何らかの形で破損したため、.jpg拡張子が未登録であることが判明し、Apacheはその前に拡張子を分析します。 chrootが原因で/etc/mime.typesが利用できなくなった可能性があります。 攻撃者(またはkrivorukyの管理者)が、そのような.htaccessをupload /ディレクトリにスローしたことがあります。これにより、すべてのファイルのPHPコードを連続して実行できます。



さらに、PHPの最近のバージョンまでは、「pwn.php \ 0.jpg」という名前のファイルをダウンロードできました。これはディスクに保存されると「pwn.php」になります。システムコールの場合、ファイル名の行は\ 0で終わるためです、およびPHP関数の場合、これは文字列で許可される通常の文字です。 この場合、拡張子をチェックしても何も保証されません。



そして何をすべきか?



彼らはstackoverflowの徹底的なチェックリストをコンパイルしようとしました。 つまり、a)ユーザーファイルが保存されているディレクトリでのPHPの実行を明示的に禁止します。 b)ユーザーファイルの名前を、ユーザーが制御していない名前に変更します。 c)可能であれば、GDを使用して画像を再保存し、ファイルの最後にある不要なメタデータと未承諾の投稿を削除します。



All Articles