讀懂PHP反序列化

主要目的

借著本次機(jī)會(huì)系統(tǒng)的學(xué)習(xí)反序列化漏洞劫扒,和PHP的一些語句的具體用法

問題原因:

漏洞的根源在于unserialize()函數(shù)的參數(shù)可控适揉。如果反序列化對象中存在魔術(shù)方法,而且魔術(shù)方法中的代碼或變量用戶可控徐钠,就可能產(chǎn)生反序列化漏洞呜魄,根據(jù)反序列化后不同的代碼可以導(dǎo)致各種攻擊灌旧,如代碼注入、SQL注入悴晰、目錄遍歷等等棵逊。
魔術(shù)方法:PHP的類中可能會(huì)包含一些特殊的函數(shù)叫魔術(shù)函數(shù)甫何,魔術(shù)函數(shù)命名是以符號__開頭的; 有以下的魔術(shù)方法: __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set(), _state(), __clone(), __debugInfo()

__sleep 和__wakeup

序列化serialize可以把變量包括對象,轉(zhuǎn)化成連續(xù)bytes數(shù)據(jù). 你可以將序列化后的變量存在一個(gè)文件里或在網(wǎng)絡(luò)上傳輸. 然后再反序列化還原為原來的數(shù)據(jù). 你在反序列化類的對象之前定義的類,PHP可以成功地存儲(chǔ)其對象的屬性和方法. 有時(shí)你可能需要一個(gè)對象在反序列化后立即執(zhí)行. 為了這樣的目的,PHP會(huì)自動(dòng)尋找__sleep和__wakeup方法.

當(dāng)一個(gè)對象被序列化,PHP會(huì)調(diào)用__sleep方法(如果存在的話). 在序列行化一個(gè)對象后,PHP 會(huì)調(diào)用__wakeup方法. 這兩個(gè)方法都不接受參數(shù). __sleep方法必須返回一個(gè)數(shù)組,包含需要序列化化的屬性.PHP會(huì)拋棄其它屬性的值. 如果沒有__sleep方法,PHP將保存所有屬性.

在程序執(zhí)行前,serialize() 函數(shù)會(huì)首先檢查是否存在一個(gè)魔術(shù)方法 __sleep.如果存在,__sleep()方法會(huì)先被調(diào)用旁涤, 然后才執(zhí)行串行化(序列化)操作。這個(gè)功能可以用于清理對象搓萧,并返回一個(gè)包含對象中所有變量名稱的數(shù)組讳窟。如果該方法不返回任何內(nèi)容,則NULL被序列化饲帅,導(dǎo)致 一個(gè)E_NOTICE錯(cuò)誤复凳。與之相反,unserialize()會(huì)檢查是否存在一個(gè)__wakeup方法灶泵。如果存在育八,則會(huì)先調(diào)用 __wakeup方法,預(yù)先準(zhǔn)備對象數(shù)據(jù)赦邻。

__sleep() 方法常用于提交未提交的數(shù)據(jù)髓棋,或類似的清理操作。同時(shí)惶洲,如果有一些很大的對象按声,但不需要全部保存,這個(gè)功能就很好用恬吕。
與之相反签则,unserialize() 會(huì)檢查是否存在一個(gè) __wakeup() 方法。如果存在铐料,則會(huì)先調(diào)用 __wakeup 方法渐裂,預(yù)先準(zhǔn)備對象需要的資源豺旬。
__wakeup() 經(jīng)常用在反序列化操作中,例如重新建立數(shù)據(jù)庫連接柒凉,或執(zhí)行其它初始化操作族阅。

<?php
class Connection 
{
    protected $link;
    private $server, $username, $password, $db;
    
    public function __construct($server, $username, $password, $db)
    {
        $this->server = $server;
        $this->username = $username;
        $this->password = $password;
        $this->db = $db;
        $this->connect();
    }
    
    private function connect()
    {
        $this->link = mysql_connect($this->server, $this->username, $this->password);
        mysql_select_db($this->db, $this->link);
    }
    
    public function __sleep()
    {
        return array('server', 'username', 'password', 'db');
    }
    
    public function __wakeup()
    {
        $this->connect();
    }
}
?>

下面例子顯示了如何用__sleep和 __wakeup方法來序列化一個(gè)對象. Id屬性是一個(gè)不打算保留在對象中的臨時(shí)屬性. __sleep方法保證在串行化的對象中不包含id屬性. 當(dāng)反串行化一個(gè)User對象,__wakeup方法建立id屬性的新值. 這個(gè)例子被設(shè)計(jì)成自我保持. 在實(shí)際開發(fā)中膝捞,你可能發(fā)現(xiàn)包含資源(如圖像或數(shù)據(jù)流)的對象需要這些方法坦刀。

<?php
class user {
    public $name;
    public $id;
     
    function __construct() {    // 給id成員賦一個(gè)uniq id
        $this->id = uniqid();
        }
         
    function __sleep() {       //此處不串行化id成員
        return(array('name'));
        }
         
    function __wakeup() {
        $this->id = uniqid();
        }
    }
$u = new user();
$u->name = "Leo";
$s = serialize($u); //serialize串行化對象u,此處不串行化id屬性蔬咬,id值被拋棄
$u2 = unserialize($s); //unserialize反串行化鲤遥,id值被重新賦值
//對象u和u2有不同的id賦值
print_r($u);
print_r($u2);
 
?>
user Object
(
   [name] => Leo
   [id] => 5d0d9c66b9a03
)
user Object
(
   [name] => Leo
   [id] => 5d0d9c66b9a45
)
<?php
class Person
{
    private $name, $age, $sex, $info;

    public function __construct( $name, $age, $sex )
    {
        $this->name = $name;
        $this->age  = $age;
        $this->sex  = $sex;
        $this->info = sprintf("prepared by construct magic functionname: %s age: %d sex: %s",
            $this->name, $this->age, $this->sex);
    }

    public function getInfo()
    {
        echo $this->info . PHP_EOL;
    }
    /**
     * serialize前調(diào)用 用于刪選需要被序列化存儲(chǔ)的成員變量
     * @return array [description]
     */
    public function __sleep()
    {
        echo __METHOD__ . PHP_EOL;
        //序列化時(shí)只會(huì)存儲(chǔ) name age sex, info 不會(huì)被序列化
        return ['name', 'age', 'sex'];
    }
    /**
     * unserialize前調(diào)用 用于預(yù)先準(zhǔn)備對象資源
     */
    public function __wakeup()
    {
        echo __METHOD__ . PHP_EOL;
        $this->info = sprintf("prepared by wakeup magic function name: %s age: %d sex: %s",
            $this->name, $this->age, $this->sex);
    }
}

$boy = new Person( 'sallency', 25, 'male' );
//構(gòu)造函數(shù)組裝的 $info
$boy->getInfo();
echo "<hr>";
//序列化時(shí)并不會(huì)存儲(chǔ) $info 屬性
$temp = serialize($boy);
echo $temp . PHP_EOL;
echo "<hr>";
//反序列化時(shí)會(huì)調(diào)用 __wakeup() 函數(shù)
$boy = unserialize($temp);
//__wakeup() 組裝的 $info
$boy->getInfo();
echo "<hr>";
?>
prepared by construct magic functionname: sallency age: 25 sex: male
<hr>Person::__sleep
O:6:"Person":3:{s:12:"Personname";s:8:"sallency";s:11:"Personage";i:25;s:11:"Personsex";s:4:"male";}
<hr>Person::__wakeup
prepared by wakeup magic function name: sallency age: 25 sex: male
<hr>

先寫一段代碼

class myClass{
    public $myContent;
    function outMycontent(){
        //dosomething
    }
}
$content = new myClass();
echo serialize($content);

輸出的結(jié)果是O:7:”myClass”:1:{s:9:”myContent”;N;}

它竟然把一個(gè)類的給序列化了,也就是把一個(gè)類轉(zhuǎn)換成了一個(gè)字符串计盒,可以傳輸或者保存下來渴频。

下面我修改一下上面的代碼

class myClass{
    public $myContent;
    function __construct($string){
        $this->myContent = $string;
    }
}
$content = new myClass('my china');
echo serialize($content);

輸出的結(jié)果是O:7:”myClass”:1:{s:9:”myContent”;s:8:”my china”;}

序列化后也對應(yīng)了相應(yīng)的值,但是現(xiàn)在有個(gè)問題北启,比如我這個(gè)變量是個(gè)秘密呢卜朗?而且我又得把這個(gè)類序列化傳給別的地方呢?
看下面的代碼

class myClass{
    public $myContent;
    function __construct($string){
        $this->myContent = $string;
    }
}
$content = new myClass('我愛宋祖英咕村,這是一個(gè)秘密');
echo serialize($content);

輸出的結(jié)果是O:7:”myClass”:1:{s:9:”myContent”;s:36:”我愛宋祖英场钉,這是一個(gè)秘密”;}

我的秘密序列化后還是存在的,可是我不想我的心里話被別人看到懈涛。這個(gè)時(shí)候PHP很貼心逛万,她知道你的問題,所以設(shè)置了魔術(shù)方法批钠。

__sleep() 就表示當(dāng)你執(zhí)行serialize()這個(gè)序列化函數(shù)之前時(shí)的事情宇植,就像一個(gè)回調(diào)函數(shù),所以在這個(gè)回調(diào)函數(shù)里面我們就可以做點(diǎn)事情埋心,來隱藏我的秘密指郁。

class myClass{
    public $myContent;
    function __construct($string){
        $this->myContent = $string;
    }
    public function __sleep(){
        $this->myContent = '這是我的秘密';
        return array('myContent');

    }
}
$content = new myClass('我愛宋祖英,這是一個(gè)秘密');
echo serialize($content);

輸出的結(jié)果是:O:7:”myClass”:1:{s:9:”myContent”;s:18:”這是我的秘密”;}

我的心里話被加密了拷呆,這個(gè)就是__sleep()的作用闲坎。至于__wakeup()和__sleep()大同小異,只不過是反序列化之前進(jìn)行的回調(diào)函數(shù)茬斧。我不詳細(xì)說了腰懂,大家看下下面的代碼就明白了。

class myClass{
    public $myContent;
    function __construct($string){
        $this->myContent = $string;
    }
    public function __sleep(){
        $this->myContent = '這是我的秘密';
        return array('myContent');

    }
    public function __wakeup(){
        $this->myContent = '我的秘密又回來了';
        //反序列化就不用返回?cái)?shù)組了项秉,就是對應(yīng)的字符串的解密绣溜,字符串已經(jīng)有了就不用其他的了
    }
}
$content = new myClass('我愛宋祖英,這是一個(gè)秘密');
print_r(unserialize(serialize($content)));

輸出的內(nèi)容為:myClass Object ( [myContent] => 我的秘密有回來了 )

__toString

__toString() 方法用于定義一個(gè)類被當(dāng)成字符串時(shí)該如何處理伙狐。

__toString是在直接輸出對象引用時(shí)自動(dòng)調(diào)用的涮毫, 前面我們講過對象引用是一個(gè)指針瞬欧,比如說:“p=new Person()“中贷屎,p就是一個(gè)引用罢防,我們不能使用echo 直接輸出$p, 這樣會(huì)輸出”Catchable fatal error: Object of class Person could not be converted to string“這樣的錯(cuò)誤,如果你在類里面定義了“__toString()”方法唉侄,在直接輸出對象引用的時(shí)候咒吐,就不會(huì)產(chǎn)生錯(cuò)誤,而是自動(dòng)調(diào)用了”__toString()”方法, 輸出“__toString()”方法中返回的字符属划,所以“__toString()”方法一定要有個(gè)返回值(return 語句).

<?php 
class Person{ 
    private $name = ""; 
    function __construct($name = ""){ 
        $this->name = $name; 
    } 
    function say(){ 

        echo "Hello,".$this->name."!<br/>";   
    } 
    function __tostring(){//在類中定義一個(gè)__toString方法 

        return  "Hello,".$this->name."!<br/>";     
    } 
} 
$WBlog = new Person('WBlog'); 

echo $WBlog;//直接輸出對象引用則自動(dòng)調(diào)用了對象中的__toString()方法 

$WBlog->say();//試比較一下和上面的自動(dòng)調(diào)用有什么不同 
?>

程序輸出:
Hello,WBlog!
Hello,WBlog!
如果不定義“__tostring()”方法會(huì)怎么樣呢恬叹?例如在上面代碼的基礎(chǔ)上,把“ __tostring()”方法屏蔽掉同眯,再看一下程序輸出結(jié)果:
Catchable fatal error: Object of class Person could not be converted to string
由此可知如果在類中沒有定義“__tostring()”方法绽昼,則直接輸出以象的引用時(shí)就會(huì)產(chǎn)生誤法錯(cuò)誤,另外__tostring()方法體中需要有一個(gè)返回值须蜗。

__invoke

當(dāng)嘗試以調(diào)用函數(shù)的方式調(diào)用一個(gè)對象時(shí)硅确,__invoke() 方法會(huì)被自動(dòng)調(diào)用。(本特性只在 PHP 5.3.0 及以上版本有效明肮。)

<?php 
class Demo{ 
        public function __invoke(){ 
                echo "測試"; 
        } 
} 
$demo = new Demo; 
$demo(); 
?> 

這樣的話,直接用對象名就當(dāng)函數(shù)使用了,調(diào)用的是_invoke的方法;
輸出
測試

__construct 構(gòu)造方法 __destruct 析構(gòu)方法

__construct()在每次創(chuàng)建新對象時(shí)先調(diào)用此方法
__destruct() 允許在銷毀一個(gè)類之前執(zhí)行執(zhí)行析構(gòu)方法菱农。

<?php
 
/**
 * 清晰的認(rèn)識__construct() __destruct()
 */
class Example {
 
    public static $link;
    //在類實(shí)例化的時(shí)候自動(dòng)加載__construct這個(gè)方法
    public function __construct($localhost, $username, $password, $db) {
        self::$link = mysql_connect($localhost, $username, $password);
        if (mysql_errno()) {
            die('錯(cuò)誤:' . mysql_error());
        }
        mysql_set_charset('utf8');
        mysql_select_db($db);
    }
 
    /**
     * 通過__construct鏈接好數(shù)據(jù)庫然后執(zhí)行sql語句......
     */
     
    //當(dāng)類需要被刪除或者銷毀這個(gè)類的時(shí)候自動(dòng)加載__destruct這個(gè)方法
    public function __destruct() {
        echo '<pre>';
        var_dump(self::$link);
        mysql_close(self::$link);
        var_dump(self::$link);
    }
 
}
 
$mysql = new Example('localhost', 'root', 'root', 'test');

結(jié)果:

resource(2) of type (mysql link)
resource(2) of type (Unknown)

__set __get

__get()方法:這個(gè)方法用來獲取私有成員屬性值的,有一個(gè)參數(shù),參數(shù)傳入你要獲取的成員屬性的名稱柿估,返回獲取的屬性值循未。如果成員屬性不封裝成私有的,對象本身就不會(huì)去自動(dòng)調(diào)用這個(gè)方法秫舌。
__set()方法:這個(gè)方法用來為私有成員屬性設(shè)置值的的妖,有兩個(gè)參數(shù),第一個(gè)參數(shù)為你要為設(shè)置值的屬性名足陨,第二個(gè)參數(shù)是要給屬性設(shè)置的值嫂粟,沒有返回值。(key=>value)
__set() 方法用于設(shè)置私有屬性值:

function __set($property_name, $value)
{ 
    $this->$property_name = $value; 
}

在類里面使用了 __set() 方法后钠右,當(dāng)使用 $p1->name = "張三"; 這樣的方式去設(shè)置對象私有屬性的值時(shí)赋元,就會(huì)自動(dòng)調(diào)用 __set() 方法來設(shè)置私有屬性的值。

__get()
__get() 方法用于獲取私有屬性值:

function __set($property_name, $value)
{ 
    return isset($this->$property_name) ? $this->$property_name : null;
}

例子:

<?php
class Person {
    private $name;
    private $sex;
    private $age;

    //__set()方法用來設(shè)置私有屬性
    function __set($property_name, $value) { 
        echo "在直接設(shè)置私有屬性值的時(shí)候飒房,自動(dòng)調(diào)用了這個(gè) __set() 方法為私有屬性賦值<br />";
        $this->$property_name = $value; 
    }
    //__get()方法用來獲取私有屬性
    function __get($property_name) {  
        echo "在直接獲取私有屬性值的時(shí)候搁凸,自動(dòng)調(diào)用了這個(gè) __get() 方法<br />";
        return isset($this->$property_name) ? $this->$property_name : null;
    }
}

$p1=new Person();
//直接為私有屬性賦值的操作, 會(huì)自動(dòng)調(diào)用 __set() 方法進(jìn)行賦值
$p1->name = "張三";
//直接獲取私有屬性的值狠毯, 會(huì)自動(dòng)調(diào)用 __get() 方法护糖,返回成員屬性的值
echo "我的名字叫:".$p1->name;    
?>

運(yùn)行該例子,輸出:

在直接設(shè)置私有屬性值的時(shí)候嚼松,自動(dòng)調(diào)用了這個(gè) __set() 方法為私有屬性賦值
在直接獲取私有屬性值的時(shí)候嫡良,自動(dòng)調(diào)用了這個(gè) __get() 方法

我的名字叫:張三

__isset() __unset()

__isset()
__isset() 方法用于檢測私有屬性值是否被設(shè)定锰扶。

如果對象里面成員是公有的,可以直接使用 isset() 函數(shù)寝受。如果是私有的成員屬性坷牛,那就需要在類里面加上一個(gè) __isset() 方法:

private function __isset($property_name)
{
    return isset($this->$property_name);
}

這樣當(dāng)在類外部使用 isset() 函數(shù)來測定對象里面的私有成員是否被設(shè)定時(shí),就會(huì)自動(dòng)調(diào)用 __isset() 方法來檢測很澄。

__unset()
__unset() 方法用于刪除私有屬性京闰。

同 isset() 函數(shù)一樣,unset() 函數(shù)只能刪除對象的公有成員屬性甩苛,當(dāng)要?jiǎng)h除對象內(nèi)部的私有成員屬性時(shí)蹂楣,需要使用__unset() 方法:

private function __unset($property_name)
{
    unset($this->$property_name);
}

### __call __callStatic  

1.__call()方法。當(dāng)調(diào)用一個(gè)沒有在類中聲明的方法時(shí)讯蒲,可以調(diào)用__call()方法代替聲明一個(gè)方法痊土。接受方法名和數(shù)組作為參數(shù)。

代碼實(shí)例:

<?php  
class test{  
//魔術(shù)方法__call  
/* 
$method 獲得方法名 
$arg 獲得方法的參數(shù)集合 
*/  
public function __call($method,$arg){  
    echo '你想調(diào)用我不存在的方法',$method,'方法<br/>';  
    echo '還傳了一個(gè)參數(shù)<br/>';  
    echo print_r($arg),'<br/>';  
  }   
$list=new test();  
$list->say(1,2,3);  
  
?> 

執(zhí)行結(jié)果:
你想調(diào)用我不存在的方法say方法
還傳了一個(gè)參數(shù)
Array ( [0] => 1 [1] => 2 [2] => 3 )

2.__callStatic()方法墨林。從PHP5.3開始出現(xiàn)此方法赁酝,當(dāng)創(chuàng)建一個(gè)靜態(tài)方法以調(diào)用該類中不存在的一個(gè)方法時(shí)使用此函數(shù)。與__call()方法相同萌丈,接受方法名和數(shù)組作為參數(shù)赞哗。
代碼實(shí)例:

<?php  
class test{  
//魔術(shù)方法__callStatic 
/* 
$method 獲得方法名 
$arg 獲得方法的參數(shù)集合 
*/  
//魔術(shù)方法__callStatic  
public static function __callStatic($method,$arg){  
  
    echo '你想調(diào)用我不存在的',$method,'靜態(tài)方法<br/>';  
    echo '還傳了一個(gè)參數(shù)<br/>';  
    echo print_r($arg),'<br/>';  
  }  
  
}  
test::cry('痛哭','鬼哭','號哭');  
 
?> 

執(zhí)行結(jié)果:
你想調(diào)用我不存在的cry靜態(tài)方法
還傳了一個(gè)參數(shù)
Array ( [0] => 痛哭 [1] => 鬼哭 [2] => 號哭 )

參考:
https://www.cnblogs.com/uduemc/p/4122156.html
https://blog.csdn.net/guiyecheng/article/details/60590646
https://blog.csdn.net/wong_gilbert/article/details/76679108
http://www.5idev.com/p-php_member_overloading.shtml
https://blog.csdn.net/sunyinggang/article/details/78906048

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辆雾,隨后出現(xiàn)的幾起案子肪笋,更是在濱河造成了極大的恐慌,老刑警劉巖度迂,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件藤乙,死亡現(xiàn)場離奇詭異,居然都是意外死亡惭墓,警方通過查閱死者的電腦和手機(jī)坛梁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腊凶,“玉大人划咐,你說我怎么就攤上這事【迹” “怎么了褐缠?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長风瘦。 經(jīng)常有香客問我队魏,道長,這世上最難降的妖魔是什么万搔? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任胡桨,我火速辦了婚禮官帘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘昧谊。我一直安慰自己刽虹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布揽浙。 她就那樣靜靜地躺著状婶,像睡著了一般意敛。 火紅的嫁衣襯著肌膚如雪馅巷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天草姻,我揣著相機(jī)與錄音钓猬,去河邊找鬼。 笑死撩独,一個(gè)胖子當(dāng)著我的面吹牛敞曹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播综膀,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼澳迫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了剧劝?” 一聲冷哼從身側(cè)響起橄登,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讥此,沒想到半個(gè)月后拢锹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萄喳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年卒稳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片他巨。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡充坑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出染突,到底是詐尸還是另有隱情捻爷,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布觉痛,位于F島的核電站役衡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏薪棒。R本人自食惡果不足惜手蝎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一榕莺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧棵介,春花似錦钉鸯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吨述,卻和暖如春岩睁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背揣云。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工捕儒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邓夕。 一個(gè)月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓刘莹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親焚刚。 傳聞我的和親對象是個(gè)殘疾皇子点弯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容