Phân tích CVE-2018-7600

– Tác giả:

Drupal security team

– CVE link:

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-7600

– Dạng lỗi:

Remote Code Execution

– Sản phẩm dính đạn:

Drupal trước 7.58, 8.x trước 8.3.9, 8.4.x trước 8.4.6, và 8.5.x trước 8.5.1

– Tóm tắt lỗi:

Kẻ tấn công có thể gọi Drupal Form Api Ajax Request có chứa function call_user_func tự do

– Cụ thể:

Trong bài phân tích này mình xài drupal 8.3.8

Sơ lược về Drupal API:
– Được giới thiệu từ drupal 7
– Dùng để Rendering structured data thành HTML markup.
– Còn được gọi là Renderable Arrays, có dạng key-value. Key sẽ bắt đầu bằng dấu #
Ví dụ với element file:

Nhìn sơ qua thì cũng hiểu đại khái nó là gì rồi ha, tựa tựa tạo config giao diện trước vậy đó.

Trở lại với lỗi Drupalgeddon2, chúng ta tìm được các keys có sử dụng call_user_func#pre_render, #post_render, #access_callback, #submit, #lazy_builder, #validate

Trong bài này mình sẽ chọn #post_render
( ./core/lib/Drupal/Core/Render/Renderer.php )

Ok vậy nhiệm vụ của chúng ta bây giờ là tìm được cái param nào mà user submit lên có render, có thể thay đổi được key, và nhận key #post_render, để gọi thằng nó ra.


Khi ta upload 1 file, function này sẽ call API để resize hình lại, bắt request trong burpsuite, ta thấy:

Trong request ta thấy chương trình có gửi 1 biến element_parents theo phương thức GET với giá trị là user_picture/widget/0

luồng xử lý này nằm trong function uploadAjaxCallback./core/modules/file/src/Element/ManagedFile.php

line 176 $form_parents sẽ có giá trị là 1 array, var_dump ra xem thử:

array(3) {
  [0]=>
  string(12) "user_picture"
  [1]=>
  string(6) "widget"
  [2]=>
  string(1) "0"
}

nó sẽ lấy giá trị từ element_parents, tách ra theo dấu / thành array và gán vào $form_parents

line 179 gọi hàm getValue từ class NestedArray, vào đó xem:
(./core/lib/Drupal/Component/Utility/NestedArray.php)

&$array đưa vào function này là array của các element mặc định khi submit, chèn thử vô code debug nè:

line 72, 73 check:

ý chính đoạn này là xài $parent làm key path của array

$ref = &$ref[$parent]; lần đầu
=> $ref['user_picture']
$ref = &$ref[$parent]; lần 2
=> $ref['user_picture']['widget']
$ref = &$ref[$parent]; lần 3
=> $ref['user_picture']['widget'][0]

giả sử sửa giá trị của mail khi upload:

account/mail/#value là form element trỏ đến giá trị của mail

=> $ref[‘account’][‘mail’][#value]

$form sẽ trả về giá trị của biến mail nhập vào, debug:

sau đó thì $form sẽ được đưa vào function renderRoot

=> Render input ta control ^_^!

– Exploit:

Trở lại đoạn code ban đầu:

line 503 gọi hàm call_user_func:

vậy sửa cái mail cho phù hợp nữa thôi ^_^, PoC:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s