昨天被我亲爱的小杰杰和师弟拉去玩耍了一波红帽杯。。来写下wp做个小记录。
这次还是只解出来一题WEB2,,老废物了。。。。
最近没咋更博客。。因为文章都发到安全客上混点零花钱用了。。。= =
WEB2 - Yii2反序列化
这道题主要考察两个东西吧:Yii2反序列的链子 及 Apache mod_cgi bypass disable_functions
首先找入口点,比赛平台给的控制器为 /controllers/SiteController.php
。
找到反序列化的入口点 actionAbout()
1 | public function actionAbout($message = 'Hello') |
如果不清楚路由的,看到页面上的 “About” 按钮,点过去就是了。
反序列化POC,这里就不细细分析了,详情可以看看下面这些文章:
https://mp.weixin.qq.com/s/S3Un1EM-cftFXr8hxG4qfA
https://mp.weixin.qq.com/s/KCGGMBxmW5LSIey5nN7BDg
1 |
|
通过该POC,得到 disable_functions ,这里注意下,由于有 disable_functions。所以在 poc上无脑冲命令执行的将会得到报错回显。。。这可不是反序列化链子错了。。而是函数被禁用了。。
disable_functions内容:
1 | pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,dl,mail,putenv,error_log,error_reporting,unset,unlink,return |
经过了多次测试后,得到这玩意有两个坑:
- 使用
assert(eval())
形式执行命令时,注意 eval 里的语句最后要手动加个die()
,不然会使得程序继续执行而报错 - 直接写shell,该程序会自动将文件内 $ 后面的字符全部删去,导致无法直接写shell,但可以通过 php 的 copy 函数从 vps 上把shell扒拉下来
修改POC:
1 | ...... |
上shell后,在 / 目录下发现 readflag 文件。查看权限发现是 003 是 wx 权限,没r权限。说明我们需要执行这个文件才能获取 flag。
由于 putenv 被禁用了我们不可能使用 LD_PRELOAD 来 Bypass disable_function 。通过查看 apache配置文件可知,.htaccess 开着,并且mod_cgi 也开着。想到也许能通过 .htaccess来指定加载另外一个 php.ini。本以为是史无前例的发现,百度了才发现原来是人尽皆知的东西。。。。==
httpd.conf
1 | LoadModule cgi_module modules/mod_cgi.so |
我们可以使用 Apache Mod CGI 来 bypass,图省事直接用蚁剑插件。。这里挖个坑,过段时间没事干了去研究下 bypass disable_functions 的原理。。翻找文章的时候发现了 一篇文 感觉写的还可以。


WEB4 - LightCMS 0day
LightCMS 是基于 Laravel 框架的一个CMS。目前的最新版 v1.3.7 基于 Laravel 6.x 开发,PHP>=7.2。
挖掘思路:
- 搜索得到 LightCMS 的历史漏洞 RCE in “catchImage”‘ (CVE-2021-27112)
- 得知LightCMS可以上传远程文件
- 若 解析远程文件时存在文件函数,PHP<8 可触发 phar 反序列化
- 在 phpggc 中有 Laravel 6.x 的链子
按着这个思路,我们重点调试上传远程文件时的代码即可。(这些都是后面看了wp才得出的结论==,当时根本没有想到 Phar反序列化和 文件上传结合起来。。。果然还是太菜了)
补充点 Laravel 的知识
由于之前没怎么摸过 Laravel,这里提一点 Laravel的基本知识,有助于理解这个漏洞
路由、控制器
路由文件位置: /routes
控制器文件位置:**/app/Http/Controllers**
/app/Http 目录结构:

路由
路由文件会被 App\Providers\RouteServiceProvider
自动加载。可以在该文件中添加路由文件。格式如下:
1 | public function map() |
知道了有哪些路由文件被加载后,我们直接看对应的路由文件 (routes/admin.php
),格式如下:
1 | Route::group( |
综上可知发送 POST格式的 admin/neditor/serve/xxx
会被路由到 /app/Http/Controllers/Admin/NEditorController.php
的serve()
方法。这个php文件就是开发者自己写的处理业务逻辑的文件了
查看 serve()
方法
1 | //这里的 $type 对应路由中定义的参数 {type} |
漏洞逻辑
根据 CVE-2021-27112 的漏洞点,定位到 NEditorController.php
的 catchImage()
1 | public function catchImage(Request $request) |
跟进 fetchImageFile()
方法。该方法可简化成如下代码:
1 | protected function fetchImageFile($url) |
Image 是一个 Facade。具体的 Facade逻辑可以暂时不用理会,只需知道 Facade 的 __callStatic()
有一段代码 $instance->$method(...$args);
即可。
Image::make()
最终调用了 Intervention\Image\ImageManager make()
方法
1 | Intervention\Image\ImageManager |
这个switch派生了这个漏洞需要利用的两个分支:phar反序列化的点 及 上传phar文件的点。
phar反序列化
进入 case $this->isUrl()
分支,跟进 $this->initFromUrl()
1 | public function initFromUrl($url) |
上传phar文件
进入 case $this->isBinary()
分支,跟进 $this->initFromBinary()
1 | public function initFromBinary($binary) |
综上分析,我们可以得出这样一个利用链:首先上传一个文件头是图片类型的phar文件,phar文件内容为 phpggc 中laravel6.x的反序列化链。获取到phar文件上传路径后,然后再上传一个“URL文件”,内容为phar路径的文件。即可触发phar反序列化
POC编写
按照正常逻辑,我们的POC如下:
1 |
|
使用 xxd 查看文件结构:

请求如下:

然后。。。就报错了。。。由于下载远程图片时使用了 imagecreatefromstring()
。而我们的 phar.jpg 不是一个正规的图片,导致该方法无法正常生成图片,遂报错。。。

解决办法也挺简单,只需要在文件中存在有 <?php __HALT_COMPILER(); ?>
即可。哪怕它位于文件的末尾也是可行的。
1 | ...... |
程序成功返回上传文件路径:

根据文件路径构造 “URL文件” 的内容:

此时再次请求,成功执行命令:
