Upload-Labs チャレンジの解説

環境構築

Upload-Labs の動作環境は以下の通りです。

  • OS: Windows, Linux
  • PHPバージョン: 5.2.17(他のバージョンでは一部のレベルがクリアできない可能性があります)
  • PHPモジュール: php_gd2, php_exif(特定のレベルで必要)
  • Apache: モジュール方式で接続

プロジェクトURL: https://github.com/c0ny1/upload-labs

phpstudyを使用して簡単にセットアップできます。ダウンロードしたファイルを適切なルートディレクトリに配置し、ブラウザからアクセスします。

解法

Pass-01

最初のレベルでは、フロントエンドのJavaScript検証が行われています。この検証はクライアントサイドで行われるため、簡単にバイパスできます。

方法1: ブラウザでJavaScriptを無効化し、直接PHP木馬をアップロードします。

方法2: Burp Suiteを使用してパケットをキャプチャし、拡張子を変更してアップロードします。

Pass-02

このレベルでは、Content-Typeヘッダーがチェックされています。Burp Suiteを使用してパケットをキャプチャし、Content-Typeをimage/jpegに変更してPHP木馬をアップロードします。

Pass-03

ブラックリストによるフィルタリングが行われています。.asp, .aspx, .php, .jspの拡張子は許可されていません。ただし、.phtml, .phps, .php5, .phtなどの拡張子は許可されます。Apacheの場合、.htaccessファイルもアップロードできます。

Apacheの設定ファイル(httpd.conf)に以下のように追加します:

AddType application/x-httpd-php .php .phtml .phps .php5 .pht

Pass-04

このレベルでもブラックリストによるフィルタリングが行われていますが、.htaccessは除外されています。そのため、.htaccessファイルをアップロードすることで、スクリプトの解析を可能にできます。

また、.php. (中間スペース) という形式の拡張子を使用することでもバイパス可能です。

Pass-05

このレベルでは、.htaccessがブラックリストに追加されています。そのため、.php. (中間スペース) という形式の拡張子を使用してバイパスします。

Pass-06

このレベルでは、大文字小文字の区別がありません。例えば、.pHPのような形式の拡張子を使用してバイパスします。

Pass-07

このレベルでは、末尾のスペースが許可されています。そのため、.php (末尾スペース) という形式の拡張子を使用してバイパスします。

Pass-08

このレベルでは、全ての解析可能な拡張子がブラックリストに含まれています。しかし、.php. (点php点加空格) という形式の拡張子を使用することでバイパスできます。

Pass-09

このレベルでは、::$DATAを使用してバイパスします。Windowsの特性を利用し、test.php::$DATAという形式でアップロードすると、::$DATA以降のデータがファイルストリームとして処理され、拡張子の検証がスキップされます。

Pass-10

このレベルでは、.php. . (点php点空格点) という形式の拡張子を使用してバイパスします。

Pass-11

このレベルでは、str_ireplace関数を使用して文字列を置換しています。バイパスするには、ダブル書き込みを使用します。

Pass-12

このレベルでは、ホワイトリストによるフィルタリングが行われています。ただし、アップロードパスを制御できるため、%00で切断してバイパスします。

Pass-13

このレベルでもホワイトリストによるフィルタリングが行われていますが、POSTメソッドを使用しているため、16進数で%00を挿入してバイパスします。

Pass-14

このレベルでは、画像ファイルの先頭2バイトを読み込んでタイプを判定しています。そのため、画像ヘッダーを偽装してバイパスします。

function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2);
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);    
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
    $fileType = '';    
    switch($typeCode){      
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "ファイル不明、アップロード失敗!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "アップロードエラー!";
        }
    }
}

Pass-15

このレベルでは、getimagesize()関数を使用して画像を検証しています。画像ヘッダーを偽装してバイパスします。

Pass-16

このレベルでは、exif_imagetype関数を使用して画像を検証しています。画像ヘッダーを偽装してバイパスします。

Pass-17

このレベルでは、拡張子、Content-Type、およびimagecreatefromgifを使用して画像を検証しています。さらに二次レンダリングも行われます。画像木馬を作成し、データパケットをキャプチャして悪意のあるコードを挿入してバイパスします。

Pass-18

このレベルでは、競合条件を利用する必要があります。複数の同じファイルを同時にアップロードし、削除前にアクセスすることでバイパスします。

Pass-19

このレベルでも競合条件を利用する必要があります。ただし、画像木馬を使用します。

Pass-20

このレベルでは、save_nameパラメータを使用してmove_uploaded_file()関数のパスを制御します。%00で切断してバイパスします。

Pass-21

このレベルでは、複雑なロジックが使用されています。MIMEタイプを変更し、save_nameパラメータを利用して配列を操作することでバイパスします。

タグ: PHP Upload-Labs ファイルアップロード セキュリティ ブラックリスト

6月24日 16:13 投稿