この記事では、PHP に関する関連知識を主に紹介します。シリアル化とは、実際にはデータを可逆的なデータ構造に変換することです。当然、その逆の処理はデシリアライズと呼ばれます。 PHP では、データをシリアル化および逆シリアル化する 2 つの関数を使用します: シリアル化はオブジェクトを順序付けられた文字列にフォーマットし、アンシリアル化は文字列を元のオブジェクトに戻します。
(推奨チュートリアル: PHP ビデオ チュートリアル)
シリアル化の目的は、データを容易にすることです。送信とストレージ: PHP では、通常、セッション キャッシュ、Cookie などのキャッシュにシリアル化と逆シリアル化が使用されます。
__wakeup() //unserialize() を実行すると、この関数が最初に呼び出されます
#__sleep() //serialize() を実行すると、この関数が最初に呼び出されます##__destruct() //オブジェクトが破棄されるとトリガーされます
##__unset( ) // unset() がアクセスできないプロパティで使用されるときにトリガーされます。
#__toString() // クラスが文字列として使用されるときにトリガーされます
__invoke() //オブジェクトを関数として呼び出そうとするときにトリガーされます
逆シリアル化は小さなトリックを回避します
変数が保護されている場合、シリアル化結果の前に
\x00*\x00Bypass_wakeup(CVE-2016- 7124)
バージョン:PHP5
PHP7 エクスプロイト方法: の数を表す値がシリアル化された文字列内のオブジェクト属性が実際の属性数より大きい場合、__wakeup の実行はスキップされます。 次のようなカスタム クラスの場合
<?php class test{ protected $a; public function __construct(){ $this->a = 'abc'; } public function __destruct(){ echo $this->a; } } 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 の同様のテスト ポイントです。
serialize(array(a ) ) ; / / a));//a));
//a は逆シリアル化されるオブジェクトです (シリアル化の結果は a で始まり、
<?php class test{ public $a; public function __construct(){ $this->a = 'abc'; } public function __wakeup(){ $this->a='666'; } public function __destruct(){ echo $this->a; } }参照を使用する
<?php class test{ public $a; public function __construct(){ $this->a = 'abc'; } public function __destruct(){ echo $this->a.PHP_EOL; } } function match($data){ if (preg_match('/^O:\d+/',$data)){ die('you lose!'); }else{ return $data; } } $a = 'O:4:"test":1:{s:1:"a";s:3:"abc";}'; // +号绕过 $b = str_replace('O:4','O:+4', $a); unserialize(match($b)); // serialize(array($a)); unserialize('a:1:{i:0;O:4:"test":1:{s:1:"a";s:3:"abc";}}');
$b を
$a
$a
は常に$b
以上がPHP デシリアライゼーション構造の知識ポイントの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。