Post

CVE-2025-47812, attack chain và các chiến thuật tấn công mình tự bịa

CVE-2025-47812, attack chain và các chiến thuật tấn công mình tự bịa

Mở đầu

Khá lâu rồi mình mới lên một bài blog kĩ thuật, đây là quá trình tự mình nghiên cứu đồng thời học hỏi và tiếp thu kiến thức của đàn anh trong khoảng thời gian vừa rồi. Bài viết sẽ là cách chain CVE-2025-47812 với kĩ thuật Pre OS Booting giúp cho attacker sau khi khai thác thành công sẽ stealth trên máy nạn nhân. Mặc dù vẫn còn nhiều hạn chế trong việc khiến người dùng (ở đây là server) trigger file độc hại nhưng vẫn sẽ là một cách để mọi người mở rộng kiến thức. malware here

Thân bài

Tổng quan

Wing FTP Server là một phần mềm máy chủ chạy trên nhiều nền tảng hệ điều hành khác nhau: Linux, Window, MacOS được phát triển để truyền file với nhiều protocols như: FTP, SSH, SFTP, HTTP, HTTPS,… Phần mềm này được sử dụng rộng rãi trong các doanh nghiệp, trong mạng nội bộ lẫn bên ngoài Internet.

banner

Ngày 30/06/2025, bài viết về lỗ hổng này được công bố và chỉ 1 ngày sau đó đã ghi nhận cuộc tấn bởi huntress. Thông tin về lỗi được mô tả như sau:

banner Các điểm cần lưu ý

  • CVE này có điểm CVSS là 10.0: Đây là điểm rất cao vì bề mặt tấn công và độ phức tạp rất dễ để khai thác và không yêu cầu bất kì tương tác nào của người dùng
  • CVE xảy ra trên máy chủ Wing FTP Server trước bản 7.4.4: Từ bản 7.4.3 trở xuống đã có thể bị tấn công
  • Lỗ hổng xảy ra trong quá trình xử lý nullbyte tại giao diện đăng nhập của admin và user cho phép RCE
  • Lỗ hổng còn cho phép leo thang đặc quyền (Administrator với Windows, root với Linux, mình chưa test trên MacOS) do chạy mặc định với quyền cao.
  • Vẫn cần tài khoản người dùng nhưng nếu có người dùng anonymous, cuộc tấn công sẽ xảy ra ở dạng Unauthenticated,

    Phân tích kĩ thuật

1. Dựng môi trường phân tích

Dựa vào những dữ kiện đã biết, thiết lập lab sẽ gồm.

Sau khi cài đặt xong thì tạo 1 user là anonymous banner

2. Phân tích lỗ hổng

Quan sát hành vi thấy rằng khi người dùng đăng nhập sẽ tạo 1 yêu cầu POST với các tham số username=&password= tại endpoint /loginok.html. Người dùng đăng nhập thành công thì server sẽ sinh ra cookie với UID là một chuỗi ngẫu nhiên và tạo 1 file với filename là .lua tại folder session.

banner banner

Mình sẽ kiểm tra trong file loginok.html này nó đang làm gì. Dòng 16-20 sẽ nhận input của mình nhập vào bởi tham số tương ứng qua các phương thức GET/POST, sau khi nhận sẽ đến dòng 35 sẽ check tài khoản có hợp lệ không.

banner

Nếu tài khoản hợp lệ nó tiếp tục thực hiện và đi xuống dòng 64 để set vào table _SESSION với key là username và value là input được người dùng nhập. Tại đây có thể thấy input người dùng đã được truyền trực tiếp vào _SESSION mà không có biện pháp filter hay validate nào cả. Tiếp theo là đến dòng 76 và gọi SessionModule.save() với đối số là _SESSION_ID

banner

Đi vào file SessionModule.lua, ta thấy hàm save(id) nhận giá trị là UID được tạo, nó sẽ dùng UID để tạo 1 file là .lua trong folder Session và gọi hàm serialize() với tham số là SESSION do ta kiểm soát và một hàm write để ghi vào file .lua

banner

Tại hàm serialize() ta thấy nó đang lọc qua từng key và value và ghi vào file bằng cách cộng chuỗi. Chúng ta có thể kiểm soát được nội dung trong SESSION thì hoàn toàn có thể ghi vào file này

banner

Luồng thực thi mình sẽ tóm tắt như sau: username qua methods GET hoặc POST -> hàm c_CheckUser() kiểm tra thông tin -> rawset() -> SessionModule.save() -> serialize()

Tuy nhiên lỗi này xảy ra do quá trình xử lý nullbyte không đúng, server sẽ chỉ check phần trước nullbyte tại tham số username, và nếu tài khoản hợp lệ thì sẽ ghi toàn bộ username có chứa cả nullbyte vào .lua `phân tích binary sẽ lên sau`. Vậy là ta đã có thể ghi tùy ý phần nội dung phía sau vì khi này SESSION có chứa username do ta kiểm soát tức là file này cũng do ta kiểm soát

banner

Ghi file thành công nhưng để trigger file thì sao?? Câu trả lời là sau khi login thì dùng bất kì chức năng nào thì cũng có thể trigger được payload. Mỗi khi load sẽ gọi đến hàm runpage(), tiếp đến gọi đến init_session(), trong init_session() lại gọi đến SessionModule.load() và cuối cùng gọi đến loadfile() với tham số là file .lua do ta kiểm soát và thực thi tại dòng 108 f(). Mình để luồng hoạt động tại đây.

banner

Mình khai thác với tài khoản anonymous và kết quả như sau

banner

3. Diff patch và đánh giá patching

sẽ có bài phân tích sau

4. Scan Wing FTP Server public và đánh giá bảo mật banner

Tổng quan về Pre OS Booting

1. Pre OS Booting là gì

Pre OS Booting là quá trình tải các phần mềm hoặc thực hiện các thao tác trước khi hệ điều hành (OS) chính thức được nạp vào máy tính, điều này khiến cho mã độc hoàn toàn ẩn mình, tự do ghi mình vào những nơi khó ghi và còn có thể tránh được cả AntiVirus.

2. Native application

References

This post is licensed under CC BY 4.0 by the author.