Phân tích lỗi CVE-2014-3704 trên Drupal

ping

VIP Members
19/06/2013
57
101 bài viết
Phân tích lỗi CVE-2014-3704 trên Drupal
Tóm tắt - Giữa tháng 10/2014, một lỗi SQL injection nghiêm trọng trong core của CMS Drupal được công bố [1], đây là một trong 6 lỗi ở core dupal được phát hiện trong năm 2014 [2]. Trớ trêu ở chỗ, vị trí bị khai thác lại là lớp database abstraction chuyên xử lý truy vấn database. Lỗi này được đánh mã CVE-2014-3704 [3] và khuyến cáo an ninh SA-CORE-2014-005 [4]

Từ khóa: Information Security, Web, Drupal, CVE-2014-3704, SA-CORE-2014-005



1. Tổng quan về lỗi
Về cơ bản thì đây là một lỗi SQL Injection, một trong 6 lỗi được phát hiện ở core Drupal trong năm 2014 và được đánh giá ở mức Highly Critical (cực kỳ nguy hiểm) với Security risk: 25/25 [3] và điểm CVSS 7.5 [5].
Đối tượng ảnh hưởng: Drupal các phiên bản từ 7.x đến 7.31.
Rất nhanh chóng sau khi lỗi được công bố thì đã có bản vá chính thức, tuy nhiên mã khai thác cũng đã được tin tặc tung ra tràn lan và những website nào chưa kịp vá hoặc chưa update lên phiên bản mới hơn (7.32) đều có nguy cơ bị khai thác [6].

Nguy cơ khi bị khai thác?
Các mã khai thác mà tôi quan sát được đều cho phép tạo user với quyền admin, trên thực tế thì lỗi SQLi này cho phép tấn công Remote code execution, upload backdoor,...
Lưu ý là nếu đã bị tấn công thì update lên phiên bản mới sau đấy không có nghĩa là đã loại bỏ được backdoor bị gài vào.

2. Chi tiết lỗi
Drupal 7.x cung cấp một lớp database abstraction tên là DatabaseConnection để trừu tượng hóa truy vấn DB, chính xác là làm cho việc truy vấn được dễ dàng hơn. Lớp này nằm trong file /includes/database/database.inc

Lỗi SQLi lần này xuất phát từ phương thức expandArguments(&$query, &$args). Phương thức này nhận vào hai tham số là $query và $args, mục đích là mở rộng danh sách tham số trong $query.

DmXos.jpg


Một cách dễ hiểu như sau:

yvOKw.jpg


Nếu chúng ta truyền

PHP:
$query = "SELECT * FROM products WHERE id IN (pid)";
$args = [ 'pid' => [1, 2, 3,]];

Sau khi gọi phương thức expandArguments sẽ có các giá trị mới:

PHP:
$query = SELECT * FROM foo WHERE id IN (pid_0, pid_1, pid_2)
$args = ['pid_0' => 1, 'pid_1' => 2, 'pid_2' => 3]

Khai thác như thế nào?
Nếu gán giá trị như sau

PHP:
$args = [
    'pid' => [
        '0); DROP TABLE products; --' => 1
    ],
];

Sau lời gọi phương thức expandArguments(), ta sẽ có:
PHP:
$query = “SELECT * FROM products WHERE id IN (pid_0); DROP TABLE products; --”
Class DatabaseConnection sử dụng PDO để kết nối database nên lệnh kép sẽ được thực thi
==> Khai thác thành công

Mấu chốt

Chú ý vào expandArguments() thì nhận thấy thấy quy trình khai thác bao gồm việc truyền vào $args một mảng 2 chiều, qua vòng lặp foreach để lấy key-value

PHP:
    foreach (array_filter($args, 'is_array') as $key => $data) {

value sau lệnh này (biến $data) là mảng một chiều, tiếp tục qua một lần bóc tách key-value nữa:

PHP:
      foreach (($data) as $i => $value) {

Chính key sau lời gọi này (biến $i) là giá trị mà chúng ta điều khiển để inject

PHP:
        $new_keys[$key . '_' . $i] = $value;
        $query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query);

Vá lỗi như thế nào?
Security Team của Drupal đã rất nhanh chóng đưa ra bản vá cho lỗi này, và họ cũng chỉ cần thêm 14 ký tự vào code để vá :| [7]
Họ đã chuyển dòng lệnh

PHP:
      foreach (($data) as $i => $value) {
thành

PHP:
foreach (array_values($data) as $i => $value) {

Tại sao lại làm như vậy?

Như tôi đã giải thích ở trên, chúng ta chỉ khai thác được lỗi này khi điều khiển được giá trị key của mảng một chiều phía trong một mảng 2 chiều. Hàm array_values() đã vô hiệu hóa khả năng điều khiển giá trị key này.
Điều này có thể minh họa với đoạn code sau:

d6cmH.jpg


Kết quả thu được:

3Zd3A.jpg


Như vậy sau khi qua hàm array_values() thì toàn bộ key của mảng bị ép về giá trị tự tăng, tính từ 0. Nghĩa là điểm inject của chúng ta đã bị vô hiệu hóa :)

WhiteHat Contest 8 có một challenge áp dụng lỗi này, các bạn có thể chơi thử tại đây http://lab10.wargame.whitehat.vn/contests/8/web300_82b13c59d42e5c805b73b17b1c523aea/


3. Tài liệu tham khảo
[1] "WhiteHat," [Online]. Available: http://whitehat.vn/threads/8160-Dru...QL-Injection-nghiem-trong.html?highlight=3704.
[2] "WhiteHat," [Online]. Available: https://whitehat.vn/threads/9427-Tong-quan-ve-an-ninh-tren-CMS-Drupal.html?highlight=3704.
[3] "Mitre CVE," 2014. [Online]. Available: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3704.
[4] "Drupal," 2014. [Online]. Available: https://www.drupal.org/SA-CORE-2014-005.
[5] "Cvedetails," [Online]. Available: http://www.cvedetails.com/cve/CVE-2014-1475/.
[6] "Drupal," [Online]. Available: https://www.drupal.org/PSA-2014-003.
[7] "DrupalCode," 2014. [Online]. Available: http://cgit.drupalcode.org/drupal/commit/?id=19b32a3.
 
Chỉnh sửa lần cuối bởi người điều hành:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Bên trên