Lỗ hổng CVE-2026-42945 ẩn mình trong Nginx suốt 18 năm: phân tích toàn diện nguyên lý, PoC và giải pháp khắc phục

🚨 Lỗ hổng CVE-2026-42945 ẩn mình trong Nginx suốt 18 năm: nguyên lý, PoC và giải pháp khắc phục
Ngày 13/5/2026, tổ chức nghiên cứu bảo mật depthfirst phối hợp cùng F5 chính thức công bố lỗ hổng nghiêm trọng nhất trong lịch sử NGINX — CVE-2026-42945:
- Điểm CVSS v4.0 đạt 9.2: thuộc nhóm lỗ hổng nghiêm trọng
- Tràn bộ đệm trên heap: có thể dẫn tới thực thi mã từ xa (RCE)
- Ẩn mình suốt 18 năm: đã tồn tại trong mã nguồn từ năm 2008
- Ảnh hưởng tới 9,75 triệu trang web toàn cầu: hơn 2,54 triệu website tại Trung Quốc bị ảnh hưởng
- PoC đã được công khai: Qianxin đã tái hiện thành công
Đây là lỗ hổng mang tính lịch sử của mô-đun lõi NGINX, kẻ tấn công chỉ cần gửi một yêu cầu HTTP được chế tạo riêng là có thể chiếm quyền kiểm soát máy chủ từ xa.
🔍 Tổng quan về lỗ hổng
Thông tin cơ bản
| Thuộc tính lỗ hổng | Chi tiết |
|---|---|
| Mã lỗ hổng | CVE-2026-42945 |
| Điểm CVSS | v4.0: 9.2 | v3.1: 8.1 |
| Loại lỗ hổng | Tràn bộ đệm trên heap (Heap-based Buffer Overflow) |
| Loại mối đe dọa | Thực thi mã từ xa (RCE), từ chối dịch vụ (DoS) |
| Điều kiện khai thác | Không cần xác thực, chỉ cần dựng một yêu cầu HTTP |
| Thành phần bị ảnh hưởng | ngx_http_rewrite_module (mô-đun tích hợp sẵn trong lõi NGINX) |
| Đơn vị phát hiện | depthfirst (hệ thống tự động phát hiện trong vòng 6 giờ) |
Phạm vi ảnh hưởng
- 9,75 triệu trang web toàn cầubị ảnh hưởng
- 2,54 triệu website tại Trung Quốcbị ảnh hưởng
- NGINX đang vận hành khoảng 1/3 số website toàn thế giới, phạm vi ảnh hưởng cực rộng
- Đoạn mã được đưa vào từ năm 2008, ẩn mình suốt 18 năm
⚠️ Điều kiện kích hoạt
Ba điều kiện phải đồng thời thỏa mãn
Lỗ hổng được kích hoạt khi cấu hình thỏa mãn một tổ hợp điều kiện đặc biệt:
| Điều kiện | Mô tả | Ví dụ |
|---|---|---|
| 1. Captures PCRE không tên | Chỉ thị rewrite sử dụng nhóm bắt (capture) không tên | $1, $2, $3… |
| 2. Chuỗi thay thế chứa dấu hỏi | Chuỗi thay thế chứa ký tự ? | /profile.php?id=$1&tab=$2 |
| 3. Theo sau là rewrite/if/set | Ngay sau chỉ thị rewrite là các chỉ thị khác | rewrite … last; if (…) { … } |
Ví dụ cấu hình dễ bị tấn công
# 易受攻击配置
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;
# 后跟其他指令
if ($arg_debug) {
set $debug_flag 1;
}
Cấu hình này đồng thời thỏa mãn cả ba điều kiện:captures không tên $1/$2, chuỗi thay thế chứa ?, theo sau là chỉ thị if.
🔬 Nguyên lý của lỗ hổng
Sự không nhất quán trạng thái trong xử lý hai giai đoạn
Công cụ kịch bản (script engine) của NGINX sử dụng xử lý hai giai đoạn:
- Giai đoạn một: tính toán kích thước bộ đệm cần thiết
- Giai đoạn hai: sao chép dữ liệu vào bộ đệm
Trái tim của lỗ hổng nằm ở quản lý sai cờ is_args:
| Giai đoạn | Trạng thái is_args | Logic xử lý | Kết quả |
|---|---|---|---|
| Giai đoạn tính độ dài | is_args = 0 | Trả về độ dài capture gốc | Đánh giá thấp kích thước bộ đệm |
| Giai đoạn sao chép dữ liệu | is_args = 1 | Gọi ngx_escape_uri, mỗi byte được mở rộng thành 3 byte | Tràn bộ đệm trên heap |
Diễn biến cụ thể
- Chỉ thị rewritechứa captures không tên $1/$2
- Chuỗi thay thếchứa ?, kích hoạt is_args = 1
- Giai đoạn tính độ dài: sử dụng công cụ con được khởi tạo mới, is_args = 0
- Trả về độ dài gốc: cấp phát bộ đệm heap quá nhỏ
- Giai đoạn sao chép dữ liệu: sử dụng công cụ chính, is_args = 1
- Gọi ngx_escape_uri: mở rộng byte, làm tràn bộ đệm
- Dữ liệu URI do kẻ tấn công kiểm soátđược ghi vào vùng tràn
Cách khai thác
Heap Feng Shui xuyên các request:
- Thân POST requestphun (spray) bộ nhớ heap (vì URI không thể chứa byte null)
- Dữ liệu trànphá hủy con trỏ cleanup của ngx_pool_t liền kề
- Giả mạo ngx_pool_cleanup_s, trỏ tới system()
- Khi pool bị hủykích hoạt lời gọi system()
- thực hiện RCE
Ảnh hưởng của ASLR
- ASLR bật: chỉ khiến tiến trình worker gặp sự cố (DoS)
- ASLR tắt: có thể thực hiện thực thi mã từ xa (RCE)
📊 Các phiên bản bị ảnh hưởng
NGINX Open Source
| Khoảng phiên bản | Phiên bản sửa lỗi |
|---|---|
| 0.6.27 – 1.30.0 | 1.31.0, 1.30.1 |
NGINX Plus
| Khoảng phiên bản | Phiên bản sửa lỗi |
|---|---|
| R32 – R36 | R36 P4, R35 P2, R32 P6 |
Các thành phần khác bị ảnh hưởng
- NGINX Instance Manager: 2.16.0 – 2.21.1
- NGINX App Protect WAF: 4.9.0 – 5.8.0
- NGINX Ingress Controller: 3.5.0 – 5.4.1
- NGINX Gateway Fabric: 1.3.0 – 2.5.1
- F5 DoS for NGINX: 4.8.0
🔥 Tình trạng PoC
PoC đã được công khai
- Kho lưu trữ GitHub: https://github.com/DepthFirstDisclosures/Nginx-Rift
- Qianxin đã tái hiện: các nhà nghiên cứu bảo mật tại Trung tâm Tình báo Mối đe dọa đã tái hiện thành công
- Chi tiết kỹ thuật đã được công khai: depthfirst đã công bố phân tích kỹ thuật
- Khai thác ngoài thực tế: chưa phát hiện thấy
Cách sử dụng PoC
# 构建容器 ./setup.sh # 启动易受攻击的 NGINX 服务器 docker compose -f env/docker-compose.yml up # 执行 PoC 获取 Shell python3 poc.py --shell
✅ Giải pháp khắc phục
Cách 1: Nâng cấp phiên bản
# 升级到修复版本 NGINX Open Source >= 1.31.0 NGINX Open Source >= 1.30.1 NGINX Plus >= R32 P6 NGINX Plus >= R36 P4 # 升级后重启 NGINX nginx -s reload
Cách 2: Điều chỉnh cấu hình (biện pháp giảm thiểu)
Thay nhóm capture không tên bằng nhóm capture có tên:
# 易受攻击配置(未命名捕获) rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last; # 修复后配置(命名捕获) rewrite ^/users/(?[0-9]+)/profile/(?.*)$ /profile.php?id=$user_id&tab=$section last;
Nhóm capture có tên không kích hoạt lỗ hổng.
Cách 3: Kiểm tra cấu hình
Kiểm tra xem có cấu hình dễ bị tấn công hay không:
# 搜索易受攻击的 rewrite 指令 grep -E "rewrite.*\$[0-9]+.*\?.*(rewrite|if|set)" /etc/nginx/nginx.conf grep -rE "rewrite.*\$[0-9]+.*\?.*(rewrite|if|set)" /etc/nginx/conf.d/
🔍 Quá trình phát hiện
Hệ thống tự động phát hiện
depthfirst và hệ thống phân tích bảo mật của họ:
- trong vòng 6 giờtìm thấy 5 vấn đề
- 4 vấn đề được NGINX xác nhận
- CVE-2026-42945là lỗ hổng nghiêm trọng nhất
- Có thể truy nguồn về năm 2008, hiện diện trong hầu hết các bản build chuẩn
Các lỗ hổng liên quan khác
- CVE-2026-42946: vấn đề hủy hoại bộ nhớ
- CVE-2026-40701: vấn đề hủy hoại bộ nhớ
- CVE-2026-42934: vấn đề hủy hoại bộ nhớ
📝 Tổng kết
CVE-2026-42945 là lỗ hổng nghiêm trọng nhất trong lịch sử NGINX:
- Ẩn mình 18 năm: tồn tại trong mã nguồn từ năm 2008
- CVSS 9.2: tràn bộ đệm trên heap, có thể dẫn tới RCE
- Điều kiện kích hoạt: chỉ thị rewrite dùng capture không tên + chuỗi thay thế chứa ? + theo sau bởi chỉ thị khác
- Phạm vi ảnh hưởng: 9,75 triệu trang web toàn cầu, trong đó 2,54 triệu website tại Trung Quốc
- PoC đã công khai: kho GitHub + Qianxin đã tái hiện thành công
- Giải pháp khắc phục: nâng cấp phiên bản hoặc sử dụng nhóm capture có tên
Lỗ hổng ẩn mình 18 năm đã bùng phát, khuyến nghị nâng cấp hoặc điều chỉnh cấu hình càng sớm càng tốt.
Thông báo chính thức: https://my.f5.com/manage/s/article/K000161019
Kho lưu trữ PoC: https://github.com/DepthFirstDisclosures/Nginx-Rift
Phân tích kỹ thuật: https://depthfirst.com/research/nginx-rift