[CVE 2021-36394] – Hack trường, sửa điểm, các kiểu (có POC)

I. Mở bài

Trong một lần coi livestream định hướng của CyberJutsu, mình tình cờ thấy được demo cho cái bug này. Nhớ lại trong scope mình handle cũng không ít site sử dụng moodle. Nên thử reproduce.

II. Hướng dẫn cài đặt

Mình sử dụng version 3.9.7 để làm POC.

Link Download: https://download.moodle.org/download.php/stable39/moodle-3.9.7.tgz

Sau khi cài đặt xong, vào Site administration -> Plugins -> Authentication -> Manager Authentication

Sau đó active plugins shibboleth

II. Phân tích Lỗi

Bài này phân tích khá chi tiết: https://buaq.net/go-81019.html. Nên mình chỉ tóm tắt lại

Vị trí lỗi nằm ở file /auth/shibboleth/classes/helper.php

Khi thực thi hàm logout_file_session, server sẽ chạy 1 vòng lặp để unserialize tất cả session trong thư mục /moodledata/sessions/ để tìm ra cái shibboleth_session_id. Sau đó mới so sánh với spsessionid hiện tại – Một pha xử lý khá cồng kềnh.

Khi thực thi hàm unserializesession, đoạn code tạo một preg_split với patern (\w+)\| để cắt chuỗi, như vậy nếu control được session và chèn (\w+)\| vào thì có thể tách chuỗi ra để unserialize được.

    $a = preg_split("/(\w+)\|/", $serializedstring, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

Sử dụng regex tìm kiếm với file chứa cả 2 chuỗi patern \$SESSION.->.= và (optional_param\(|required_param\(), sau đó phân tích dữ liệu tìm được, có thể tìm ra /grade/report/grader/index.php chứa đoạn code mà user có thể control.

Đoạn code này có thể control được SESSION input thông qua chèn sifirst hoặc silast mà không cần Authen.

Từ đó rút ra được các bước khai thác như sau:

III. Exploit

1. Các bước khai thác

S1: Requests tới /grade/report/grader/index.php và chèn payload vào param sifirst hoặc silast với 1 MoodleSession hợp lệ.

Payload sẽ có dạng (\w+)\|input_payload_SERIALIZE_here(\w+)\|

S2: Gọi hàm logout_file_session bằng cách Request WSDL tới /auth/shibboleth/logout.php để trigger đoạn code

2. Gadget

** Một vài nhận xét:

  • Trong đoạn code thực thi logout_file_session không có thao tác ngầm ép kiểu String nên First Link không thể là một class chứa __toString, một số chain trên mạng sẽ không work. First Link sẽ là class chứa __destruct.
  • Để đa dạng hoá gadget chain, có thể tìm first link ép kiểu String.
  • Default Moodle sẽ gọi được các class trong /*/classes/*. Do đó first link sẽ nằm trong /*/classes/*.
  • Có thể gọi những class ngoài /*/classes/* bằng cách gọi một class khác có chứa hàm include(_once), require(_once), class đó.

** First Link: Sử dụng search __destruct với */classes/* sẽ tìm ra ứng cử viên cho First Link.

Sau khi đọc code 3 hàm này thì link duy nhất \core\lock\lock() có khả năng ứng cử vì sử dụng ép kiểu string thông qua cộng chuỗi.

** Next Link:

Tới đây chỉ cần $this->caller trỏ tới Next Link, mình có thể gọi 1 class khác chứa chain __toString()

Với 136 kết quả sẽ làm đa dạng hoá gadget chain.

Bài này có sử dụng 1 gadget chain đổi password admin, mình đem về modify lại trong context này.

Moodle – Remote Code Execution

Để khai thác chain này, có 2 vấn đề, thứ nhất __toString() không được gọi, vấn đề này đã được giải quyết, vấn đề thứ hai, các class \grade_grade \grade_item sẽ không gọi được do không nằm trong */classes/*.

Để xử lý bài toán này, mình sẽ gọi 1 class khác chứa hàm include class này.

/lib/grade/grade_grade.php <- /lib/gradelib.php <- /analytics/classes/course.php <- \core_analytics\course

-> Gọi class \core_analytics\course sẽ include file /lib/grade/grade_grade.php, sau đó có thể gọi được class \grade_grade

/lib/grade/grade_item.php <- /lib/gradelib.php <- /analytics/classes/course.php <- \core_analytics\course

-> Gọi class \core_analytics\course sẽ include file /lib/grade/grade_item.php, sau đó có thể gọi được class \grade_item

Ngoài ra có 1 chain khác khai thác dễ dàng hơn, link mình để phần POC

3. POC

https://github.com/dinhbaouit/CVE-2021-36394

VIdeo Tutorial Step by Step:

IV. Kết bài

Cơ bản lỗi này sẽ chỉ ảnh hưởng tới những site enable shibboleth plugin, sau khi đi săn mình thấy đa số trường Đại Học ở VN không enable plugin này. Lỗi này nói chung là có điều kiện cần và impact integrity khá gắt nên khả năng khai thác thực tế khá rủi ro.

Tuy nhiên cũng không nên chủ quan, vì còn nhiều chain khác cũng có thể khai thác mà không cần đổi password admin. Ví dụ

V. References:

https://buaq.net/go-81019.html

https://moodle.org/mod/forum/discuss.php?d=424799

Moodle – Remote Code Execution

Bình luận về bài viết này