Tháng 5 năm 2025 đánh dấu sự tiết lộ công khai về lỗ hổng bảo mật nghiêm trọng, CVE-2025-1974, được gọi là IngressNightmare, ảnh hưởng đến bộ điều khiển Kubernetes ingress-nginx được triển khai rộng rãi trên các cơ sở hạ tầng đám mây gốc. Lỗ hổng này cho phép những kẻ tấn công chưa xác thực đưa các cấu hình tùy ý vào NGINX, có khả năng dẫn đến RCE (thực thi mã từ xa) trái phép và xâm phạm toàn bộ cụm.
Là một phần của OPSWAT Chương trình học bổng, các thành viên của chúng tôi đã tiến hành phân tích kỹ thuật chuyên sâu để hiểu rõ hơn nguyên nhân gốc rễ, con đường khai thác và các chiến lược giảm thiểu liên quan đến vấn đề nghiêm trọng này.
Tổng quan về CVE-2025-1974
CVE-2025-1974 là lỗ hổng tiêm mẫu quan trọng được xác định trong các phiên bản ingress-nginx lên đến 1.11.4 và cụ thể là 1.12.0. Kẻ tấn công có quyền truy cập cấp độ nút vào cụm Kubernetes có thể khai thác lỗ hổng này để thực thi mã tùy ý bằng RCE thông qua bộ điều khiển ingress-nginx, theo mặc định, có các đặc quyền mở rộng, bao gồm quyền truy cập vào các bí mật quan trọng trong cụm.
Ủy ban ứng phó bảo mật Kubernetes đã đánh giá lỗ hổng này ở mức CVSS v3.1 là 9,8 (mức độ nghiêm trọng nghiêm trọng):
Các thành phần chính trong phân tích này
Tổng quan về Kubernetes
Kubernetes (K8s) là một nền tảng mã nguồn mở để tự động hóa việc triển khai, mở rộng quy mô và quản lý hoạt động của các ứng dụng được chứa trong container. Các cụm Kubernetes thường bao gồm nhiều máy, có thể bao gồm cả phần cứng vật lý và máy ảo, hoạt động cùng nhau để cung cấp môi trường ứng dụng có khả năng mở rộng, quản lý và sẵn sàng cao.
Bộ điều khiển NGINX Ingress
Bộ điều khiển ingress NGINX (ingress-nginx) là bộ điều khiển ingress mã nguồn mở được xây dựng trên máy chủ web NGINX. Nó hoạt động trong cụm Kubernetes, hoạt động chủ yếu như một proxy ngược và bộ cân bằng tải. Bộ điều khiển này diễn giải các tài nguyên Ingress do người dùng xác định và chuyển chúng thành các cấu hình NGINX có thể thực hiện được để định tuyến luồng lưu lượng vào và trong cụm.
AdmissionReview và vai trò của nó
Ingress-nginx tích hợp với Kubernetes bằng dịch vụ webhook có tên AdmissionReview. Dịch vụ này rất quan trọng để xử lý các đối tượng Kubernetes Ingress gốc và dịch chúng thành các cấu hình NGINX đã được xác thực và cú pháp chính xác. Trong khi AdmissionReview đảm bảo độ chính xác của cấu hình, nó hoạt động độc lập với bộ điều khiển ingress-nginx và thường thiếu các biện pháp kiểm soát xác thực nghiêm ngặt. Việc thiếu xác thực nghiêm ngặt này là một yếu tố chính góp phần vào khả năng khai thác CVE-2025-1974.
Khai thác lỗ hổng và phân tích kỹ thuật
Cơ chế khai thác
Về cơ bản, việc khai thác CVE-2025-1974 bắt đầu bằng một yêu cầu độc hại. Kẻ tấn công tạo một yêu cầu độc hại đến webhook AdmissionReview, buộc NGINX phải tải động một thư viện dùng chung khi chạy. Dựa trên cơ chế này, các cộng sự của chúng tôi đã phân tích cả webhook AdmissionReview và quy trình làm việc NGINX để hiểu đường dẫn khai thác này.
Lỗ hổng tiêm mẫu
Trên webhook AdmissionReview, khi xử lý các yêu cầu đến, hàm CheckIngress sẽ chuyển đổi Kubernetes Ingress Object thành các tệp cấu hình NGINX hợp lệ. Luồng tiến hành như sau:
- Mỗi cấu hình được phân tích cú pháp và chuyển đến generateTemplate để định dạng theo các mẫu NGINX được xác định trước.
- Sau đó, testTemplate xác thực cấu hình đã tạo so với tệp nhị phân NGINX cơ bản.
Tất cả cấu hình NGINX đều dựa trên các mẫu được xác định trước có trong tệp nginx.tmpl trong mã nguồn ingress-nginx:
Trong hàm generateTemplate , cấu hình được xử lý như trong đoạn mã sau:
Tuy nhiên, xác thực và vệ sinh đầu vào là không đủ. Cụ thể, trường uid từ Đối tượng Ingress được chèn trực tiếp vào mẫu cấu hình NGINX, tạo ra điểm tiêm. Kẻ tấn công có thể khai thác điều này bằng cách cung cấp đầu vào được tạo thủ công như uid="1234#;\n\n}\n}\n}\n injection_value" .
Đầu vào độc hại này cho phép đưa phạm vi toàn cục vào mẫu NGINX, cho phép kẻ tấn công kích hoạt các lệnh NGINX tùy ý và có khả năng đạt được RCE.
Từ Tiêm Mẫu đến Thực Thi Mã Từ Xa
Giải thích về hàm testTemplate()
Sau khi cấu hình NGINX được tạo bởi hàm generateTemplate , hàm testTemplate sẽ tạo một tệp cấu hình tạm thời và chạy thư viện NGINX bằng lệnh nginx -c {config_file} -t . Lệnh này sẽ buộc tệp nhị phân NGINX phân tích cú pháp và xác thực cấu hình.
Để khai thác lỗ hổng, kẻ tấn công cần xác định một chỉ thị có khả năng thực thi mã độc hại. Ban đầu, các cộng sự của chúng tôi xác định chỉ thị load_module có khả năng hữu ích, vì chỉ thị này cho phép NGINX tải các plugin bên ngoài. Tuy nhiên, chỉ thị này chỉ được phép trong giai đoạn đầu của quá trình phân tích cấu hình, không khớp với điểm tiêm của chúng tôi.
Để giải quyết thách thức này, chúng tôi đã tiếp tục nghiên cứu sâu hơn, dẫn đến chỉ thị ssl_engine , được mô tả là "Mô-đun có thể được OpenSSL tải động trong quá trình thử nghiệm cấu hình". Điều này gây tò mò vì khả năng tải động các mô-đun, đòi hỏi phải kiểm tra sâu hơn.
Hiểu về Chỉ thị ssl_engine
Để hiểu sâu hơn về cách NGINX xử lý chỉ thị ssl_engine , cũng như xác định các điều kiện mà NGINX cho phép tải động các mô-đun bổ sung thông qua chỉ thị này, chúng tôi đã xem xét mã nguồn NGINX.
Khi khởi động, NGINX tải trạng thái ban đầu của nó, sau đó phân tích từng dòng tệp cấu hình. Mỗi chỉ thị được xử lý bởi cấu trúc nginx_command_t , với chỉ thị ssl_engine trực tiếp gọi ngx_openssl_commands .
Sau khi phân tích hàm ngx_openssl_commands , các cộng sự của chúng tôi phát hiện ra rằng hàm này dựa vào hỗ trợ OpenSSL, cụ thể là hàm ENGINE_by_id được sử dụng cho các mô-đun SSL tăng tốc phần cứng.
Và trong khi phân tích hàm ENGINE_by_id , chúng tôi xác định rằng nó cho phép tải động các thư viện chia sẻ. Hơn nữa, nếu thư viện được biên dịch với phần mở rộng __attribute__((constructor)) , hàm liên quan có thể được thực thi ngay khi tải. Điều này chỉ ra rằng bằng cách khai thác chỉ thị ssl_engine , kẻ tấn công có thể tải các thư viện chia sẻ tùy ý trên máy chủ, có khả năng dẫn đến RCE.
Nhắm mục tiêu vào các thư viện chia sẻ và chiến lược tấn công
Để tạo điều kiện thực thi mã một cách đáng tin cậy, bước tiếp theo liên quan đến việc xác định một thư viện dùng chung. Thay vì dựa vào các thư viện bên ngoài, một cách tiếp cận khả thi và được kiểm soát hơn xuất hiện từ hành vi riêng của NGINX: cơ chế đệm thân máy khách. Tính năng này cho phép NGINX chuyển các yêu cầu lớn đến thành các tệp tạm thời, mở ra cơ hội khai thác dựa trên hành vi xử lý tệp có thể dự đoán được.
Theo mặc định, khi yêu cầu đến vượt quá 8KB, NGINX sẽ ghi nội dung yêu cầu vào tệp tạm thời nằm tại /tmp/nginx/client-body, sử dụng tên tệp theo định dạng cfg-{random_value}. Các tệp tạm thời này được lưu giữ trong tối đa 60 giây giữa các phần thành công của tin nhắn đã nhận.
Sau khi ghi một phần thân yêu cầu vào một tệp tạm thời, NGINX sẽ hoãn xóa cho đến khi nhận được toàn bộ thân yêu cầu. Nếu yêu cầu vẫn chưa hoàn tất và không nhận được dữ liệu trong tối đa 60 giây, tệp cuối cùng sẽ bị xóa. Tuy nhiên, bằng cách cố tình giữ lại phần dữ liệu cuối cùng, kẻ tấn công có thể giữ tệp tạm thời đang sử dụng, khiến nó có thể bị khai thác.
Mặc dù có thể kiểm soát được nội dung tệp đã tải lên, nhưng việc định vị tệp trên hệ thống tệp rất khó khăn do tên tệp được ngẫu nhiên hóa. Đường dẫn lưu trữ có thể được định cấu hình bằng client_body_temp_path , nhưng tên tệp được tạo ngẫu nhiên khi chạy, khiến nó trở nên không thể đoán trước. Tính ngẫu nhiên này cản trở đáng kể quyền truy cập có mục tiêu ngay cả khi sử dụng vũ lực. Để khắc phục điều này, nhóm đã tận dụng các hành vi vốn có của HĐH Linux. Hãy xem xét ví dụ sau:
This code opens a file and keeps it in an active state, closely mimicking the behavior of NGINX's client body buffer mechanism. Using /proc/{pid}/fd directory, attackers can find symbolic links created by the Linux kernel that map open file descriptors to their corresponding file paths. This route allows attackers to reduce the brute-force space to only two variables: the process ID (pid) and the file descriptor (fd).
Mô phỏng khai thác
Dựa trên phân tích trên, phương pháp khai thác thực tế cho RCE trong pod Ingress-NGINX là:
- Tải lên thư viện chia sẻ độc hại bằng cơ chế đệm thân máy khách của NGINX để lưu trữ tạm thời trên hệ thống tệp.
- Sử dụng template injection để khởi tạo một nỗ lực tấn công bằng vũ lực buộc NGINX tải thư viện chia sẻ đã tải lên trước đó thông qua các lệnh dễ bị tấn công.
Tạo Payload chứa Thư viện được chia sẻ
Để đảm bảo thực thi mã khi tải, một hàm entrypoint có phần mở rộng constructor được định nghĩa trong thư viện chia sẻ độc hại. Hàm này được thực thi khi tải bởi NGINX và được thiết kế để thiết lập kết nối shell ngược với máy chủ từ xa.
Sau khi biên dịch, kích thước của thư viện chia sẻ kết quả đã vượt quá 8KB, cho phép NGINX lưu vào bộ đệm mà không cần thêm phần đệm.
Sau đó, các cộng sự của chúng tôi đã tạo một yêu cầu với giá trị Content-Length được thổi phồng (ví dụ: 1MB) để tạo ra sự không khớp về kích thước. Điều này khiến NGINX đệm toàn bộ nội dung thay vì xử lý ngay lập tức, đảm bảo đối tượng được chia sẻ sẽ được ghi vào một vị trí có thể dự đoán được.
Kích hoạt Thư viện chia sẻ thông qua Injection
Với thư viện chia sẻ tại chỗ, chúng tôi tiếp tục tiêm một lệnh độc hại vào cấu hình NGINX bằng cách sử dụng trường uid dễ bị tấn công. Lệnh này bao gồm ssl_engine trỏ đến đường dẫn tệp được đệm:
RCE thành công yêu cầu chỉ thị ssl_engine tham chiếu đường dẫn chính xác đến tệp được đệm. Điều này có thể đạt được thông qua một tập lệnh brute force tự động lặp lại một cách có hệ thống các kết hợp có thể có của ID quy trình và mô tả tệp để xác định liên kết tượng trưng hợp lệ trỏ đến đối tượng được chia sẻ được đệm.
Dưới đây là mẫu NGINX được tạo ra đã kích hoạt lỗ hổng.
Sau khi khai thác thành công, kẻ tấn công có thể giành được quyền truy cập shell trong bối cảnh pod ingress-nginx, theo mặc định có quyền truy cập vào các bí mật cụm Kubernetes nhạy cảm.
Giảm thiểu và khắc phục
Để giảm thiểu hiệu quả các rủi ro liên quan đến CVE-2025-1974, các tổ chức cần có giải pháp cung cấp khả năng hiển thị và kiểm soát các thành phần nguồn mở của mình.
OPSWAT SBOM , một công nghệ nền tảng trong nền tảng MetaDefender® , giải quyết nhu cầu này bằng cách cung cấp danh mục tất cả các thành phần phần mềm, thư viện, vùng chứa Docker và các phụ thuộc đang sử dụng. Nó cho phép các tổ chức theo dõi, bảo mật và cập nhật các thành phần của họ một cách chủ động.
Trong ví dụ trên, công nghệ SBOM trong MetaDefender Core™ đã quét gói nginx-ingress-controller có chứa lỗ hổng CVE-2025-1974. Hệ thống tự động đánh dấu sự cố là Nghiêm trọng và cung cấp hướng dẫn về các phiên bản đã sửa có sẵn, cho phép các nhóm nhanh chóng ưu tiên và vá lỗ hổng trước khi có thể khai thác.
OPSWAT SBOM có sẵn trong MetaDefender Core Và MetaDefender Software Supply Chain™, cho phép các nhóm bảo mật xác định và hành động trên các lỗ hổng nhanh hơn . Với OPSWAT SBOM, các nhóm an ninh có thể:
- Xác định nhanh các thành phần dễ bị tấn công - Xác định ngay các thành phần nguồn mở bị ảnh hưởng bởi các cuộc tấn công deserialization. Điều này đảm bảo hành động nhanh chóng trong việc vá hoặc thay thế các thư viện dễ bị tấn công.
- Đảm bảo vá lỗi và cập nhật chủ động - Liên tục giám sát các thành phần nguồn mở thông qua OPSWAT SBOM sẽ đi trước các lỗ hổng giải tuần tự hóa. OPSWAT SBOM có thể phát hiện các thành phần lỗi thời hoặc không an toàn, cho phép cập nhật kịp thời và giảm nguy cơ bị tấn công.
- Duy trì sự tuân thủ và báo cáo – OPSWAT SBOM giúp các tổ chức đáp ứng các yêu cầu về tuân thủ khi khuôn khổ pháp lý ngày càng yêu cầu tính minh bạch trong chuỗi cung ứng phần mềm.