Heim >Backend-Entwicklung >PHP-Problem >PHP-Kurzanalyse der Wissenspunkte der Deserialisierungsstruktur
Dieser Artikel führt Sie hauptsächlich in das relevante Wissen über PHP ein. Bei der Serialisierung handelt es sich tatsächlich um die Umwandlung von Daten in eine reversible Datenstruktur. Der umgekehrte Vorgang wird natürlich Deserialisierung genannt. PHP verwendet zwei Funktionen, um Daten zu serialisieren und zu deserialisieren: Serialize formatiert das Objekt in eine geordnete Zeichenfolge und unserialize stellt die Zeichenfolge im Originalobjekt wieder her. Ich hoffe, dass dies für alle hilfreich ist.
(Empfohlenes Tutorial: PHP-Video-Tutorial)
Der Zweck der Serialisierung besteht darin, die Übertragung und Speicherung von Daten zu erleichtern. In PHP werden Serialisierung und Deserialisierung im Allgemeinen zum Zwischenspeichern verwendet, beispielsweise zum Sitzungs-Caching , Kekse usw.
__wakeup() //Bei der Ausführung von unserialize() wird diese Funktion zuerst aufgerufen
__sleep() //Wenn serialize() ausgeführt wird, wird diese Funktion zuerst aufgerufen ?? context Wird ausgelöst, wenn die Methode
__get() //Diese Methode wird aufgerufen, wenn Daten aus unzugänglichen Eigenschaften gelesen werden oder der Schlüssel nicht vorhanden ist
__set() //Wird zum Schreiben von Daten in unzugängliche Eigenschaften verwendet. Eigenschaften
__isset() //Wird ausgelöst, wenn isset() oder empty() für eine unzugängliche Eigenschaft aufgerufen wird
__isset() //Wird ausgelöst, wenn unset() für eine unzugängliche Eigenschaft verwendet wird
__toString() / /Ausgelöst, wenn die Klasse als String verwendet wird
__invoke() //Ausgelöst, wenn versucht wird, das Objekt als Funktion aufzurufen
Deserialisierung umgeht den kleinen Trick
Wir haben zuvor gesagt, dass dem Serialisierungsergebnis x00*x00
vorangestellt wird, wenn die Variable geschützt ist.
abc
aus, auch wenn kein x00*x00
vorhanden ist <?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";}');
unserialize('O:4:"test":1:{s:1:"a";s:3:"abc";}');
Die Ausgabe ausführen Ergebnis ist 666
und der Wert der Anzahl der Objektattribute wird erhöht und ausgeführt unserialize('O:4:"test":2:{s:1:"a"; s:3:"abc";}');
Das Ausgabeergebnis ist abc
x00*x00
但在特定版本7.1以上则对于类属性不敏感,比如下面的例子即使没有x00*x00
也依然会输出abc
<?php class test{ public $a; public function __construct(){ $this->a = 'abc'; } public function __wakeup(){ $this->a='666'; } public function __destruct(){ echo $this->a; } }
版本:
PHP5 < 5.6.25
PHP7 < 7.0.10
利用方式:序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
对于下面这样一个自定义类
<?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";}}');
如果执行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里传参时+要编码为%2B)
serialize(array(a ) ) ; / / a));//a));
//a为要反序列化的对象(序列化结果开头是a,不影响作为数组元素的$a的析构)
<?php class test{ public $a; public $b; public function __construct(){ $this->a = 'abc'; $this->b= &$this->a; } public function __destruct(){ if($this->a===$this->b){ echo 666; } } } $a = serialize(new test());
上面这个例子将$b
设置为$a
的引用,可以使$a
永远与$b
Unter Umgehung einiger regulärer Regeln
preg_match('/^O:d+/') Übereinstimmt, ob die serialisierte Zeichenfolge mit einer Objektzeichenfolge beginnt. Dies war ein ähnlicher Testpunkt in früheren CTFs.
Verwenden Sie das Pluszeichen zum Umgehen (beachten Sie, dass + als %2B codiert werden muss, wenn Parameter in der URL übergeben werden).
serialize(array(a ) ) ; / / a));//a));
//a ist das zu deserialisierende Objekt (das Serialisierungsergebnis beginnt mit a, was keine Auswirkungen hat (die Verwendung als Array) Zerstörung des Elements $a)
Referenz verwenden
rrreeeDas obige Beispiel setzt $b
auf eine Referenz von $a
, was Folgendes bewirken kann $a
ist immer gleich $b
Hexadezimal umgeht die ZeichenfilterungO:4:"test":2:{s:4:"%00*% 00a" ;s:3:"abc";s:7:"%00test%00b";s:3:"def";}
🎜kann geschrieben werden als🎜🎜O:4:"test":2:{ S:4: „Das obige ist der detaillierte Inhalt vonPHP-Kurzanalyse der Wissenspunkte der Deserialisierungsstruktur. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!