MAC OS
7.3.18
8.22.0
根据原文(https://www.ambionics.io/blog/laravel-debug-rce)的搭建方式,把服务开起来。
访问http://127.0.0.1:8000/
可以看到这时候Ignition
(Laravel 6+默认错误页面生成器)给我们提供了一个solutions,让我们在配置文件中给Laravel配置一个加密key。
点击按钮后会发送一个请求
通过这个请求Ignition
成功在配置文件中生成了一个key。
接着页面就可以正常访问了,环境也就搭建完了
漏洞其实就是发生在上面提到的Ignition
(<=2.5.1)中,Ignition
默认提供了以下几个solutions。
通过这些solutions,开发者可以通过点击按钮的方式,快速修复一些错误。
本次漏洞就是其中的vendor/facade/ignition/src/Solutions/MakeViewVariableOptionalSolution.php
过滤不严谨导致的。
首先我们到执行solution的控制器当中去,看看是如何调用到solution的
<?php namespace Facade\Ignition\Http\Controllers; use Facade\Ignition\Http\Requests\ExecuteSolutionRequest; use Facade\IgnitionContracts\SolutionProviderRepository; use Illuminate\Foundation\Validation\ValidatesRequests; class ExecuteSolutionController { use ValidatesRequests; public function __invoke( ExecuteSolutionRequest $request, SolutionProviderRepository $solutionProviderRepository ) { $solution = $request->getRunnableSolution(); $solution->run($request->get('parameters', [])); return response(''); } }
接着调用solution对象中的run()
方法,并将可控的parameters
参数传过去。通过这个点我们可以调用到MakeViewVariableOptionalSolution::run()
<?php namespace Facade\Ignition\Solutions; use Facade\IgnitionContracts\RunnableSolution; use Illuminate\Support\Facades\Blade; class MakeViewVariableOptionalSolution implements RunnableSolution { ... public function run(array $parameters = []) { $output = $this->makeOptional($parameters); if ($output !== false) { file_put_contents($parameters['viewFile'], $output); } } public function makeOptional(array $parameters = []) { $originalContents = file_get_contents($parameters['viewFile']); $newContents = str_replace('$'.$parameters['variableName'], '$'.$parameters['variableName']." ?? ''", $originalContents); $originalTokens = token_get_all(Blade::compileString($originalContents)); $newTokens = token_get_all(Blade::compileString($newContents)); $expectedTokens = $this->generateExpectedTokens($originalTokens, $parameters['variableName']); if ($expectedTokens !== $newTokens) { return false; } return $newContents;