Phân tích CVE-2025-59489: Lỗ hổng trong Unity Runtime cho phép chiếm quyền ứng dụng Android qua Intent

Trong khuôn khổ sự kiện Meta Bug Bounty Researcher Conference, một nhà nghiên cứu bảo mật đã phát hiện và công bố một lỗ hổng nghiêm trọng trong Unity Runtime, được định danh là CVE-2025-59489. Lỗ hổng này ảnh hưởng đến một loạt các game và ứng dụng được xây dựng trên Unity phiên bản 2017.1 trở về sau, đặc biệt nguy hiểm trên nền tảng Android.

96f5ccbc-34d6-4280-9afc-2d4f93c3e60c

Vấn đề này sau đó đã được báo cáo cho đội ngũ Unity. Phía Unity cũng đã nhanh chóng hành động bằng cách phát hành các bản vá lỗi.

Cơ chế xử lý Intent của Unity trên Android

Để phục vụ cho mục đích debugging, Unity cung cấp một cơ chế cho phép các nhà phát triển command-line arguments vào ứng dụng khi nó khởi chạy. Điều này được thực hiện thông qua một Intent của Android chứa một extra đặc biệt tên là unity.

UnityPlayerActivity, vốn là activity mặc định cho hầu hết các ứng dụng Unity, được thiết lập là exported. Điều này có nghĩa là bất kỳ ứng dụng nào khác trên cùng thiết bị cũng có thể gửi Intent đến nó.

Một lệnh adb minh họa cho tính năng này:

# Lệnh ADB để khởi chạy một game Unity với tham số dòng lệnh tùy chỉnh
adb shell am start -n "com.devteam.awesomegame/com.unity3d.player.UnityPlayerActivity" \
  -e unity "-force-glcore"

Mặc dù hữu ích cho việc debug, cơ chế này lại vô tình mở ra một bề mặt tấn công: nếu một ứng dụng độc hại có thể kiểm soát nội dung của extra, nó có thể điều khiển các tham số khởi động của ứng dụng mục tiêu.

Tham số xrsdk-pre-init-library

Trong quá trình phân tích sâu vào file binary của Unity Runtime, nhà nghiên cứu đã phát hiện ra một tham số dòng lệnh đặc biệt là -xrsdk-pre-init-library.

Khi Unity Runtime xử lý tham số này, giá trị đi kèm với nó là một đường dẫn file sẽ được truyền trực tiếp vào hàm dlopen().

// Đoạn code minh họa logic của Unity Runtime
char* libraryPath = get_command_line_argument_value("-xrsdk-pre-init-library");
if (libraryPath != NULL) {
    void* handle = dlopen(libraryPath, RTLD_LAZY); // Lỗ hổng nằm ở đây
}

dlopen() là một hàm hệ thống trên các hệ điều hành dựa trên Linux (bao gồm Android) dùng để dynamically load một shared library, file .so. Khi một thư viện được nạp, mã khởi tạo của nó sẽ được thực thi ngay lập tức.

Sự kết hợp của hai yếu tố trên tạo ra một lỗ hổng có thể Arbitrary Code Execution:

  1. Bất kỳ ứng dụng nào cũng có thể gửi Intent để kiểm soát tham số dòng lệnh.
  2. Một tham số dòng lệnh cho phép nạp và thực thi một file .so bất kỳ.

Kẻ tấn công có thể khai thác điều này để buộc ứng dụng Unity phải import một thư viện độc hại, qua đó thực thi mã với toàn bộ quyền hạn mà ứng dụng đó đang có.

Các loại tấn công

  1. Tấn công Local

Đây là kiểu đơn giản và trực tiếp nhất. Một ứng dụng độc hại được cài đặt trên cùng thiết bị có thể:

  1. Chứa một file thư viện độc hại (ví dụ: payload.so).
  2. Tạo và gửi một Intent đến ứng dụng Unity mục tiêu.
  3. Trong Intent, nó chèn extra unity với giá trị là -xrsdk-pre-init-library /data/data/com.malicious.app/files/payload.so.

Ngay khi ứng dụng Unity khởi chạy, nó sẽ nạp và thực thi file payload.so, và mã độc sẽ chạy với quyền của ứng dụng Unity.

  1. Tấn công qua Browser

Kiểu này phức tạp hơn và đòi hỏi một số điều kiện nhất định. Nếu một ứng dụng Unity khai báo UnityPlayerActivity với category là android.intent.category.BROWSABLE, nó có thể được khởi chạy từ một liên kết trên trình duyệt web.

Kẻ tấn công có thể tạo một trang web chứa một URL với định dạng intent:// đặc biệt để khai thác:

<a href="#Intent;scheme=gameprotocol;package=com.target.gameapp;S.unity=-xrsdk-pre-init-library%20/data/data/com.target.gameapp/cache/payload.dat;end;">
  Click here for a free reward!
</a>

Tuy nhiên, có một rào cản lớn đó là chính sách SELinux nghiêm ngặt của Android. SELinux ngăn chặn hàm dlopen() truy cập vào các thư mục công cộng như /sdcard/Download/. Điều này có nghĩa là kể cả khi trình duyệt tải về một file .so độc hại, ứng dụng Unity cũng không thể nạp nó từ thư mục Download.

Nhật ký hệ thống sẽ hiển thị lỗi tương tự như sau:

E/linker: library "/storage/emulated/0/Download/evil.so" is not accessible for the namespace... permitted_paths="/data:/mnt/expand:/data/data/com.target.gameapp"

Mặc dù vậy, có một cách để vượt qua. Như trong log ở trên, đường dẫn permitted_paths vẫn bao gồm thư mục dữ liệu riêng của ứng dụng (/data/data/com.target.gameapp). Nếu kẻ tấn công tìm ra một cách khác để ghi một file với nội dung tùy ý vào thư mục này (ví dụ, thông qua một lỗ hổng cache poisoning hoặc một tính năng cho phép lưu file từ web), chúng vẫn có thể thực hiện cuộc tấn công này. dlopen() không yêu cầu file phải có đuôi .so, nên bất kỳ file nào chứa mã thực thi hợp lệ đều có thể dùng để tấn công.

Hành động khắc phục và khuyến nghị

Unity đã phát hành các bản vá cho tất cả các phiên bản bị ảnh hưởng từ 2019.1 trở đi và một công cụ Unity Application Patcher.

Cộng đồng nhà phát triển được khuyến nghị thực hiện các bước sau:

  1. Cập nhật Unity Editor: Tải về phiên bản Unity mới nhất cho dòng sản phẩm của bạn (ví dụ: 2022.3.x LTS, 2023.2.x…).
  2. Build lại dự án: Mở dự án của bạn và build lại toàn bộ các phiên bản cho Android.
  3. Phát hành lại: Đăng tải phiên bản đã được build lại lên Google Play Store và các kênh phân phối khác càng sớm càng tốt.

CVE-2025-59489 là một lời nhắc nhở rõ ràng rằng các lỗ hổng có thể tồn tại ngay trong chính những framework và thư viện nền tảng mà chúng ta tin tưởng. Việc một tính năng được thiết kế cho mục đích debug có thể trở thành một kiểu tấn công nghiêm trọng cho thấy tầm quan trọng của việc xem xét các hàm ý bảo mật trong mọi khía cạnh của phát triển phần mềm.

Việc Unity nhanh chóng đưa ra bản vá là một tín hiệu tích cực, nhưng trách nhiệm cuối cùng vẫn thuộc về các nhà phát triển trong việc cập nhật và bảo vệ sản phẩm cũng như người dùng của mình.

Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận