1. 脆弱性の紹介
2019 年 1 月 11 日、ThinkPHP チームは A を修正するパッチ更新をリリースしました。安全でない動的関数呼び出しによって引き起こされるリモートコード実行の脆弱性が発見されました。この脆弱性は非常に有害であり、デフォルトでリモート コードが実行される可能性があります。 Venus ADLab のセキュリティ研究者は、ThinkPHP の複数のバージョンでソース コードの分析と検証を行った結果、特に影響を受けるバージョンが ThinkPHP 5.0 ~ 5.0.23 のフル バージョンであることを確認しました。
2. 脆弱性の再現
ローカル環境では、ThinkPHP 5.0.22 および PHP5.5.38 Apache のフルバージョンを使用して再現します。環境をインストールした後、図に示すように POC を実行してシステム コマンドを実行します:
3. 脆弱性分析
公式 Web サイトに基づく ダウンロードした 5.0.22 のフル バージョンを分析した後、最初に脆弱性のキー ポイントを特定しました。
thinkphp/library/think/Request.php:518
メソッド関数の 2 番目の if 分岐では、外部から制御可能なデータ$_POST[Config::get が導入されました ['var_method']。 var_method の値は _method です。
Request クラスの __construct 関数は次のとおりです。
$options パラメーターは制御可能であるため、攻撃者はフィルター属性、メソッド属性を上書きできます。そしてクラスの属性の値を取得します。 Request クラスの param 関数内:
$this->mergeParam が空の場合、ここで $this->get(false) が呼び出されます。 $this->get 関数を追跡します。
$this->input 関数が関数の最後で呼び出され、$this->get が渡され、$this- の値が渡されます。 >getは制御可能な攻撃です。 $this->input 関数を追跡します。
この関数は、$this->getFileter を呼び出してフィルターを取得します。関数本体は次のとおりです:
#$this->フィルターの値はオーバーライドされ、コンストラクターを呼び出すことで攻撃者によって制御されます。値を返した後、入力関数に入ります:filterValue 関数を次のように表示します。 call_user_func 関数の呼び出しでは、$filter と $value が制御可能です。したがって、コードが実行される可能性があります。脆弱性トリガー プロセス:
ThinkPHP5 のエントリ ポイントから分析を開始します:thinkphp/library/think/App.php:77run 関数の最初の行は、Request クラスをインスタンス化します。 . そして $request に割り当てられます。次に、routeCheck($request,$config):ここで、ルート検出のために Route::check を呼び出します。機能は次のとおりです。 赤い文字の部分に注目してください。冒頭の最初のステップに相当します。これは、変数カバレッジのためのメソッド関数を呼び出すことです。ここでオーバーライドする必要があるプロパティは、$this->filter、$this->method、$this->get です。 $request->method() の戻り値は $this->method であるため、この値も制御する必要があります。ここでの戻り値を$methodに代入し、さらにself::$rules[$method]の値を取り出して$rulesに渡します。ここで注意してください: THINKPHP5 には自動クラス ロード メカニズムがあり、ベンダー ディレクトリ内のいくつかのファイルが自動的にロードされます。ただし、フルバージョンとコアバージョンのベンダーディレクトリ構造は異なります。 完全バージョンのディレクトリ構造は次のとおりです: コア バージョンのディレクトリ構造は次のとおりです:
#完全バージョンには、コア バージョンよりもいくつかのフォルダーが多いことがわかります。特に注意が必要なのは、think-captcha/src フォルダーに helper.php ファイルがあることです。
\think\Route::get 関数はここで呼び出されます。ルートを登録し、操作します。このステップの影響は、上記の self::$rules の値を変更することです。このルートでのみ RCE を実行できます。それ以外の場合は成功しません。これが、コア バージョンではなくフル バージョンにのみ影響する理由です。このとき、self::$rules の値は
# となります。すると、攻撃者が get に返される $method の値を制御すると、$ の値が取得されます。 rules はこのルーティング ルールです。次に、上記に戻って $rules を取得し、受信 URL に従って $item の値を取得します。これにより、$rules[$item] の値がキャプチャ ルーティング配列になり、さらに self:: を呼び出すことができます。 parseRule関数。関数本体は少し長くなります。重要な点は次のとおりです。
この時点で渡される $route の値は、\think\captcha\CaptchaController@index です。したがって、赤でマークされた if 分岐に入ります。このブランチでは、$result の「type」キーに対応する値は「method」です。次に、$result がレイヤーごとに run 関数に返され、$dispatch に割り当てられます。
次に $dispatch を self::exec 関数に組み込みます:
赤でマークされたブランチに入り、Request クラスの param メソッドを呼び出します。したがって、エクスプロイト チェーンの 3 番目のステップが満たされ、コマンドが実行されます。
Venstar ADLab のセキュリティ研究者は、ThinkPHP5.0-5.0.23 の各バージョンを分析し、ThinkPHP5.0.2-5.0.23 は同じ POC を使用できるが、ThinkPHP5.0-5.0.1 は変更する必要があることを発見しました。 POC を見てみますと、その理由は Route.php のルール関数の実装の小さな違いにあります。
ThinkPHP5.0-5.0.1 バージョン thinkphp/library/think/Route.php:235、$type を大文字に変換します:
ThinkPHP5 では。 0.2-5.0.23 バージョンでは、ルール関数内で $type が小文字に変換されます。
# 4. パッチ分析
In ThinkPHP5.0.24では、$this->methodの判定が追加され、クラス関数の自由呼び出しができなくなりました。
5. 結論
回避策として、ThinkPHP5.0.24 バージョンにアップグレードし、デバッグ モードを有効にしないことを強くお勧めします。攻撃されている。
関連する推奨事項: 「PHP チュートリアル 」
以上がThinkPHP5 コアクラス リモートコードの脆弱性分析をリクエストの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。