CVE-2024-27956: SQLi in WP Automatic Plugin
Shut up, be better
Overview
Hi mình viết về 1day để có 0day hihi.
WP Automatic là một plugin WordPress, cho phép tự động thu thập và đăng tải nội dung từ nhiều nguồn khác nhau lên trang web của bạn. Plugin này hỗ trợ nhập nội dung như văn bản, hình ảnh, video và sản phẩm từ các trang web và xuất bản chúng thông qua một giao diện thống nhất.
Lỗ hổng SQL Injection (SQLi) tồn tại trong plugin WP-Automatic cho WordPress, ảnh hưởng đến các phiên bản từ n/a đến 3.92.0. Do việc lọc đầu vào không đầy đủ, kẻ tấn công chưa xác thực có thể chèn các lệnh SQL độc hại vào cơ sở dữ liệu của trang web, dẫn đến việc truy cập trái phép hoặc chiếm quyền điều khiển trang web.
Affected Software
Plugin: WP-Automatic Plugin for WordPress
Active Installations: Over 38.000 worldwide
Affected Assets: WP-Automatic <= 3.92.0
Classification: SQL Injection ( SQLi )
CVSS Score: 9.8 ( Critical )
Technical Analysis
Nhờ đọc các Blog ta biết được lỗ hổng có sink nằm ở file /wp-automatic/inc/csv.php
File này là một endpoint trực tiếp và được truy cập thông qua HTTP POST request, ta thấy ở dòng từ 17 → 19 nhận các tham số $_POST['q'] , $_POST['auth'] , $_POST['integ'] từ người dùng.

Khi gửi request tham số $q không được sanitize từ đó dẫn tới attacker có thể chèn Untrusted Data vào tham số này.
Ở dòng 38 → Plugin sử dụng SQL Query với tham số $q do người dùng hoàn toàn kiểm soát.

Sau đó từ dùng 21 → 35 lần lượt là các đoạn code dùng if để check giá trị $auth và $integ:

Ta thấy các câu điều kiện đều sử dụng func wp_automatic_trim() hàm này được định nghĩa ở file wordpress_data\wp-content\plugins\wp-automatic\wp-automatic.php ⇒ Trace thử xem hàm này dùng để làm gì ??
Hàm wp_automatic_trim($str) là một function kiểm tra nếu input là null thì trả về chuỗi rỗng '', ngược lại thì gọi hàm trim() của PHP để loại bỏ khoảng trắng ở đầu và cuối chuỗi input.
Phân tích từng câu điều kiện:
Câu điều kiện nãy đã check sai. Giả sử $auth = " " khi đó $auth == '' =false ⇒ Ta có wp_automatic_trim(false)="" khi đó if sẽ có dạng if(""){}, Trong PHP chuỗi rỗng được đánh giá là false khi được dùng trong biểu thức điều kiện ⇒ Từ đó khi ta truyền vào khoảng trắng có thể bypass qua dòng if trên. ⇒ Hơi ảo ;c
Code check dữ kiện đúng sẽ như này:
Qua với câu điều kiện thứ 2 câu điều kiện này dùng để so sánh giá trị $auth được gửi và password của user hiện tại ⇒ Tuy nhiên nếu ta access endpoint này bằng unauthenticated user khi đó $current_user->user_pass="" ⇒ Bypass được nốt
Tới câu điều kiện cuối cùng ⇒ điều kiện check giá trị của $integ ở với MD5 hash của Query nối chuỗi với User Pass ⇒ Ở đây User Pass bằng rỗng nên ta chỉ cần Hash MD5 câu Query là Bypass OKE.
Do csv.php chỉ là một endpoint thực hiện function nên chắc chắn phải có file nào đó include hoặc gọi đến file csv.php để xuất dữ liệu dưới dạng CSV.
Dùng regex để tìm kiếm thì ta thấy wordpress_data\wp-content\plugins\wp-automatic\p_log.php có gọi đến csv.php ⇒ Check chức năng lưu trữ log trên Plugin trên:

⇒ Tìm thấy được nơi thực thi csv.php ⇒ Này tìm cho vui thôi chứ gửi thẳng Request đến <HOST>/wp-content/plugins/wp-automatic/inc/csv.php ⇒ Với các tham số thiết lập sẵn là Exploit được rồi.

Exploit Time
Bước 1: Viết Exploit Code lợi dụng lỗ hổng SQLi để tạo thêm 1 User có quyền Administrator
Bước 2: Run exploit code

Bước 3: Đăng nhập bằng user vừa tạo ⇒ Đăng nhập thành công

Bước 4: Check Role User được tạo ⇒ Administrator

Note: Bản thân mình vẫn thấy Exploit Code này chưa hoàn hảo ở 2 điểm đó là mình chưa tạo được User từ Input của Exploit mà phải set sẵn. Và vẫn chưa handler được error nếu không khai khác được. Mong Exploit Code lần sau có thể tốt hơn nữa.
Referrer
Last updated
