5 phút đọc

Lỗ hổng PHP2Shell đã bị khai thác thật, và tắt upload progress là chưa đủ

Hai lỗ hổng PHP CVE-2026-109618 và CVE-2026-109619 (CVSS 9,2) đang bị dò quét và khai thác trên diện rộng, có lần thử từ 17/10, trước khi bản vá ra. Không cài đặt php.ini nào chặn được hết. Kiểm tra bản PHP mà web đang chạy, vá, khởi động lại và xem log có dấu bị tấn công không.

Xem nhanh trong 1 phút

Ngày 17/10, một máy chủ mồi (honeypot) của Amazon nhận được một request lạ nhắm vào PHP. Bốn ngày sau PHP mới phát hành bản vá. Nghĩa là đã có người cầm cách khai thác trong tay trước khi phần lớn chúng ta biết lỗ hổng tồn tại.

Robot linh vật cầm cờ lê vá khe nứt trên thanh tiến trình tải lên nối vào tủ máy chủ

Tối 21/10 blog đã có bài về hai lỗ hổng chạy mã từ xa trong PHP, CVE-2026-109618 và CVE-2026-109619, mỗi lỗi 9,2/10 theo CVSS v4. Lúc đó PHP Foundation nói chưa thấy bản khai thác nào chạy được, CISA cũng chưa ghi nhận vụ tấn công nào. Ba ngày sau, tình hình đã khác, và có một lời khuyên trong bài trước cần nói lại cho rõ.

Đã có tấn công thật

Những gì đã được các bên công bố đến chiều 24/10:

  • Amazon ghi nhận lần thử khai thác đầu tiên vào máy chủ mồi MadPot ngày 17/10, thêm nhiều lần nữa từ 21/10, và nói vụ này (giới bảo mật gọi là PHP2Shell) giờ “đang bị khai thác trên diện rộng” (theo Tenable).
  • watchTowr thấy khai thác cả hai lỗi trên mạng máy chủ mồi của họ từ ngày 21/10.
  • Cloudflare, qua lời CTO Dane Knecht, nói ngày 21/10 đã thấy những đợt tấn công đầu tiên và bật luật tường lửa (WAF) chặn tạm.
  • Datadog nói có dò quét hàng loạt, không chọn mục tiêu.

Chưa rõ bao nhiêu lần tấn công thành công. Tới 23/10, CISA vẫn chưa đưa hai lỗi vào danh sách đang bị khai thác (KEV). Mã khai thác thì đang được chia nhau trên mạng, Tenable chưa kiểm chứng được bản nào chạy thật và cảnh báo một số bản có thể chứa mã độc. Đừng tải về chạy thử trên máy mình.

Một nhà nghiên cứu ước tính hơn 1,3 triệu máy chủ PHP mở ra internet có thể đang dính lỗi. Bị dò quét không chọn mục tiêu có nghĩa là cái VPS chạy WordPress của khách cũng nằm trong danh sách, không cần ai biết tới nó.

Cài đặt php.ini không thay được bản vá

Bài trước có khuyên đặt session.upload_progress.enabled=0. Lời khuyên đó vẫn đúng, nhưng dễ khiến người đọc nghĩ tắt nó là xong. Không phải vậy.

Cài đặt này chỉ bịt một đường của CVE-2026-109619. Lỗi còn lại, CVE-2026-109618, đi qua đường làm cạn bộ nhớ lúc PHP đọc request, và upload progress không liên quan gì tới nó. Chính PHP nói rõ không có thay đổi cấu hình nào chặn được hoàn toàn hai lỗi này. Datadog cũng viết rằng các cách giảm rủi ro đang lan truyền trong cộng đồng “không bảo vệ trọn vẹn”.

Một điểm nữa: bài trước nói PHP-FPM chưa ai dựng được bản khai thác hoàn chỉnh. Các khuyến cáo cập nhật sau đó đều xếp mọi cách chạy PHP phục vụ web vào diện bị ảnh hưởng, gồm PHP-FPM, Apache mod_php, php-cgi, FrankenPHP và LiteSpeed. Mod_php vẫn là nguy hiểm nhất vì tấn công xong trước khi code của bạn chạy dòng nào. Nhưng dùng nginx với PHP-FPM thì cũng phải vá như mọi người.

Theo watchTowr, PHP 5 cũng dính. PHP 7.4, 8.0, 8.1 chỉ có bản sửa mã nguồn tối thiểu (backport) để nhà phân phối tự đóng gói, PHP 7.3 trở xuống không có gì. CISA khuyên tắt hẳn những máy chạy PHP 8.1 trở xuống nếu không vá được.

Kiểm tra máy chủ của bạn

Xem bản PHP mà web đang chạy, không phải bản dòng lệnh. Hai cái có thể khác nhau. Trên Ubuntu, Debian:

php-fpm8.3 -v              # đổi 8.3 thành nhánh bạn dùng
apache2ctl -M | grep php   # có dòng php_module là đang dùng mod_php

Cần đạt 8.5.12, 8.4.27, 8.3.36 hoặc 8.2.35 trở lên. Gói của distro đôi khi vá mà giữ nguyên số phiên bản, khi đó xem changelog có nhắc mã CVE không:

apt changelog php8.3-fpm 2>/dev/null | grep -m2 "CVE-2026-10961"

Chạy PHP trong Docker thì kéo image mới, build lại và deploy lại container. Sửa trong container đang chạy không tính.

Vá xong phải khởi động lại. Tiến trình cũ còn sống thì vẫn chạy code lỗi:

sudo systemctl restart php8.3-fpm   # hoặc apache2 nếu dùng mod_php
ps -o lstart=,cmd= -C php-fpm8.3 | head -3

Giờ khởi động ở dòng thứ hai phải là sau lúc bạn vá.

Xem có dấu bị tấn công không. Datadog gợi ý vài dấu hiệu trong log. Lỗi hết bộ nhớ với dòng Unknown on line 0 cho thấy PHP chết ngay lúc đọc request, chưa tới code của bạn:

sudo grep -rh "Allowed memory size.*Unknown on line 0" /var/log/php* /var/log/nginx /var/log/apache2 2>/dev/null | tail
sudo grep -h "AH00052" /var/log/apache2/error.log* 2>/dev/null | tail

AH00052 là tiến trình Apache bị lỗi phân đoạn (segfault). Một hai dòng lẻ tẻ chưa nói lên gì, vì app bình thường cũng có lúc hết bộ nhớ. Đáng lo là một chùm dòng như vậy dồn trong vài phút.

Dấu chắc chắn nhất là có shell hay lệnh tải file chạy dưới tiến trình PHP, và file PHP lạ mới xuất hiện trong thư mục web:

ps -ef --forest | grep -B1 -A3 "php-fpm\|apache2" | grep -E "sh -c|bash|curl|wget"
sudo find /var/www -name "*.php" -newermt 2026-10-17 -ls
crontab -l -u www-data

Lưu ý tấn công thành công có thể trả về mã 200 bình thường mà không làm sập gì, nên log sạch chưa có nghĩa là an toàn. Thấy file lạ hay cron lạ thì chép log và file đó ra chỗ khác trước khi xóa, rồi đổi hết mật khẩu database, key API trong .env của site, vì kẻ đã chạy được lệnh trên máy thì đọc được file đó.

Chưa vá được ngay thì đừng để máy mở ra internet. Đặt site sau Cloudflare chỉ có tác dụng khi mọi lưu lượng thật sự đi qua Cloudflare, nếu IP gốc của máy chủ vẫn truy cập thẳng được thì luật WAF không giúp gì.


Máy chủ của bạn đã lên bản vá chưa, và gói của distro bạn dùng ra bản vá lúc nào? Vào cộng đồng Vibe Code & Bảo Mật kể cho mọi người cùng biết nhé.

Nguồn

Chia sẻ lên Facebook

Bình luận

Đang tải bình luận…