ファイルアップロードの脆弱性 - アップロード射撃場 1-2 パスのメモ (フロントエンド検証とバックエンド検証を区別する方法)

ファイルアップロードの脆弱性 - 射撃場 1-2 パスメモのアップロード (フロントエンド検証とバックエンド検証を区別する)

序文

Upload はファイル アップロード専用の射撃場です。セットアップは非常に簡単です。使用するには、関連するソース コード ファイルを Apache Web サイトのディレクトリに配置するか、github にアクセスして、ワンクリックで緑化パッケージをダウンロードするだけです。インストール。リンクは次のとおりです。

[リリース · c0ny1/upload-labs (github.com) ]

画像-20230822214734727

ダウンロード後は、指示に従ってインストールしてください。射撃場をインストールするときは、仮想マシンにインストールするのが最適です。ここではあまり分析しません。わからない場合は、プライベートでチャットしてください。 。

画像-20230822214826621

アップロード範囲は、ファイル アップロードの脆弱性を再現する練習に役立ち、脆弱性の原因をよりよく学習するのに役立ちます。このツールには合計 20 のレベルがあります。最初のレベル (フロントエンド検証) を除き、他の 19 レベルはすべてバックエンド検証について。

ここに画像の説明を挿入します

アップロード射撃場の難易度も徐々に上がり、13レベルに到達するのが分水嶺となります。

レベルに挑戦し始める前に、まず攻撃の成功とは何かを理解しましょう。

  1. Webshel​​l はサーバーに正常にアップロードされる必要があります
  2. サーバー内のWebシェルのパスを知るには
  3. アップロードされたWebシェルは正常に解析できます

これら 3 つの条件が満たされた場合にのみ、攻撃が成功したと見なされます。

第 1 レベルのアップロード (JS 検証)

画像-20230822222434463

JavaScript の簡単な紹介:
JavaScript はフロントエンドでよく使用される言語です。JavaScript で書かれたコードは通常フロントエンドに属します。ただし、サーバー環境として node.js を使用する場合、JavaScript はバックエンドとしても使用できます。言語。

判断のアイデア

Webシェルをアップロードするとき、Webサイトがアップロードされたファイルを検証するためにどのような方法を使用しているかはわかりません。そのため、適切な攻撃方法を見つけるために、ソースコードを分析したり、トラフィックをキャプチャしたりすることによって検証方法を分析する必要があります。 。

1つ目の方法: ソースコードを分析する
            <h3>任务</h3>
            <p>上传一个<code>webshell</code>到服务器。</p>
        </li>
        <li>
            <h3>上传区</h3>
            <form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">
                <p>请选择要上传的图片:<p>
                <input class="input_file" type="file" name="upload_file"/>
                <input class="button" type="submit" name="submit" value="上传"/>
            </form>


<script type="text/javascript">
    function checkFile() {
      
      
        var file = document.getElementsByName('upload_file')[0].value;
        if (file == null || file == "") {
      
      
            alert("请选择要上传的文件!");
            return false;
        }
        //定义允许上传的文件类型
        var allow_ext = ".jpg|.png|.gif";
        //提取上传文件的类型
        var ext_name = file.substring(file.lastIndexOf("."));
        //判断上传文件类型是否允许上传
        if (allow_ext.indexOf(ext_name) == -1) {
      
      
            var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
            alert(errMsg);
            return false;
        }
    }
</script>

上記のソース コードはこの Web サイトから見つかったもので、より重要なフォームと js スクリプトが含まれています。

フォーム form には 3 つの属性があります。

  • enctype 属性: フォーム データを送信するときに使用されるエンコード タイプを指定するためにフォームで使用されます。
    • その値は multipart/form-data です。HTTP リクエストのデータ形式であり、リクエスト内で非 ASCII 文字を含むバイナリ データまたはテキスト データを送信するために使用されます。ファイルのアップロードやフォームの送信によく使用されます
  • Method 属性: このフォームでデータを受信する方法を示します
    • 値は post です。データを受信するには post メソッドを使用します。
  • onsubmit 属性: フォームの送信時に実行される JavaScript コードを指定するために使用されます。
    • その値は return checkFile(): で、フォームが送信される前に実行される JavaScript 関数を指定するために使用されます。checkFile()

入力タグの解析:

  • <input class=”input_file” type=”file” name=”upload_file”/>
    • このコードを使用して、ユーザーがローカル コンピューター上のファイルを選択してサーバーにアップロードできるようにするファイル アップロード入力フィールドを作成できます。その表現名の値は、upload_file です。
  • <input class=”button” type=”submit” name=”submit” value=”上传”/>
    • 送信ボタンを作成し、ユーザー インターフェイスに「アップロード」テキストを表示します。ユーザーがこのボタンをクリックすると、フォーム送信アクションがトリガーされ、フォーム データがサーバーに送信されます。

js ソース コードから見つかった関数checkFile()は、フロントエンド検証に使用されるカスタム関数です。

  • document.getElementsByName()name="upload_file"属性を持つ要素を取得し、[0]インデックスを通じて最初に一致する要素を取得し、属性を使用して.valueその値を取得するメソッド。ファイルがアップロードされていないか、空のファイルがアップロードされている場合は、ファイルを選択するように求められます。アップロードする。

js ソースコードの後半では次のようになります。

  • まず、アップロードされるファイルの拡張子には制限があり、これら 3 つの拡張子を持つファイルのみをアップロードできます。
  • このメソッドを呼び出すとfile.lastIndexOf(".")、ファイル名の最後のドット (.) のインデックスを取得できます。
  • その後、file.substring()メソッドを呼び出すことで、インデックス位置から始まる文字列をインターセプトし、ファイル名の拡張子を取得して判断することができます。アップロードされたファイルが要件を満たしていない場合、ユーザーは正しい形式でファイルをアップロードするように求められます。 。

このコードの解析により、それがフロントエンド検証であることが判明した場合、問題は単純で、いわゆるフロントエンド検証は張り子の虎です。

jsコードの関数解析

document.getElementsByName()

  • これは JavaScript の DOM メソッドであり、name要素の属性に基づいてドキュメント内の一致するすべての要素のコレクションを取得するために使用されます。

  • このメソッドは、取得する要素の属性の値を示す文字列パラメータを受け取り、指定された属性に一致するnameすべての要素を含む配列のようなオブジェクトを返します。name

对象.lastIndexOf()

  • これは、文字列内で指定された文字または部分文字列が最後に出現するインデックス位置を取得するために使用される JavaScript 文字列メソッドです。

对象.substring()

  • これは、文字列内の指定されたインデックス位置間の部分文字列を取得するために使用される JavaScript 文字列メソッドです。
2 番目の方法: げっぷスイート キャプチャ パケット

まず、Burp を開いて、アップロードされたパッケージを取得します。

画像-20230822233118103

このパッケージを分析のためにリピーターに入れます

画像-20230822233247084

ここで、123.jpg という名前のファイルをアップロードしたことがわかります。

Content-Type: image/jpeg は、画像ファイルを送信することを意味します

ここでは、アップロードしたファイルのサフィックス名を変更します

  • フロントエンド検証であれば拡張子を変更しても検証済みなので正常に送信できます。

画像-20230822234556009

ファイルのサフィックスを asp に変更すると、バックエンド サーバーに正常に送信されました。これは、フロントエンド検証のみを使用していることも証明しています。

burp suite を使用してパケットをキャプチャする、より簡単で効果的な方法があります。burp suite を直接有効にしてリクエスト パケットをインターセプトし、制限されたファイルをアップロードします。burp suite がパケットをキャプチャせず、Web ページにプロンプ​​トが表示される場合は、それ以外の場合はバックエンド検証に属します。

攻撃のアイデア

フロントエンド検証の最大の欠点は、クライアントによって改ざんされる可能性があることです。このファイルはローカル コンピュータにあります。必要に応じて変更できます。バックエンド サーバーの方が面倒です。方法を詳しく紹介します。」後で正常にアップロードできるようにします。

前のセクションで確認した攻撃方法:

1. ソース コードを直接変更します。

画像-20230822235836598

ブラウザーに付属のチェック ツールを使用して、フロントエンド検証コードを見つけて直接削除します。

2. bp パケット キャプチャ ツールを使用します。

画像-20230823000308923

前回の検証に合格しており、この時点での変更はアップロードされたファイルには影響しないため、パケット キャプチャ ツールでファイル サフィックスを直接変更します。

3. br を使用して Web ページの js 機能を無効にします

画像-20230823000846522

画像-20230823001103937

4. ブラウザ(Firefox)付属のjs無効化機能を利用する

1. Firefox ブラウザの URL インターフェイスに「about:config」と入力して、詳細設定インターフェイスに入ります。

画像-20230823001327765

javascript.enabled を検索します。

画像-20230823001430901

javascript.enabled を true から false に変更します。

画像-20230823001503534

br パケット キャプチャを無効にする効果も得られますが、ブラウザの無効化方法を使用することはお勧めできません。すべての js が無効になり、一部の通常の js も使用できなくなります。

最後に、単純な Web シェル スクリプトをアップロードして、成功したかどうかをテストします。

画像-20230823001929745

ウェブサイトの許可が正常に取得されました。


第 2 レベルのアップロード (MIME 検証)

MIMEとは何ですか?

MIME (MultiPurpose Internet Mail Extensions) は、ファイルの種類を識別するための標準です。これは、インターネット経由でメールやその他のデータを送信する一般的な方法です。

MIME タイプは、スラッシュ (/) で区切られたメイン タイプとサブタイプの 2 つの部分で構成されます。メイン タイプはファイルの広範なカテゴリを表し、サブタイプは特定のファイル タイプを表します。例は次のとおりです。

  • テキストファイル:text/plain
  • HTMLファイル:text/html
  • JPEG画像ファイル:image/jpeg
  • PNG画像ファイル:image/png
  • JSONデータファイル:application/json
  • PDF ドキュメント:application/pdf

MIME タイプは主に、HTTP プロトコルで送信されるデータのタイプを指定するために使用され、電子メール、ファイル アップロードなどの他のアプリケーションでも使用されます。正しい MIME タイプを使用することで、サーバーとクライアントは転送されるデータのタイプを理解し、それに応じて解析して処理できます。

MIME タイプを使用して、データの文字エンコーディング、言語、およびその他の関連情報を指定することもできます。これらの情報は、データの正しい表示と処理を保証するために使用されます。

HTTP プロトコルでは、送受信するデータの種類を指定するために、要求メッセージと応答メッセージのContent-Typeヘッダー フィールドでMIME タイプがよく使用されます。

ソースコード分析
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    
    
    if (file_exists(UPLOAD_PATH)) {
    
    
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
    
    
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
    
    
                $is_upload = true;
            } else {
    
    
                $msg = '上传出错!';
            }
        } else {
    
    
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
    
    
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}

分析の結果、これはアップロードされたファイルが特定の条件を満たしているかどうかを確認するために使用されるバックエンド検証の一例であることがわかりました。

  • $is_upload: ファイルが正常にアップロードされたかどうかを示すために使用され、初期値は false です。
  • $msg: 検証プロセス中にプロンプ​​ト情報を保存するために使用され、初期値は null です。

検証プロセスに入る条件は、ユーザーがフォームの「送信」ボタンをクリックすること、つまり $_POST['submit'] が存在することです。

検証ロジックは次のとおりです。

  1. まず、指定したアップロードパス(UPLOAD_PATH)が存在するか確認してください。存在しない場合は、$msg をエラー メッセージを含む文字列に設定します。
  2. アップロード パスが存在する場合は、検証を続行します。
  3. アップロードされたファイルのタイプが要件を満たしていることを確認してください。このソース コードでは、アップロードするファイルの種類が「image/jpeg」、「image/png」、または「image/gif」のいずれかである必要があります。
  4. アップロードされたファイルの種類が要件を満たしている場合は、一時ファイル ($_FILES['upload_file']['tmp_name']) を指定されたアップロード パスに移動します。ファイルが正常に移動された場合は、$is_upload を true に設定します。
  5. ファイルの移動が失敗した場合は、$msg にエラー メッセージを含む文字列を設定します。
  6. アップロードされたファイルの種類が要件を満たしていない場合は、ファイルの種類が間違っていることを示すメッセージが表示されます。再度アップロードしてください。
攻撃のアイデア

まず、ファイルを任意にアップロードし、burpsuite を使用してパケットをキャプチャし、使用する検証方法を決定します。

ここに画像の説明を挿入します
Webシェルをアップロードしたところ、Burpsuiteがリクエストパケットをインターセプトし、Webページではエラーが報告されなかったことから、バックエンド検証方式を使用していると判断しました。
ここに画像の説明を挿入します
直接リリースした後、Web ページでエラーが報告され、ファイルの種類が間違っていることがわかりました。

ここに画像の説明を挿入します
リクエスト パッケージを分析し、リクエスト本文の Content-Type フィールドを見つけます。その値は application/octet-steram で、特定のメディア タイプを持たないバイナリ データを示します。多くの場合、他のメディア タイプで明確に定義されていない、または不明なバイナリ データを転送するために使用されます。平たく言えば、送信者 (ローカル) はアップロードされたファイルの特定のタイプを判断できないか、意図的にそれを汎用のバイナリ データ タイプとして扱います。

ここに画像の説明を挿入します
リクエスト本文に Content-Type が表示されている場合、それがバックエンドによって検証されたファイルの MIME タイプであるかどうかを最初に疑うことができます。この値をバックエンドがアップロードを許可するファイルの名前に変更すると、アップロードできるかどうかがわかります。完成させるためには、考えるよりも行動したほうが良いと考え、私たちは挑戦を始めました。
ここに画像の説明を挿入します
Content-Type の値を image/png に変更した後、ファイルのアップロードが成功したことがわかりました。これで、バックエンドが MIME 検証を使用していることを確認できます。あとは、Web シェルを解析して、それが正常に渡されたかどうかを確認するだけです。

ここに画像の説明を挿入します
phpinfo(); 関数は正常に解析され、テストに正常に合格しました。

要約:

フロントエンド検証とバックエンド検証:

  1. フロントエンド検証:
    フロントエンド検証は、ユーザーが入力したデータが特定のルールと形式に準拠していることを確認するためにクライアント (ブラウザーなど) で実行される検証です。フロントエンド検証は通常、JavaScript などのスクリプト言語を使用して実装されます。その主な目的は、ユーザーがフォームを送信したり他のアクションを実行したりする前に、入力エラーを見つけて修正できるように、即時のユーザー フィードバックを提供することです。フロントエンド検証はユーザー エクスペリエンスを向上させ、不必要なネットワーク リクエストとサーバーの負担を軽減しますが、クライアント側の検証はバイパスまたは改ざんされる可能性があるため、完全に信頼できるわけではありません。

  2. バックエンド検証:
    バックエンド検証は、クライアントから送信されたデータが合法的、安全、信頼できるかどうかを検証するためにサーバー側で実行される検証です。バックエンド検証は通常、プログラミング言語とフレームワークを使用してサーバー側で実装されます。その主な目的は、受信したデータがビジネス ロジックとセキュリティ要件に準拠していることを確認し、潜在的な脅威や攻撃からサーバーとアプリケーションを保護することです。バックエンド検証は、サーバーがより詳細に制御でき、より厳格で包括的な検証を実行できるため、フロントエンド検証よりも信頼性が高くなります。

2 つの違い:

  • 基本的な立場: フロントエンドの検証はクライアント側で行われ、バックエンドの検証はサーバー側で行われます。
  • 目的: フロントエンド検証は主にユーザーに即時フィードバックと検証を提供するために使用され、バックエンド検証は主にデータの合法性、セキュリティ、信頼性を確保するために使用されます。
  • セキュリティ: クライアント側の検証は改ざんまたはバイパスされる可能性があるため、バックエンド検証の信頼性が高くなります。そのため、データのセキュリティを確保するにはバックエンド検証がより重要です。
  • フォールト トレランス: フロントエンド検証により、より迅速なユーザー フィードバックが提供されますが、データの一貫性と整合性を確保するためにバックエンド検証も必要になります。
  • 実行順序: フロントエンド検証は通常、ユーザーがデータを送信する前に実行され、バックエンド検証はデータがサーバーによって受信された後に実行されます。
  • データ転送: フロントエンド検証は不要なネットワーク要求とサーバーの負担を軽減し、バックエンド検証はクライアントからの信頼できないデータをフィルタリングして処理できます。

最後に、フロントエンドとバックエンドの検証フローチャートを示します。
画像-20230824004345678


おすすめ

転載: blog.csdn.net/weixin_44369049/article/details/132463757