PHP序列化與反序列化

2022-08-27 19:15:15 字數 3880 閱讀 8729

物件序列化

<?php

class site

function geturl()

function settitle($par)

function gettitle()

}$s = new site();

var_dump(serialize($s));

//string(41) "o:4:"site":2:"

$s->url = '';

$s->title = "cdr's blog";

var_dump(serialize($s));

//string(85) "o:4:"site":2:"

?>

可見,對於類物件的序列化,函式沒有體現出來。規律可總結如下:

不同修飾符修飾修飾的變數

<?php

class test

public function get_flag($flag)

}$test = new test();

$test->$flag = 'flag';

var_dump(serialize($test));

?>

①修飾符為public時:string(46) "o:4:"test":2:"

②修飾符為protected時:string(49) "o:4:"test":2:

public function __destruct()

public function __wakeup()

public function __tostring()

}$a = new tostring_demo("demo");

$b = serialize($a);

$c = unserialize($b);

print $c;結果為:

__wakeup:wakeup  //序列化時啟動__wakeup

__tostring:tostring //__tostring方法處有返回值,實現呼叫

__destruct:tostring //銷毀物件$a

__destruct:demo //銷毀物件$c

當反序列化後的物件在經過php字串函式時,都會執行__tostring方法,比如strlen(),addslashes(),class_exists()等,可見__tostring的利用點還是很多的。

執行unserialize()時,先會呼叫__wakeup()unserialize()會檢查存在乙個__wakeup()方法。如果存在,則先會呼叫__wakeup()方法。

這裡有乙個比較常見的漏洞,用於繞過__wakeup():

class xctf

}?code=

序列化後為o:4:"xctf":1:,意味物件名稱長度為4,包含屬性數1,屬性名稱型別為string,長度為4,名稱為"flag",屬性值長度為3,屬性值為"111"。__wakeup()漏洞就是與整個屬性個數值有關。

當序列化字串表示物件屬性個數的值大於真實個數的屬性時就會跳過__wakeup的執行。為了避開__wakeup()函式的exit(),可以上傳o:4:"xctf":2:

執行serialize()時,先會呼叫__sleep()serialize() 函式會檢查類中是否存在乙個魔術方法 __sleep()。如果存在,則該方法會優先被呼叫,然後才執行序列化操作。

此功能可以用於清理物件,並返回乙個包含物件中所有應被序列化的變數名稱的陣列。

如果該方法未返回任何內容,則 null 被序列化,並產生乙個 e_notice 級別的錯誤。

<?php

class person

public function __sleep()

}$person = new person('小明'); // 初始賦值

echo serialize($person);

//o:6:"person":2:

當呼叫乙個物件中的不能用的方法的時候就回執行這個函式。

public mixed __call ( string $name , array $arguments )

string $name是要呼叫的方法名。array $arguments引數是乙個列舉陣列,包含著要傳遞給$name的引數。

__call()成對出現的是__callstatic()方法,在靜態上下文中呼叫乙個不可用的方法時會執行這個方法。

<?php

class methodtest

// php 5.3.0之後的版本

public static function __callstatic($name, $arguments)

}

$obj = new methodtest;

$obj -> runtest('in object context');

// php 5.3.0 版本以後

methodtest::runtest('in static context');

//calling object method 『runtest』 in object context

//calling static method 『runtest』 in static context

__get()是訪問不存在的成員變數時呼叫的;

__set()是設定不存在的成員變數時呼叫的;

<?php

class test

public function __get($x)

} $a = new test;

$a->b = 1 ;//成員變數b不存在,所以會呼叫__set

$a->c = 2;//成員變數c存在,所以無任何輸出

$d=$a->b;// 成員變數b不存在,所以會呼叫__get

?>b1

the value of b is 1

class test

$test=new test();

var_dump(isset($test->abc));

//false

雖然類裡面有abc這個屬性,但是它是私有屬性,是不能被外部所訪問的,所以返回布林false。如果想讓外部能夠發現私有屬性,可以設定__isset()方法。
class test

}

$test=new test();

var_dump(isset($test->abc));

//true

當外部的isset($test->abc) 檢測不到abc時,它就會自動去執行類裡面的__isset()這個方法,然後返回結果。

__unset($var):用來刪除私有屬性,只有乙個引數:屬性名。

class test

}$test=new test();

unset($test->abc);

外部的unset($test->abc)檢測不到abc時,設定了__unset()方法後就會去執行類裡面的__unset()這個方法,然後刪除屬性。

例項化物件本身是不能被呼叫,但是類中如果實現 __invoke() 方法,則把例項物件當作方法呼叫,會自動呼叫到 __invoke() 方法,引數順序相同。

<?php

class asdf

}$obj = new asdf();

$obj(123, 456);

var_dump(is_callable($obj));

?>

//int(123)

//int(456)

//bool(true)

php序列化與反序列化

php的序列化 反序列化對與一些大檔案的壓縮操作,讀寫操作十分有用。乙個簡單的序列化案例 同時用到了序列化與反序列化函式,二者在被呼叫時會分別自己呼叫對應的函式,sleep 以及 wakeup.sleep和 wakeup練習題 故事 乙個果農生產了很多水果種類,於是需要把乙個買家指定的種類寄給他,生...

php 序列化與反序列化

序列化 反序列化序列化 例一class user number 66 str jerry bool true null null arr array a 1,b 2 user new user tom true var dump serialize number var dump serialize...

php序列化與反序列化

jarvisoj上的一道題 是關於php序列化以及反序列化引起的問題,我看 wp大神的wp 題目給直接給出了源 這句話是關鍵,漏洞產生在php serialize和php解析方式上。如果我們通過php serialize的方式構造序列化語句,然後通過php的方式解析序列化語句,就會出現問題。原因是在...