- vừa được xem lúc

Phân tích CVE-2023-23488 Paid Memberships Pro < 2.9.8 - Unauthenticated Blind SQLi và vấn đề với request trong Wordpress

0 0 29

Người đăng: Minh Tuấn Ngụy

Theo Viblo Asia

Xin chào mọi người, đã lâu rồi mình mới viết một bài phân tích CVE. Dạo gần đây xoay quanh nhiều chuyện 🍚👕🌾💸 nên ít thời gian để viết lách. Bài viết này là một cơ hội tình cờ để mình tìm kiếm lỗ hổng trên WordPress. Tuy nhiên, mình đã bỏ qua rất nhiều trường hợp, và mình muốn chia sẻ với các bạn về một lỗ hổng cụ thể.

CVE-2023-23488

CVE-2023-23488 được miêu tả rõ ràng tại đường link https://www.tenable.com/security/research/tra-2023-2. Đây là một lỗ hổng Unauth SQL injection ảnh hưởng đến plugin WordPress Paid Memberships Pro phiên bản < 2.9.8. Kẻ tấn công có thể gửi các truy vấn SQL tùy ý đến cơ sở dữ liệu của trang web thông qua tham số code của đường dẫn REST /pmpro/v1/order.

Để khai thác lỗ hổng này, có thể sử dụng payload TimeBased SQL Injection thông thường. Cách khai thác rất đơn giản như sau (không cần xác thực):

GET /?rest_route=/pmpro/v1/order&code=a%27%20OR%20(SELECT%201%20FROM%20(SELECT(SLEEP(1)))a)--%20- HTTP/1.1

Vậy tại sao lại dẫn tới lỗ hổng này, cài đặt và phân tích code plugin này theo version 2.9.7 có chứa lỗ hổng tại: https://downloads.wordpress.org/plugin/paid-memberships-pro.2.9.7.zip

Cực kỳ dễ dàng chúng ta có thể tìm thấy lỗ hổng được thấy ở đây. Sử dụng REST API của Wordpress được đăng ký theo router

nhảy vào function pmpro_rest_api_permissions_get_order với

GET /?rest_route=/pmpro/v1/order HTTP/1.1

Sau đó truyền thêm tham số code vào khởi tạo MemberOrder, nhảy trực tiếp đến __construct

Ở đây ta truyền giá trị code không phải là số sẽ nhảy sang function getMemberOrderByCode($id)

Tại đây giá trị code được truyền vào hoàn toàn không được filter hay escape gì, tại đây chúng ta có thể inject SQL vào đây theo kiểu TimeBased như PoC bên trên mình đã nêu. Mọi bước thực hiện đều không cần xác thực.

Nhưng điều kỳ lạ ở đây là mình hoàn toàn, thường xuyên gặp những đoạn code viết kiểu này trên Wordpress, mình thường xuyên bỏ qua những đoạn code này vì nó biến được ngăn cách bởi '" . $code . "'khi này Wordpress sẽ tự động thêm slash vào mỗi khi truyền ' hoặc " thành \' hoặc \" => không tấn công SQL Injection được do không thể bypass qua dấu ' hoặc "

Addslash tại Wordpress

Test thử với đoạn code sau

$code = $_GET['code'];
var_dump("SELECT id FROM $wpdb->pmpro_membership_orders WHERE code = '" . $code . "' LIMIT 1");
die();

Với response từ Wordpress

Chúng ta có thể thấy rằng giá trị $_GET['code'] đã tự động được thêm slash vào, từ đây chúng ta không thể nào break ra khỏi nháy đơn để thoát khỏi string. Từ đây mình luôn tưởng viết code theo kiểu bên trên là an toàn do mình không thể thoát khỏi nháy đơn!!

Sau một hồi hỏi ChatGPT, WordPress sẽ tự động xử lý và áp dụng addslashes() cho các giá trị này để đảm bảo rằng chúng an toàn khi được sử dụng trong các câu lệnh SQL hoặc các tình huống khác. Hàm được gọi lên ngay từ wp-setting.php

Với ghi chú rõ ràng rằng sử dụng để escape cho wpdb

Mình đã test thử thì với mọi $_GET, $_POST, $_COOKIE, $_SERVER khi truyền từ input người dùng thì đều sẽ bị thêm slash vào.

Tuy nhiên, tại sao khi sử dụng REST API thì Wordpress lại xoá mất dấu slash đi, điều này dẫn đến lỗ hổng CVE-2023-23488. Chúng ta có thể break ra khỏi dấu nháy đơn, inject câu lệnh SQL tuỳ ý.

Vậy tại sao lại như thế, Wordpress thêm slash xong rồi lại xoá slash đi là sao?? Lại đi hỏi ChatGPT thì hoá ra WordPress có sử dụng một cơ chế để loại bỏ dấu backslash \ được thêm vào khi sử dụng REST API.

Tại đây request được gửi tới REST API sẽ được load vào rest_api_loaded(), sau đó tiếp tục được handle tại WP_REST_Server::serve_request()

Và được unslash() tại đây

Thật vậy, thử var_dump($request) chúng ta được kết quả

Kết luận

Vậy mình đã bỏ qua kha khá nhiều lỗ hổng SQL Injection vì bỏ qua cách viết nối chuỗi này. Lúc nào mình cũng tin rằng không thể bypass được qua dấu nháy khi code dạng đó 😦. Với REST API của Wordpress thì hoàn toàn có thể.

Một số cách phòng tránh lỗ hổng SQL Injection khi sử dụng REST API trong WordPress, ví dụ:

  • Sử dụng esc_sql() filter input từ người dùng truyền vào
  • Sử dụng prepare() để truy vấn an toàn trong Wordpress
  • ...

Bình luận

Bài viết tương tự

- vừa được xem lúc

Linux Hardening and System Auditing (P1)

. Ngày nay, các hệ thống Linux được sử dụng trong suốt quá trình tính toán, từ các hệ thống nhúng đến hầu như tất cả các siêu máy tính, đồng thời đảm bảo một vị trí quan trọng trong các hệ thống máy chủ trên toàn thế giới. Linux đem lại cho người dùng khả năng tùy biến cao, sự ổn định và độ tin cậy

0 0 43

- vừa được xem lúc

Tìm bug với Eyewitness

. Chào các bạn, trong bài này mình sẽ viết về tool Eyewitness. Eyewiteness có tính năng chính là chụp hình lại giao diện trang web sau đó tạo một report thông qua file .

0 0 35

- vừa được xem lúc

Tôi đã debug code PHP như nào!

. Nhân dịp đầu xuân năm mới, mình xin gửi lời chúc an lành tới tất cả thành viên của viblo.asia.

0 0 57

- vừa được xem lúc

OAuth 2.0 và vài vấn đề bảo mật liên quan (Phần 2)

III. Demo một số tấn công vào cơ chế OAuth. Trong phần này mình sẽ demo một số kiểu tấn công của OAuth dựa trên các bài lab được thiết kế bởi Portswigger. a.

0 0 97

- vừa được xem lúc

OAuth 2.0 và vài vấn đề bảo mật liên quan (Phần 1)

Trong thời đại công nghệ ngày nay, việc đăng nhập bằng các tài khoản của các nền tảng khác không phải điều gì xa lạ đối với mỗi người dùng chúng ta. Việc này khả thi nhờ một vài cơ chế khác nhau, một trong số đó là OAuth 2.

0 0 50

- vừa được xem lúc

Hành trình pass OSCP trong lần thi đầu tiên (2020)

Vào một chiều đông 17/12/2020, tôi nhận được cái email thông báo đã pass OSCP ngay lần thử đầu tiên. Sau đó, tôi bắt đầu tìm hiểu về Security và quyết định học cái gì đó cho riêng mình.

0 0 195