ホームページ >バックエンド開発 >PHPの問題 >PHP デシリアライゼーション構造の知識ポイントの簡単な分析

PHP デシリアライゼーション構造の知識ポイントの簡単な分析

WBOY
WBOY転載
2022-07-29 15:18:582085ブラウズ

この記事では、PHP に関する関連知識を主に紹介します。シリアル化とは、実際にはデータを可逆的なデータ構造に変換することです。当然、その逆の処理はデシリアライズと呼ばれます。 PHP では、データをシリアル化および逆シリアル化する 2 つの関数を使用します: シリアル化はオブジェクトを順序付けられた文字列にフォーマットし、アンシリアル化は文字列を元のオブジェクトに戻します。

PHP デシリアライゼーション構造の知識ポイントの簡単な分析

(推奨チュートリアル: PHP ビデオ チュートリアル)

はじめに

シリアル化の目的は、データを容易にすることです。送信とストレージ: PHP では、通常、セッション キャッシュ、Cookie などのキャッシュにシリアル化と逆シリアル化が使用されます。

逆シリアル化における一般的なマジック メソッド

  • __wakeup() //unserialize() を実行すると、この関数が最初に呼び出されます

    #__sleep() //serialize() を実行すると、この関数が最初に呼び出されます
  • ##__destruct() //オブジェクトが破棄されるとトリガーされます

  • #__call() //アクセスできないメソッドがオブジェクト コンテキストで呼び出されたときにトリガーされます。

  • __callStatic() //アクセスできないメソッドが静的コンテキストで呼び出されたときにトリガーされます

  • __get() //このメソッドは、アクセスできない属性からデータを読み取るとき、またはキーが存在しない場合に呼び出されます

  • __set() //アクセスできないプロパティにデータを書き込むために使用されます

  • ##__isset() //アクセスできないプロパティで isset() または empty() を呼び出すことによってトリガーされます
  • ##__unset( ) // unset() がアクセスできないプロパティで使用されるときにトリガーされます。
  • #__toString() // クラスが文字列として使用されるときにトリガーされます

  • __invoke() //オブジェクトを関数として呼び出そうとするときにトリガーされます

  • 逆シリアル化は小さなトリックを回避します

  • php7 .1 逆シリアル化はクラス属性に依存しません
  • 変数が保護されている場合、シリアル化結果の前に

    \x00*\x00

しかし、特定のバージョン 7.1 以降ではそうではありません。たとえば、次の例では、

\x00*\x00

Bypass_wakeup(CVE-2016- 7124)

バージョン:PHP5

PHP7 エクスプロイト方法: の数を表す値がシリアル化された文字列内のオブジェクト属性が実際の属性数より大きい場合、__wakeup の実行はスキップされます。 次のようなカスタム クラスの場合

<?php
class test{
    protected $a;
    public function __construct(){
        $this->a = &#39;abc&#39;;
    }
    public function  __destruct(){
        echo $this->a;
    }
}
unserialize(&#39;O:4:"test":1:{s:1:"a";s:3:"abc";}&#39;);

が実行された場合

unserialize(' O:4:"test":1:{s:1:"a";s:3:"abc";}');

出力結果は

666

オブジェクト属性番号の値を増やして実行

unserialize('O:4:"test":2:{s:1:"a";s:3:"abc"; }');

出力結果は #abc

いくつかの正規表現をバイパスします

preg_match('/^O:\d /')シリアル化されたかどうかを照合します文字列はオブジェクト文字列で始まります。これは、前の CTF の同様のテスト ポイントです。

プラス記号を使用してバイパスします (URL でパラメータを渡すときは、+ としてエンコードする必要があることに注意してください)

serialize(array(a ) ) ; / / a));//a));//a は逆シリアル化されるオブジェクトです (シリアル化の結果は a で始まり、

<?php
class test{
    public $a;
    public function __construct(){
        $this->a = &#39;abc&#39;;
    }
    public function __wakeup(){
        $this->a=&#39;666&#39;;
    }
    public function  __destruct(){
        echo $this->a;
    }
}

参照を使用する

<?php
class test{
    public $a;
    public function __construct(){
        $this->a = &#39;abc&#39;;
    }
    public function  __destruct(){
        echo $this->a.PHP_EOL;
    }
}
function match($data){
    if (preg_match(&#39;/^O:\d+/&#39;,$data)){
        die(&#39;you lose!&#39;);
    }else{
        return $data;
    }
}
$a = &#39;O:4:"test":1:{s:1:"a";s:3:"abc";}&#39;;
// +号绕过
$b = str_replace(&#39;O:4&#39;,&#39;O:+4&#39;, $a);
unserialize(match($b));
// serialize(array($a));
unserialize(&#39;a:1:{i:0;O:4:"test":1:{s:1:"a";s:3:"abc";}}&#39;);

上記の例では、

$b$a

の参照に設定します。

$a

は常に

$b

16 進数バイパス文字フィルタリングを行うことができます

O:4:"test":2:{ s:4: 「

以上がPHP デシリアライゼーション構造の知識ポイントの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjb51.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。