Khai thác lỗ hổng RCE trong Yii Framework thông qua unserialize
Giới thiệu về CVE-2020-15148
Lỗ hổng CVE-2020-15148 xuất hiện trong các phiên bản Yii Framework trước 2.0.38. Lỗi này gây ra nguy cơ Remote Code Execution (RCE) khi hàm unserialize
được sử dụng để xử lý dữ liệu đầu vào từ người dùng mà không có bất kỳ kiểm tra nào.
Những điều cơ bản về serialize và unserialize
Trong lập trình, serialize
và unserialize
là hai phương thức quan trọng giúp chuyển đổi đối tượng thành chuỗi dữ liệu có thể lưu trữ và hồi phục lại sau này. Trong PHP, các hàm serialize
và unserialize
cho phép chúng ta thực hiện điều này dễ dàng. Dưới đây là một ví dụ đơn giản:
php
// Ví dụ về serialize và unserialize
$object = new MyClass();
$serialized = serialize($object);
$unserialized = unserialize($serialized);
Giới thiệu về cơ chế autoload trong PHP
PHP cung cấp cơ chế tự động tải (autoload) để giúp lập trình viên quản lý các lớp trong ứng dụng của họ mà không cần phải include từng file một cách thủ công. Hàm spl_autoload_register
cho phép chúng ta đăng ký các hàm autoload, từ đó PHP sẽ tự động tải lớp khi cần. Điều này rất thuận tiện trong việc làm giảm số lượng mã phải viết và quản lý.
Ví dụ về spl_autoload_register:
php
spl_autoload_register(function ($className) {
include $className . '.php';
});
Tổng quan về các magic method trong PHP
Trong PHP, có nhiều magic method, là các phương thức được gọi trong những tình huống đặc biệt. Ví dụ, __construct
được gọi khi khởi tạo một đối tượng mới, còn __destruct
được gọi khi đối tượng bị hủy. Điều này có thể hữu ích trong việc xây dựng các chuỗi khai thác.
Phân tích lỗ hổng CVE-2020-15148
Bắt đầu từ quá trình cài đặt framework Yii, phiên bản bị ảnh hưởng là 2.0.37. Khi phân tích mã nguồn trên GitHub, thấy rằng lỗi nằm ở class BatchQueryResult
.
Để kích hoạt hàm unserialize
tạo ra class BatchQueryResult
, chúng ta cần hiểu rằng Yii sử dụng tính năng autoload, cho phép gọi một class chưa được load. Từ controller, chúng ta có thể gọi đến class đó và kích hoạt hàm __destruct
, liên quan đến việc gọi đến hàm reset
, từ đó mở ra nhiều hướng khai thác khác nhau.
Khi xem xét hàm close
trong biến _dataReader
, có thể khai thác các phương thức magic như __call
để lần ra hàm thực thi lệnh dẫn đến RCE. Bằng cách tìm kiếm trong mã nguồn, phát hiện được nhiều lớp khác nhau có thể dẫn đến việc gọi các hàm nguy hiểm như system
, eval
, hoặc call_user_func
.
Việc vá lỗi lỗ hổng
Theo bản cập nhật, class BatchQueryResult.php
đã được sửa đổi với hàm __wakeup
ném ra một exception để ngăn chặn việc unserialize
. Tuy nhiên, vẫn có khả năng tìm ra nhiều đầu vào khác để khai thác lỗ hổng này.
Kết luận
Việc khai thác lỗ hổng qua PHP object injection luôn thách thức với nhiều chuỗi khai thác khác nhau. After một ngày phân tích, tôi đã tích lũy được nhiều kiến thức quý giá về lỗ hổng này. Tầm quan trọng của việc bảo mật và xử lý input an toàn là điều không thể thiếu trong các ứng dụng web hiện đại.
source: viblo