NỘI DUNG
Khi một website WordPress có dấu hiệu bị nhiễm mã độc, redirect sang trang lạ, gửi mail spam hoặc bị Google cảnh báo nguy hiểm, việc đầu tiên không nên làm là xoá file vội vàng. Thay vào đó, quản trị viên nên kiểm tra có hệ thống để xác định mã độc nằm ở đâu, lây qua đường nào và cần xử lý phần nào trước. Trong bài viết này, mình sẽ hướng dẫn cách kiểm tra mã độc WordPress bằng WP-CLI theo hướng thực tế, có lệnh mẫu, ví dụ kết quả và các vị trí thường bị hacker chèn mã độc.

WP-CLI là gì và vì sao nên dùng để kiểm tra mã độc?
WP-CLI là công cụ dòng lệnh giúp quản trị WordPress trực tiếp qua terminal. Thay vì đăng nhập wp-admin để kiểm tra từng phần, bạn có thể dùng WP-CLI để xem version, plugin, theme, user, database, cron và nhiều thành phần khác.
Với việc kiểm tra mã độc WordPress, WP-CLI có nhiều lợi thế:
- Kiểm tra nhanh WordPress core có bị sửa file không.
- Xem danh sách plugin/theme đang kích hoạt.
- Kiểm tra plugin có khớp mã nguồn gốc trên WordPress.org không.
- Tìm user admin bất thường.
- Tìm nội dung nghi ngờ trong database.
- Làm việc được ngay cả khi wp-admin bị lỗi hoặc bị hacker chặn.
WP-CLI không thay thế hoàn toàn các công cụ malware scanner chuyên dụng như Wordfence, Imunify360, Maldet hoặc ClamAV. Tuy nhiên, WP-CLI rất hữu ích để audit nhanh và xác định hướng xử lý ban đầu.
Chuẩn bị trước khi kiểm tra website WordPress
Trước khi chạy bất kỳ lệnh kiểm tra nào, bạn cần SSH vào server và chuyển đến đúng thư mục chứa mã nguồn WordPress.
Ví dụ website nằm tại:
/home/user/domains/example.com/public_html
Bạn chạy:
cd /home/user/domains/example.com/public_html
Sau đó kiểm tra WP-CLI có hoạt động không:
wp --info
Nếu server có nhiều PHP version, có thể cần gọi WP-CLI với PHP cụ thể:
php -d memory_limit=512M $(which wp) --info
Tiếp theo, kiểm tra thư mục hiện tại có phải WordPress không:
wp core is-installed
Nếu lệnh trả về thành công, nghĩa là WP-CLI nhận diện được website WordPress.
Nên backup trước khi kiểm tra không?
Nếu chỉ chạy lệnh đọc dữ liệu như wp core verify-checksums, wp plugin list, wp user list thì chưa bắt buộc backup. Tuy nhiên, trước khi xoá file, sửa database hoặc thay đổi plugin/theme, bạn nên backup đầy đủ.
wp db export backup-before-malware-check.sql
tar -czf backup-public_html-before-malware-check.tar.gz .
Lưu ý: Không nên lưu file backup .sql, .zip, .tar.gz trực tiếp trong thư mục public_html quá lâu. Nếu backup nằm trong webroot, cần di chuyển ra ngoài hoặc chặn truy cập public.

Kiểm tra thông tin WordPress bằng WP-CLI
Đầu tiên, hãy kiểm tra version WordPress, site URL và trạng thái cơ bản:
wp core version
wp option get siteurl
wp option get home
Ví dụ kết quả:
6.6.2
https://example.com
https://example.com
Nếu siteurl hoặc home bị đổi sang domain lạ, đây là dấu hiệu cần kiểm tra ngay.
Kiểm tra checksum WordPress core
Đây là bước quan trọng nhất khi kiểm tra mã độc WordPress bằng WP-CLI.
wp core verify-checksums
Nếu WordPress core sạch, bạn sẽ thấy kết quả tương tự:
Success: WordPress installation verifies against checksums.
Nếu có file core bị sửa, thiếu hoặc lạ, WP-CLI có thể báo:
Warning: File doesn't verify against checksum: wp-includes/load.php
Warning: File should not exist: wp-includes/random-file.php
Error: WordPress installation doesn't verify against checksums.
| Kết quả | Ý nghĩa |
|---|---|
| File doesn’t verify | File core bị thay đổi so với bản gốc |
| File should not exist | Có file lạ nằm trong core |
| File missing | File core bị thiếu |
| Success | Core khớp checksum |
Nếu chỉ WordPress core bị nhiễm, cách xử lý thường là thay lại core sạch. Tuy nhiên, không nên xoá ngay nếu chưa backup.
wp core download --force --skip-content
Lệnh này sẽ thay lại core WordPress nhưng không đụng vào wp-content. Dù vậy, vẫn nên backup trước khi chạy trên website production.
Kiểm tra plugin bằng WP-CLI
Plugin là một trong những nguồn lây nhiễm phổ biến nhất, đặc biệt là plugin cũ, plugin nulled hoặc plugin không rõ nguồn gốc.
wp plugin list
Các plugin cần chú ý:
- Plugin tên lạ.
- Plugin không nhớ đã cài.
- Plugin không có trên WordPress.org.
- Plugin nulled.
- Plugin lâu không cập nhật.
- Plugin nằm trong thư mục nhưng không hiển thị ở wp-admin.
Kiểm tra checksum plugin
Với plugin trên WordPress.org, bạn có thể chạy:
wp plugin verify-checksums --all
Nếu plugin sạch:
Success: Verified 12 of 12 plugins.
Nếu có file bị sửa:
Warning: File doesn't verify against checksum: contact-form-7/includes/file.php
Warning: File should not exist: contact-form-7/includes/class-backdoor.php
Plugin premium hoặc plugin tự viết có thể không kiểm tra checksum được. Đây chưa chắc là mã độc, nhưng cần kiểm tra thủ công hoặc so sánh với bản gốc từ nhà cung cấp.
Kiểm tra theme đang sử dụng
wp theme list
wp theme list --status=active
Theme bị nhiễm mã độc thường có dấu hiệu:
functions.phpbị chèn code lạ.- File PHP lạ trong thư mục theme.
- Có thư mục
cache,vendor,incchứa file đáng ngờ. - Theme nulled có backdoor.
- Code obfuscate bằng
eval,base64_decode,gzinflate.
Nếu theme từ WordPress.org, có thể kiểm tra checksum:
wp theme verify-checksums --all
Tìm file PHP lạ trong thư mục uploads
Theo nguyên tắc bảo mật, thư mục wp-content/uploads không nên có file PHP. Nếu có file .php, .phtml, .phar trong uploads, khả năng cao là webshell hoặc backdoor.
find wp-content/uploads -type f \( -name "*.php" -o -name "*.phtml" -o -name "*.phar" \)
Ví dụ kết quả đáng nghi:
wp-content/uploads/2024/10/about.php
wp-content/uploads/2024/10/class-wp-cache.php
wp-content/uploads/2025/01/image.php
Một số hacker đặt tên file rất giống file hợp lệ như class-wp.php, wp-cache.php, autoload.php, index.php, license.php.

Tìm các hàm PHP nguy hiểm thường gặp trong mã độc
Nhiều mã độc PHP dùng các hàm để che giấu hoặc thực thi code từ xa. Bạn có thể tìm nhanh bằng:
grep -RInE "eval\(|base64_decode|gzinflate|str_rot13|shell_exec|passthru|system\(|assert\(|preg_replace.*\/e" .
Nếu thư mục lớn, có thể giới hạn phạm vi:
grep -RInE "eval\(|base64_decode|gzinflate|shell_exec|passthru|system\(" wp-content
Không phải cứ thấy base64_decode là chắc chắn mã độc. Một số plugin hợp lệ cũng dùng encode/decode. Tuy nhiên, các mẫu sau rất đáng nghi:
eval(base64_decode(...));
gzinflate(base64_decode(...));
$_POST['cmd'];
$_GET['exec'];
$_REQUEST['pass'];
Tìm file mới bị sửa gần đây
find . -type f -mtime -7
find . -type f -name "*.php" -mtime -7
find . -type f -perm /111
Kiểm tra user admin bất thường
Hacker thường tạo thêm user admin để quay lại sau khi bạn dọn mã độc.
wp user list
wp user list --role=administrator
Nếu thấy admin lạ, cần xác minh:
- Ai tạo user này?
- Email có thuộc công ty không?
- Thời điểm tạo có trùng thời điểm website bị hack không?
wp user meta list 9
Không xoá user admin ngay nếu chưa xác nhận và chưa backup database. Có trường hợp user là tài khoản kỹ thuật hợp lệ.
Kiểm tra database WordPress bằng WP-CLI
Mã độc WordPress không chỉ nằm trong file. Rất nhiều trường hợp hacker chèn script vào database, đặc biệt là wp_options, wp_posts, widget, custom HTML, theme options hoặc plugin settings.
Tìm script lạ trong bài viết
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%<script%' LIMIT 20;"
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%iframe%' LIMIT 20;"
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%document.write%' LIMIT 20;"
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%base64%' LIMIT 20;"
Tìm mã lạ trong wp_options
Trước tiên lấy prefix database:
wp db prefix
Nếu prefix là wp_, kiểm tra options:
wp db query "SELECT option_name FROM wp_options WHERE option_value LIKE '%<script%' LIMIT 30;"
wp db query "SELECT option_name FROM wp_options WHERE option_value LIKE '%iframe%' LIMIT 30;"
Nếu thấy các option như widget_custom_html hoặc theme_mods_ten-theme chứa script lạ, bạn cần kiểm tra kỹ vì mã độc có thể được render ra frontend từ widget hoặc theme option.
Kiểm tra cron job WordPress bất thường
WordPress có hệ thống cron nội bộ. Một số mã độc cài cron để tự tải lại backdoor sau khi bị xoá.
wp cron event list
wp cron event list --fields=hook,next_run,recurrence
Cần chú ý các hook lạ, tên khó hiểu hoặc không thuộc plugin nào. Ví dụ:
backdoor_update_event
wp_ajax_cache_sync
license_check_daily
remote_loader_event
Nếu nghi ngờ cron độc hại, cần xác định nó được tạo từ plugin/theme/file nào trước khi xoá.
Kiểm tra file cấu hình quan trọng
Một số file thường bị chèn mã độc:
index.phpwp-config.php.htaccesswp-blog-header.phpfunctions.phpwp-settings.php
Kiểm tra .htaccess:
sed -n '1,160p' .htaccess
Dấu hiệu đáng nghi:
RewriteCond %{HTTP_USER_AGENT} google [NC]
RewriteRule ^(.*)$ https://domain-la.example/$1 [R=302,L]
Kiểm tra wp-config.php:
sed -n '1,180p' wp-config.php
Không chia sẻ nội dung wp-config.php công khai vì file này chứa DB credentials, salts và thông tin nhạy cảm.
Checklist kiểm tra nhanh mã độc WordPress bằng WP-CLI
cd /home/user/domains/example.com/public_html
wp core verify-checksums
wp plugin list
wp plugin verify-checksums --all
wp theme list
wp user list --role=administrator
find wp-content/uploads -type f \( -name "*.php" -o -name "*.phtml" -o -name "*.phar" \)
grep -RInE "eval\(|base64_decode|gzinflate|shell_exec|passthru|system\(|assert\(" wp-content
find . -type f -name "*.php" -mtime -7
wp cron event list
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%<script%' LIMIT 20;"
wp db query "SELECT option_name FROM wp_options WHERE option_value LIKE '%<script%' LIMIT 30;"
Bảng tổng hợp vị trí mã độc thường gặp
| Vị trí | Dấu hiệu | Cách kiểm tra |
|---|---|---|
| WordPress core | File core bị sửa | wp core verify-checksums |
| Plugin | File plugin bị chèn code | wp plugin verify-checksums --all |
| Theme | functions.php có code lạ | Kiểm tra theme active |
| Uploads | Có file .php | find wp-content/uploads -name "*.php" |
| Database | Có script/iframe lạ | wp db query |
| User | Admin lạ | wp user list --role=administrator |
| Cron | Hook lạ | wp cron event list |
| .htaccess | Redirect lạ | Xem nội dung .htaccess |
Sau khi phát hiện mã độc nên làm gì?
Khi phát hiện dấu hiệu nhiễm mã độc, không nên chỉ xoá file lạ rồi kết thúc. Bạn cần xử lý theo quy trình:
- Backup hiện trạng.
- Xác định nguồn nhiễm.
- Gỡ mã độc khỏi file/database.
- Thay core/plugin/theme bằng bản sạch.
- Xoá user admin lạ nếu xác định không hợp lệ.
- Cập nhật toàn bộ WordPress core, plugin, theme.
- Đổi mật khẩu admin, hosting, database, FTP/SFTP.
- Rotate WordPress salts.
- Chặn PHP chạy trong uploads.
- Kiểm tra lại log truy cập.
- Clear cache WordPress/CDN.
- Theo dõi tái nhiễm trong vài ngày.
Ví dụ chặn PHP trong uploads với Apache .htaccess:
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
Với Nginx, có thể thêm rule:
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
Không tự chỉnh cấu hình Nginx/Apache trên production nếu chưa backup và chưa kiểm tra syntax config.
Kết luận
Kiểm tra mã độc WordPress bằng WP-CLI là bước rất hiệu quả khi website có dấu hiệu bị hack, redirect lạ, gửi spam hoặc bị cảnh báo bảo mật. Chỉ với vài lệnh cơ bản, bạn có thể kiểm tra WordPress core, plugin, theme, user admin, cron, database và file đáng ngờ trong uploads.
Tuy nhiên, WP-CLI chỉ là một phần trong quy trình xử lý mã độc. Để xử lý triệt để, bạn cần kết hợp kiểm tra log, quét file, so sánh mã nguồn gốc, rà soát database và hardening lại website sau khi dọn sạch.
Nếu bạn đang quản trị nhiều website WordPress, hãy lưu lại checklist trong bài này để dùng khi cần kiểm tra nhanh sự cố bảo mật.
FAQ
WP-CLI có quét được toàn bộ mã độc WordPress không?
Không hoàn toàn. WP-CLI giúp kiểm tra nhiều dấu hiệu quan trọng như checksum core, plugin, theme, user, database và cron. Tuy nhiên, để quét sâu mã độc, bạn nên kết hợp thêm Wordfence, Imunify360, Maldet, ClamAV hoặc kiểm tra thủ công.
Lệnh wp core verify-checksums báo lỗi có chắc là website bị hack không?
Không phải lúc nào cũng chắc chắn. Một số website có thể chỉnh sửa core thủ công, dù đây là thực hành không tốt. Tuy nhiên, nếu file core bị thay đổi không rõ lý do hoặc có file lạ trong wp-admin, wp-includes, bạn nên xem đó là dấu hiệu nghiêm trọng.
Có nên xoá ngay file PHP trong uploads không?
Không nên xoá ngay nếu chưa backup và chưa kiểm tra nội dung. File PHP trong uploads rất đáng nghi, nhưng vẫn nên backup trước để có bằng chứng và có thể khôi phục nếu xoá nhầm.
Plugin premium có kiểm tra checksum bằng WP-CLI được không?
Thông thường là không. WP-CLI chỉ verify checksum tốt với plugin/theme có trên WordPress.org. Với plugin premium, bạn cần so sánh với file gốc từ nhà cung cấp.
Website đã dọn mã độc nhưng vẫn bị nhiễm lại là do đâu?
Nguyên nhân thường gặp là còn backdoor chưa xoá, user admin lạ, plugin/theme lỗi thời, password bị lộ, cron độc hại hoặc file PHP trong uploads vẫn còn hoạt động.
Hashtag: #WordPress #WPCLI #BaoMatWordPress #MaDocWebsite #WordPressMalware #WebSecurity #HostingSecurity #Sysadmin #WebsiteBiHack #KiemTraMaDoc
Với kinh nghiệm thực chiến từ việc tiếp xúc hàng ngày với vô vàn vấn đề về Website, Hosting, VPS, Server tại Phòng Kỹ thuật AZDIGI, mình luôn ấp ủ niềm đam mê chia sẻ kiến thức.
Mình xây dựng các blog không chỉ để tự trau dồi kỹ năng mà còn để cung cấp những tài liệu, hướng dẫn hữu ích nhất đến cộng đồng. Rất mong nhận được sự quan tâm của các bạn!
Để lại thông tin, mình sẽ phản hồi ngay.
