
Đọc các advisory về PHP2Shell tuần trước, điều đọng lại trong tôi không phải điểm CVSS mà là bề mặt tấn công. Kẻ tấn công không cần đăng nhập, không cần tài khoản, không cần quyền gì. Chỉ cần biết địa chỉ của một website là có thể bắt đầu. Và lỗi không nằm ở WordPress, Laravel hay code của bạn. Nó nằm ngay trong PHP.
Bài viết này là nỗ lực của tôi để tách tín hiệu khỏi nhiễu: PHP2Shell thực sự là gì, nó làm được gì, thiệt hại nào đã thực sự được ghi nhận cho đến nay, và theo tôi các đội kỹ thuật nên làm gì, trong tuần này và trong vài năm tới. Mọi con số đều dẫn về nguồn. Dữ kiện tính đến ngày 26/10/2026.
PHP2Shell là gì
PHP2Shell là tên các nhà nghiên cứu đặt cho hai lỗ hổng trong engine của PHP, CVE-2026-109618 (“RCE via OOM corruption”) và CVE-2026-109619 (“RCE via stale global state”). Cả hai đều được chấm 9.2 (critical) theo CVSS 4.0. Đoạn code dính lỗi có từ PHP 5.4, phát hành năm 2012, và đã được vá trong PHP 8.2.35, 8.3.36, 8.4.27 và 8.5.12 vào ngày 21/10/2026.
Cả hai lỗi nằm ở hai nơi mà gần như mọi request đều đi qua: quản lý bộ nhớ và xử lý lỗi. Nói đơn giản:
- CVE-2026-109618. Khi một request chạm ngưỡng
memory_limitđúng vào thời điểm không may, PHP dừng đột ngột khi một số dữ liệu nội bộ của request mới được dựng dở dang. Đoạn code dọn dẹp chạy sau đó lại tin dữ liệu này như thể nó hợp lệ. Theo advisory, điều kiện hết bộ nhớ (out-of-memory) có thể bị kích hoạt bởi chính body của request, trước khi bất kỳ code ứng dụng nào chạy. - CVE-2026-109619. Các PHP worker sống qua nhiều request. Một số global state trỏ vào vùng nhớ của một request có thể còn tồn tại sau khi vùng nhớ đó đã được giải phóng, khi một lỗi fatal làm gián đoạn bước reset thông thường. Một request sau đó do cùng worker xử lý có thể thao tác trên vùng nhớ không còn thuộc về nó, đây là lỗi use-after-free kinh điển (advisory).
Wiz Research, một trong các nhóm phát hiện ra các lỗi này, cũng chứng minh rằng có một đường làm rò rỉ bộ nhớ của worker về phía client, vùng nhớ đó có thể chứa mật khẩu, session token, API key và chứng chỉ từ request của những người dùng khác. Chi tiết này sẽ quan trọng ở phần sau, khi bàn đến việc “đã vá” thực sự nghĩa là gì.
Vì sao “mọi site PHP” là đúng, và vì sao mod_php là trường hợp tệ nhất
Lỗ hổng nằm ở engine nên ứng dụng chạy bên trên không quan trọng. Wiz đã demo trên các container image mặc định của WordPress, Drupal và Joomla, và lưu ý rằng ngay cả một ứng dụng “Hello World” trên phiên bản PHP bị ảnh hưởng cũng có thể bị tấn công. Dùng Apache hay Nginx cũng không khác gì. Điều quan trọng là PHP được gắn vào web server theo cách nào (SAPI):
Cách PHP chạy | Mức độ phơi nhiễm theo các advisory của PHP |
|---|---|
Apache mod_php | Cao nhất. Apache chạy bước request shutdown ngay cả khi bước startup thất bại, nên cuộc tấn công có thể hoàn tất trước khi bất kỳ code ứng dụng nào chạy. Full RCE đã được chứng minh với cấu hình mặc định. |
PHP-FPM (Nginx, Apache proxy) | Bị ảnh hưởng. FPM kết thúc tiến trình con có startup thất bại, làm hỏng đường đi đơn giản nhất, nhưng RCE vẫn được xác nhận qua các đường code ở tầng ứng dụng. |
FrankenPHP, LiteSpeed (LSAPI) | Nhiều khả năng bị ảnh hưởng theo phân tích mã nguồn; chưa được xác thực đầy đủ. |
PHP CLI, cron job | Không phải mục tiêu: cuộc tấn công cần PHP phục vụ web request. |
Đó là lý do tôi coi mod_php là cấu hình nguy hiểm nhất. PHP chạy ngay trong tiến trình Apache. Ai chiếm được PHP là đang chạy code với tư cách web server, cùng mọi site và bí mật mà tiến trình đó chạm tới được. Với FPM, ít nhất còn có ranh giới tiến trình và một pool bạn có thể cô lập.
“Một request là đủ”? Không hẳn
Những tiêu đề đầu tiên nói rằng chỉ một request cũng có thể hạ gục một server. Các advisory chính xác hơn, và sự khác biệt này hữu ích cho phía phòng thủ. Không cần xác thực, phần đó là đúng. Nhưng các cuộc tấn công đã xác nhận phải nối chuỗi nhiều request cùng rơi vào cùng một PHP worker, và độ tin cậy phụ thuộc vào bản build PHP, các extension và bố cục bộ nhớ. Sansec báo cáo ngày 22/10 rằng mã proof-of-concept công khai không chạy được trên bản cài PHP mặc định, và VulnCheck thấy rằng không đoạn code công khai nào tự nó vượt được ASLR trên x86-64.
Điều đó không phải lý do để chủ quan. Wiz và Calif đã có exploit chạy được, các lỗi là có thật, và kẻ tấn công cũng có những công cụ AI mà các nhà nghiên cứu đã dùng. Đó là lý do để vá bình tĩnh và điều tra bài bản thay vì hoảng loạn.
Kẻ tấn công nhận được gì
- Thực thi code với quyền tài khoản của web worker. Từ đó: đọc thông tin đăng nhập database trong file cấu hình, trích xuất dữ liệu người dùng, cài webshell để quay lại sau, hoặc deface website. NSA đã cảnh báo rằng các lỗ hổng như vậy “thường cung cấp đường đi thẳng đến hệ thống file hoặc database của server”.
- Bí mật trong bộ nhớ, không cần full RCE. Đường làm lộ bộ nhớ có thể phơi bày dữ liệu thuộc request của người dùng khác: session token, mật khẩu, API key.
- Hạ tầng giá rẻ. Các server bị chiếm trở thành máy đào tiền mã hóa, proxy hoặc node DDoS. Payload đầu tiên Sophos bắt được là một biến thể botnet Mirai tên “Potassium”, được thiết kế cho DDoS.
- Thiết bị appliance, không chỉ website. PHP còn chạy bên trong những sản phẩm không hề quảng bá điều đó. Palo Alto Networks xác nhận giao diện quản trị PAN-OS và Panorama bị ảnh hưởng, còn Cisco liệt kê Expressway và Duo Access Gateway.
Thiệt hại đã ghi nhận đến nay
Ở đây tôi muốn thận trọng, vì “70% internet” là một tiêu đề hay nhưng là một ước tính thiệt hại kém. Đây là những gì thực sự đã được đo:
Chỉ số | Con số | Nguồn |
|---|---|---|
Website dùng PHP (trong số những site có ngôn ngữ phía server được biết) | 69,2% | |
Site PHP vẫn dùng phiên bản 7 trở xuống (không có bản phát hành PHP chính thức) | 34,5% | |
Host hướng ra internet có hiển thị phiên bản PHP và chưa được vá vào ngày 21/10 | ≈1,57 triệu trên 1,58 triệu | |
Host công bố phiên bản PHP đã hết vòng đời (5.4–8.1) | ≈758.000 trên 1,1 triệu | |
Lần thử khai thác đầu tiên được ghi nhận (honeypot) | 17/10, bốn ngày trước khi công bố | |
Các lần thử trên mạng của Cloudflare | Hàng nghìn lần trước thông báo, hàng chục nghìn lần sau 45 phút, hàng triệu lần trong vòng một ngày |
Chi phí dễ thấy nhất cho đến nay không phải dữ liệu bị đánh cắp mà là các đợt tắt hệ thống phòng ngừa. Theo khuyến nghị của NSA, NCSC của Anh và CERT-EU, Phần Lan đã tạm thời đóng các dịch vụ web công của chính phủ, còn các cơ quan Hà Lan, Tweede Kamer và một số phần của Wikimedia cũng ngừng hoạt động (BBC). Các website hội đồng thành phố Edinburgh, Bristol và Oxford cùng site của sở cảnh sát Paris cũng tê liệt (The Guardian). Tại Nhật Bản, Thủ tướng Sanae Takaichi đã đề nghị trên X kiểm tra các website công ngay trong đêm đó, và Văn phòng An ninh mạng Quốc gia cho biết tạm dừng một site là lựa chọn hợp lệ nếu không thể vá nhanh (INTERNET Watch).
Về các vụ xâm nhập đã được xác nhận, câu trả lời trung thực là bằng chứng công khai vẫn còn mỏng. watchTowr thấy việc khai thác cả hai CVE trong honeypot của họ, nhưng Sophos đã rút lại một báo cáo ban đầu về một vụ xâm nhập thành công và, tính đến ngày 22/10, không có bằng chứng về xâm nhập thành công. Tuy vậy có hai lưu ý. Honeypot của Amazon bị thăm dò ngày 17/10, nên việc bị xâm nhập có thể xảy ra trước khi có advisory. Và JPCERT/CC cảnh báo một số đường tấn công có thể không để lại dấu vết trong log. “Chưa có sự cố nào được báo cáo” không đồng nghĩa với “không có sự cố”.
Vì sao vụ rò rỉ là phần đáng sợ nhất
Theo tôi, phần đáng sợ nhất của PHP2Shell không phải là lỗi mà là tốc độ nó lọt ra ngoài. Quy trình công bố phối hợp vận hành tốt cho đến hai ngày trước ngày phát hành. Sau đó, vào ngày 20/10 lúc khoảng 15:00 UTC, các CVE ID bắt đầu lan truyền trên mạng. PHP dời ngày phát hành lên sớm một ngày. Vài giờ sau, một trong các hãng báo cáo lỡ đăng video proof-of-concept. Sáng 21/10, một vendor có bản vá từ trước đã công bố các bản build đã vá sớm hơn hơn sáu tiếng, khiến bất kỳ ai cũng có thể so sánh diff của bản sửa (PHP Foundation, timeline).

Kết luận của Amazon là điều mọi trưởng bộ phận bảo mật nên dán lên tường: “Phân tích có AI hỗ trợ khiến việc biến một patch diff hoặc advisory thành exploit chạy được trở nên rẻ hơn.” SLA vá lỗi 7 ngày hay 30 ngày giả định một khoảng trễ không còn tồn tại.
Cần làm gì ngay bây giờ
1. Vá, rồi chứng minh bản vá đã chạy thật
Nâng cấp lên PHP 8.5.12, 8.4.27, 8.3.36 hoặc 8.2.35. Với 7.4, 8.0 và 8.1 không có bản build chính thức, chỉ có các bản backport từ mã nguồn, vì vậy hãy dùng gói có người duy trì: repository của Ondřej Surý cho Debian/Ubuntu, của Remi cho họ RHEL, Ubuntu Pro, CloudLinux, TuxCare hoặc Zend (Sansec giữ danh sách này). Với 7.3 trở xuống thì hoàn toàn không có bản sửa: hãy nâng cấp.
Hai cái bẫy tôi từng thấy các đội mắc phải: kiểm tra phiên bản CLI thay vì phiên bản đang phục vụ web traffic, và quên restart các worker.
# 1. The version that actually serves web requests (the CLI can differ)
# Put a temporary phpinfo() page behind auth, or check the FPM binary:
php-fpm8.3 -v # adjust to your version
apachectl -M | grep php # is mod_php loaded at all?
# 2. Distribution packages keep the old version number after a backport,
# so look for the CVE in the changelog instead
zgrep CVE-2026-109618 /usr/share/doc/php8.3-common/changelog.Debian.gz # Debian/Ubuntu
rpm -q --changelog php-common | grep CVE-2026-109618 # RHEL/Alma/Rocky
# 3. Restart every worker, or the old code keeps running in memory
sudo systemctl restart php8.3-fpm # or: sudo systemctl restart apache22. Nếu hôm nay chưa vá được
Đội PHP nói rõ rằng cập nhật là biện pháp giảm thiểu duy nhất đầy đủ. Các biện pháp tạm chỉ mua thêm thời gian:
- Đặt site sau một WAF. Cloudflare cho biết khách hàng WAF miễn phí lẫn trả phí của họ được bảo vệ mặc định từ 03:02 UTC ngày 21/10 trước các nỗ lực khai thác đã biết, miễn là site dùng tên trường upload-progress mặc định của PHP.
- Tắt session upload progress, và trên PHP 8.5 tắt fatal error backtraces. Mỗi biện pháp đóng một đường tấn công đã được chứng minh, không phải tất cả.
- Giới hạn kích thước request, số phần multipart và độ sâu lồng nhau tại reverse proxy. Nếu ứng dụng không bao giờ nhận upload, hãy từ chối request multipart ngay tại edge.
- Nếu không làm được điều nào ở trên và site chứa dữ liệu nhạy cảm, hãy đưa site offline cho đến khi được vá, như NCSC đã khuyến nghị.
; Biện pháp tạm thời, chỉ một phần, theo các advisory của PHP. Vá lỗi là cách sửa duy nhất.
; PHP-FPM đọc cấu hình pool, không đọc php.ini của CLI:
; /etc/php/8.3/fpm/pool.d/www.conf
php_admin_flag[session.upload_progress.enabled] = off
; Chỉ dành cho PHP 8.5:
php_admin_flag[fatal_error_backtraces] = off3. Rà soát dấu hiệu bị xâm nhập, bắt đầu từ ngày 17/10
Vá lỗi là đóng cửa; nó không cho bạn biết có ai đã bước vào trước hay chưa. Ba chỉ báo của JPCERT/CC là điểm khởi đầu tốt: cookie PHPSESSID dài bất thường hoặc sai định dạng trong các response trước đây; các request multipart/form-data đáng ngờ theo sau là lỗi memory-limit hoặc HTTP 500; và PHP worker bị crash hoặc khởi động lại bất ngờ. Thêm vào đó là các kiểm tra hậu khai thác thông thường: web server sinh ra shell, file PHP lạ trong web root, cron job mới và các kết nối outbound không giải thích được.
Rotate secret trên mọi host từng bị phơi nhiễm, kể cả khi bạn không tìm thấy gì. Vì có một đường làm rò rỉ bộ nhớ, một server đã vá vẫn có thể đã bị lộ mật khẩu database, API key và khóa ký session trước khi vá. Bản vá không thể “thu hồi” những gì đã lộ.

Các biện pháp dài hạn
Tôi đã nói trên Facebook rằng không có viên đạn bạc, chỉ có phòng thủ và hạn chế thiệt hại. Sau khi nghiên cứu cho bài này, tôi sẽ gói nó thành năm việc cụ thể:
- Biết mình đang chạy PHP ở đâu. Sai Molige của Forescout nói rất đúng: hãy coi “chúng ta xác định được nơi mình chạy X nhanh đến mức nào?” là một năng lực được đo riêng, tách khỏi tốc độ vá lỗi. Điều đó bao gồm cả PHP bên trong appliance, control panel và sản phẩm của vendor.
- Tự động hóa cập nhật và giữ cửa sổ vá ở mức hàng giờ. Tự động cập nhật bảo mật cho gói của distro, base image được build lại và deploy lại bằng pipeline, và một runbook khẩn cấp đã được diễn tập. Lời khuyên của Amazon là đo thời gian vá lỗi critical bằng giờ.
- Rời bỏ mod_php và các phiên bản hết vòng đời. Chuyển sang PHP-FPM với mỗi site một pool, mỗi pool một user riêng, và một nhánh PHP còn được hỗ trợ. W3Techs cho biết 34,5% site PHP vẫn chạy phiên bản 7 trở xuống, không phiên bản nào còn nhận bản phát hành PHP chính thức.
- Giả định tầng web sẽ bị xâm nhập. Chạy worker với đặc quyền tối thiểu, chặn lưu lượng outbound không cần thiết, giữ secret ngoài web root và phân đoạn nó khỏi các hệ thống nội bộ. Giám sát hành vi theo thời gian thực (web server sinh ra
shlà đáng ngờ bất kể CVE nào), vì lần khai thác đầu tiên thường xảy ra trước khi có signature. - Dùng AI trên code của chính bạn trước khi kẻ tấn công làm điều đó. Bản thân dự án PHP hiện quét code bằng các công cụ AI, gồm Claude Mythos của Anthropic và công cụ của OpenAI. Các đội có thể đưa kiểu rà soát bằng AI tương tự vào CI cho code và dependency của chính họ.
Bức tranh lớn hơn: AI đã hạ chi phí tấn công
Các lỗi PHP2Shell đã ẩn mình ngay trước mắt mọi người. Chính nhà phát triển PHP đã thấy những dấu hiệu đầu tiên trong một đợt audit năm 2024, nhưng không ai chứng minh được một exploit thực tế, đội ngũ không thống nhất được cách sửa, và công việc bị đình trệ nhiều tháng, một độ trễ mà chính PHP Foundation gọi là thất bại mang tính cấu trúc. Điều thay đổi vào năm 2026 là công cụ. Wiz viết rằng với các frontier model, “một nhà nghiên cứu đơn lẻ hoàn thành trong một tuần những gì trước đây cần một đội đẳng cấp thế giới làm nhiều tháng”.
PHP2Shell không đơn độc. Cùng ngày, Node.js đã vá CVE-2026-111497, một lỗi ghi ngoài vùng nhớ (out-of-bounds write) trong bộ giải mã Brotli đi kèm, có thể dẫn đến remote code execution, do nhóm Codex Security của OpenAI báo cáo. Đội bảo mật PHP cho biết họ đã công bố 15 CVE kể từ ngày 1/7 và xử lý hơn 100 báo cáo không hợp lệ, khi AI nhân khối lượng lên nhiều lần. Dự đoán của tôi: mọi thành phần không an toàn bộ nhớ (memory-unsafe) nằm gần dữ liệu đầu vào không đáng tin (runtime ngôn ngữ, thư viện nén và xử lý ảnh, web server, firmware thiết bị) sẽ chịu áp lực tương tự. Những lỗi cũ từng bị gạt đi là “quá khó khai thác” nay quay lại bàn cân.
Trong bài đăng trên Facebook tôi cũng viết rằng thiệt hại nhiều khả năng chỉ dừng ở kinh tế, vì các hệ thống mật được cách ly (air-gapped) và không chạy PHP. Tôi vẫn nghĩ điều đó phần lớn đúng. Nhưng PHP2Shell cho thấy ranh giới mỏng hơn vẻ ngoài: PHP nằm bên trong giao diện quản trị của các firewall bảo vệ những mạng nhạy cảm. Mắt xích yếu nhất thường chính là chiếc hộp bạn mua để làm mắt xích mạnh nhất.
Kết luận của tôi. Không có giải pháp vĩnh viễn cho một thế giới nơi việc tìm ra và vũ khí hóa lỗ hổng ngày càng rẻ. Chỉ có một vòng lặp nhanh hơn: biết mình đang chạy gì, vá trong vài giờ, giả định đã bị xâm nhập, giám sát theo thời gian thực, và dùng chính loại AI mà kẻ tấn công sẽ dùng để rà soát code của bạn trước.
Cần hỗ trợ về chủ đề này?
Các dịch vụ của iPlus liên quan nhất đến bài viết.


