WordPress bị nhiễm mã độc: cách xử lý và làm sạch từng bước
WordPress bị nhiễm mã độc? Cách ly, tìm backdoor, làm sạch file và database bằng wp-cli, khôi phục backup sạch, rồi gia cố để website không bị hack lại.

Ý chính
- Khi WordPress bị nhiễm mã độc, hãy cách ly và sao lưu bản đang nhiễm trước khi sửa bất cứ thứ gì.
- Nếu có bản sao lưu sạch trước thời điểm bị hack, khôi phục rồi vá lỗ hổng thường nhanh và chắc hơn tự dọn từng file.
- Thay lõi WordPress, plugin và giao diện bằng bản chính thức, rồi kiểm tra uploads, mu-plugins, wp-config.php, .htaccess và database.
- Đổi mọi mật khẩu và khoá bảo mật sau khi đã sạch, rồi tìm và vá đúng đường kẻ tấn công đã vào.
Khi WordPress bị nhiễm mã độc, làm theo thứ tự: cách ly website, sao lưu nguyên trạng bản đang nhiễm, đổi mật khẩu, rồi chọn một trong hai hướng. Nếu có bản sao lưu sạch từ trước khi bị hack, khôi phục bản đó và vá lỗ hổng. Nếu không, thay toàn bộ lõi WordPress, plugin và giao diện bằng bản chính thức, rồi dọn những chỗ mã độc hay ẩn: thư mục uploads, mu-plugins, wp-config.php, .htaccess và database. Cuối cùng đổi mật khẩu lần nữa, cập nhật mọi thứ và tìm ra đường kẻ tấn công đã vào, nếu không website sẽ bị nhiễm lại trong vài ngày.
Bài viết đi qua dấu hiệu nhận biết, từng bước xử lý kèm lệnh cụ thể (chạy được trên Ubuntu 24.04, Debian 12), cách làm trên ZoPanel, và cách gia cố để không lặp lại. Nếu website có dữ liệu khách hàng hoặc giao dịch, hãy cân nhắc thuê chuyên gia; bài này giúp bạn tự xử lý các trường hợp phổ biến và biết cần hỏi gì.
Dấu hiệu WordPress bị nhiễm mã độc
Tài liệu chính thức của WordPress liệt kê các dấu hiệu rõ ràng, và trên thực tế chúng tôi hay gặp thêm vài dấu hiệu khác:
- Google hiện cảnh báo "Trang web này có thể đã bị tấn công" hoặc trang cảnh báo đỏ.
- Khách truy cập từ Google (đặc biệt trên điện thoại) bị chuyển hướng sang trang cờ bạc, thuốc, lừa đảo, trong khi bạn vào thẳng thì không thấy gì.
- Có tài khoản quản trị lạ trong mục Người dùng.
- Kết quả tìm kiếm
site:tenmien.vnhiện hàng nghìn trang lạ, thường bằng tiếng Nhật hoặc tiếng Anh về hàng hiệu. - Nhà cung cấp hosting tạm khoá website hoặc báo server gửi spam.
- CPU tăng vọt, file PHP lạ xuất hiện trong
wp-content/uploads. - Phần mềm diệt virus của khách báo động khi mở website.
Mã độc hiện đại thường ẩn với quản trị viên: chỉ hiện với khách từ Google, chỉ trên điện thoại, hoặc chỉ một lần mỗi IP. Website trông bình thường khi bạn mở không có nghĩa là sạch.
Bước 1: Bình tĩnh, ghi lại và cách ly
Ghi lại bạn thấy gì, lúc nào, và những thay đổi gần đây (plugin mới, cập nhật, người mới được cấp quyền). Ghi chú này giúp ích khi tìm nguyên nhân.
Sau đó cách ly:
- Bật chế độ bảo trì, hoặc tạm chặn truy cập công khai bằng mật khẩu thư mục cho
/. - Nếu website gửi spam, tạm dừng gửi mail của tài khoản đó.
- Trên shared hosting, báo nhà cung cấp: lây nhiễm có thể lan sang website khác cùng tài khoản.
Bước 2: Sao lưu bản đang nhiễm
Nghe có vẻ ngược, nhưng hãy lưu một bản đầy đủ (file và database) trước khi sửa gì. Nếu việc dọn dẹp làm hỏng website, bạn còn bản để tham chiếu; nếu cần điều tra, đây là bằng chứng. Đặt tên rõ ràng, ví dụ nhiem-2026-11-11.tar.gz, và đừng bao giờ khôi phục nhầm nó.
cd /home/khach1/domains/example.com
tar czf ~/nhiem-$(date +%F).tar.gz public_html
wp db export ~/nhiem-$(date +%F).sql --path=public_html --skip-plugins --skip-themes
Tuỳ chọn --skip-plugins --skip-themes rất quan trọng: wp-cli nạp WordPress để chạy lệnh, và nếu không bỏ qua plugin, giao diện, bạn có thể đang chạy chính mã độc.
Bước 3: Đổi mật khẩu và đăng xuất mọi phiên
Đổi mật khẩu của mọi điểm truy cập: quản trị WordPress, SFTP/FTP, control panel, database, email. Tạo bộ khoá bảo mật (salt) mới trong wp-config.php để mọi phiên đăng nhập, kể cả của kẻ tấn công, bị đăng xuất:
wp config shuffle-salts --path=public_html --skip-plugins --skip-themes
Liệt kê quản trị viên và xoá tài khoản lạ (chuyển bài viết của họ cho một tài khoản hợp lệ nếu cần):
wp user list --role=administrator --path=public_html --skip-plugins --skip-themes
Bạn sẽ đổi mật khẩu thêm một lần nữa sau khi website sạch, vì mật khẩu mới có thể bị đánh cắp lại nếu còn backdoor.
Bước 4: Khôi phục bản sạch hay tự dọn?
| Tình huống | Nên làm |
|---|---|
| Có bản sao lưu từ trước khi bị nhiễm, và chấp nhận mất dữ liệu từ đó tới nay | Khôi phục, rồi cập nhật và vá ngay |
| Có bản sao lưu nhưng không chắc thời điểm bị nhiễm | Khôi phục file từ bản cũ, giữ database hiện tại sau khi dọn |
| Không có bản sao lưu sạch | Dọn thủ công theo Bước 5 |
| Website thương mại điện tử có dữ liệu thanh toán | Thuê chuyên gia, bảo toàn bằng chứng |
Mã độc thường nằm im nhiều tuần trước khi lộ, nên "bản sao lưu hôm qua" chưa chắc sạch. Khôi phục xong vẫn phải chạy các bước kiểm tra bên dưới.
Bước 5: Làm sạch WordPress từng phần
5.1. So sánh lõi WordPress với checksum chính thức
wp core verify-checksums --path=public_html
Lệnh wp core verify-checksums so file lõi với checksum do WordPress.org công bố và không nạp WordPress khi chạy. File bị sửa hoặc file lạ trong thư mục lõi sẽ được liệt kê.
Cách chắc nhất là thay toàn bộ lõi bằng bản sạch cùng phiên bản (giữ nguyên wp-content và wp-config.php):
VER=$(wp core version --path=public_html --skip-plugins --skip-themes)
wp core download --version="$VER" --skip-content --force --path=public_html
Lệnh này ghi đè file, nhưng không xoá file lạ do kẻ tấn công thêm vào wp-admin hay wp-includes. Hãy xoá hai thư mục này trước rồi tải lại, hoặc xoá thủ công các file mà verify-checksums báo "should not exist".
5.2. Plugin và giao diện
wp plugin verify-checksums --all --path=public_html --skip-plugins --skip-themes
Plugin từ WordPress.org được kiểm tra checksum. Plugin trả phí hay giao diện thương mại không có checksum công khai: tải lại bản mới nhất từ nhà phát triển và thay hẳn thư mục. Xoá mọi plugin, giao diện không dùng; plugin "nulled" (bản crack) là nguồn lây nhiễm rất phổ biến, hãy xoá ngay.
5.3. Những chỗ mã độc hay ẩn
cd /home/khach1/domains/example.com/public_html
# File PHP trong uploads (WordPress không bao giờ cần)
find wp-content/uploads -type f -name "*.php"
# Must-use plugin: tự chạy, không hiện trong danh sách plugin thường
ls -la wp-content/mu-plugins 2>/dev/null
# File PHP thay đổi trong 14 ngày qua
find . -type f -name "*.php" -mtime -14 -printf "%TY-%Tm-%Td %p\n" | sort
# Mẫu mã bị làm rối hay gặp
grep -rlE "eval\(base64_decode|gzinflate\(base64_decode|str_rot13\(" --include=*.php .
Kiểm tra thêm wp-config.php (dòng include lạ ở đầu hoặc cuối file), .htaccess ở mọi thư mục (chuyển hướng theo User-Agent hay Referer từ Google), và index.php, header.php, footer.php, functions.php của giao diện. Kết quả grep có thể có cảnh báo nhầm, vì vài plugin hợp lệ cũng dùng base64; đừng xoá file chỉ vì xuất hiện trong danh sách, hãy mở ra xem.
5.4. Database
Mã độc trong database thường là đoạn <script> chèn vào bài viết, widget, hoặc tuỳ chọn của giao diện:
wp db search "<script" --all-tables --path=public_html --skip-plugins --skip-themes
wp db search "eval(" --all-tables --path=public_html --skip-plugins --skip-themes
Kiểm tra thêm các tác vụ định kỳ lạ (wp cron event list) và giá trị siteurl, home trong bảng options. Sửa bằng Adminer hoặc phpMyAdmin, và luôn sao lưu database trước khi xoá dòng nào.
Bước 6: Cập nhật, đổi mật khẩu lần hai, gia cố
- Cập nhật lõi WordPress, mọi plugin, giao diện và phiên bản PHP được hỗ trợ.
- Đổi lại mọi mật khẩu, tạo salt mới lần nữa.
- Bật xác thực hai lớp cho quản trị viên.
- Tắt trình sửa file trong trang quản trị (
DISALLOW_FILE_EDIT), chặn chạy PHP trong uploads, đặtwp-config.phpchỉ tài khoản đọc được. - Tìm nguyên nhân: plugin có lỗ hổng chưa vá, mật khẩu yếu bị dò, máy tính cá nhân nhiễm trojan đánh cắp mật khẩu FTP. Quét cả máy tính của bạn.
Nếu Google đã cảnh báo website, vào Google Search Console, mục Vấn đề bảo mật, và gửi yêu cầu xem xét lại sau khi website đã sạch.
Xử lý trên ZoPanel như thế nào?
Các công cụ dưới đây có sẵn trong panel và giúp rút ngắn đáng kể các bước trên. Chi tiết trong tài liệu Bảo mật và WordPress Toolkit.
- Quét mã độc: tìm webshell, backdoor, mã bị làm rối, JavaScript bị chèn và file PHP trong uploads. Mọi tài khoản được quét tự động vào Chủ nhật; khách có thể bấm Quét ngay. Với mỗi phát hiện, Cách ly chuyển file khỏi website vào
/var/lib/zopanel/quarantine/<user>/, thư mục chỉ root đọc được, để nó không chạy được, hoặc Bỏ qua nếu là phát hiện nhầm. - Tab WordPress → Bảo mật: Kiểm tra toàn vẹn file so lõi và plugin với checksum chính thức; Đổi khoá bảo mật tạo salt mới và đăng xuất mọi người; Đặt lại mật khẩu cho bất kỳ người dùng nào; Áp dụng tất cả bật các thiết lập khuyên dùng (tắt trình sửa file, chặn PHP trong uploads, chặn
xmlrpc.php,wp-config.phpquyền 600). - Khôi phục từng file hoặc thư mục từ snapshot tăng dần hằng đêm, trong thẻ Snapshot (sao lưu tăng dần) của trang Sao lưu; khôi phục database từ bản sao lưu database (bản hiện tại được tự sao lưu trước khi khôi phục). Bấm Tạo snapshot để lưu bản đang nhiễm trước khi dọn.
- Tường lửa ứng dụng web (ModSecurity với OWASP Core Rule Set): để Chỉ phát hiện vài ngày rồi chuyển sang Bật (chặn tấn công).
- Cập nhật an toàn: chụp snapshot, cập nhật, kiểm tra website, tự khôi phục nếu lỗi, nên bạn có thể bật cập nhật tự động mỗi đêm mà không sợ hỏng website.
Quan trọng không kém là phần nằm ngoài WordPress: mỗi tài khoản hosting chạy dưới user Linux riêng với pool PHP riêng, nên một website bị nhiễm không đọc được file của khách khác; và giới hạn số thư gửi mỗi giờ theo tài khoản ngăn website bị hack đẩy IP server vào blacklist. Chúng tôi giải thích kiến trúc này trong bài Vì sao control panel hosting không bao giờ nên chạy bằng root.
Những sai lầm làm website bị nhiễm lại
- Chỉ xoá file mà trình quét báo. Thường còn một backdoor thứ hai, được tạo đúng để sống sót sau lần dọn đầu.
- Đổi mật khẩu trước khi dọn xong và không đổi lại. Backdoor còn sót có thể đánh cắp mật khẩu mới.
- Cài lại plugin từ bản crack. Đó thường chính là nơi mã độc vào.
- Khôi phục backup mà không vá lỗ hổng. Kẻ tấn công vào lại bằng đúng con đường cũ trong vài giờ.
- Không kiểm tra database. File sạch nhưng script chèn trong bài viết vẫn chuyển hướng khách.
- Không có backup ngoài server. Nếu kẻ tấn công có quyền trên tài khoản, backup cùng tài khoản cũng không an toàn.
Kết luận
Làm sạch WordPress bị nhiễm mã độc là việc có quy trình: cách ly, lưu bằng chứng, đổi mật khẩu, khôi phục hoặc thay bằng bản chính thức, dọn những chỗ ẩn, rồi vá đúng lỗ hổng. Phòng vẫn rẻ hơn chữa: cập nhật đều, sao lưu ra ngoài server, cách ly từng tài khoản và quét định kỳ.
ZoPanel có sẵn quét mã độc, kiểm tra toàn vẹn WordPress, cập nhật an toàn có rollback và snapshot hằng đêm ngay trong gói Free. Xem bảng giá hoặc bài bảo mật VPS Ubuntu để gia cố cả server.
Câu hỏi thường gặp
Làm sao biết WordPress bị nhiễm mã độc?
Dấu hiệu thường gặp: Google cảnh báo website, khách từ Google bị chuyển hướng sang trang lạ, xuất hiện quản trị viên lạ, hàng nghìn trang lạ trong kết quả site:, file PHP trong thư mục uploads, hoặc nhà cung cấp báo server gửi spam. Chạy wp core verify-checksums và quét mã độc để xác nhận.
Có nên cài plugin bảo mật để tự dọn không?
Plugin quét giúp phát hiện, nhưng chạy bên trong chính WordPress đang bị nhiễm, nên mã độc có thể can thiệp. Kết hợp với kiểm tra từ bên ngoài: checksum bằng wp-cli, quét ở mức server và kiểm tra thủ công uploads, mu-plugins, .htaccess.
Khôi phục backup có đủ để hết mã độc không?
Chỉ khi bản backup được tạo trước thời điểm bị nhiễm, và bạn vá lỗ hổng ngay sau khi khôi phục. Mã độc có thể nằm im nhiều tuần, nên hãy kiểm tra lại bản đã khôi phục bằng checksum và quét trước khi mở website.
Bao lâu thì Google gỡ cảnh báo website bị hack?
Sau khi website sạch, gửi yêu cầu xem xét lại trong mục Vấn đề bảo mật của Google Search Console. Thời gian xử lý thay đổi theo từng trường hợp; yêu cầu bị từ chối nếu Google còn thấy mã độc, nên hãy kiểm tra kỹ trước khi gửi.
Vì sao website bị hack lại sau khi đã dọn?
Thường do còn sót backdoor, chưa vá lỗ hổng ban đầu (plugin lỗi thời, mật khẩu yếu), hoặc máy tính quản trị bị nhiễm trojan đánh cắp mật khẩu. Hãy kiểm tra cả ba trước khi coi việc dọn là xong.
Đọc tiếp

Tường lửa ứng dụng web (WAF) cho WordPress: chọn loại nào, bật ra sao
Tường lửa ứng dụng web WAF cho WordPress: so sánh WAF đám mây, WAF trên server và plugin, cách bật ModSecurity với OWASP CRS và tránh chặn nhầm.

VPS cho WordPress cấu hình bao nhiêu là đủ? Cách chọn CPU, RAM, ổ đĩa
VPS cho WordPress cấu hình bao nhiêu là đủ cho 1, 10 hay 100 website? Cách ước lượng CPU, RAM, ổ đĩa theo lưu lượng, kèm số liệu đo thực tế và lỗi cần tránh.

Control panel tốt nhất cho WordPress năm 2026
Control panel tốt nhất cho WordPress: so sánh page cache, staging, cập nhật an toàn và cách ly trên cPanel, Plesk, CyberPanel, CloudPanel và hơn nữa.