Bảo mật và sao lưu · 10 phút đọc · 2026-09-17
Website WordPress bị hack: tự kiểm dấu vết bằng WP-CLI
Success chỉ đúng với phép kiểm đang chạy, không đồng nghĩa toàn bộ website đã sạch. WP-CLI giúp đối chiếu checksum, đọc tài khoản admin và lưu dấu vết để kiểm tra lại sau mỗi lần sửa.

- Tác giả
- Quản trị viên
- Đăng ngày
- 2026-09-17
- Cập nhật
- 2026-09-17
- Thời gian đọc
- 10 phút đọc
- Tất cả bài viết
Website bị hack phải làm sao? Trước khi sửa bất cứ thứ gì, bạn cần biết cái gì đã bị thay đổi. Bài này là bốn phép kiểm bằng WP-CLI để tìm dấu vết trên một website WordPress bị hack, kèm thứ mỗi phép bắt được và thứ nó bỏ lọt.
Để đo cho thật, mình dựng một bản sao WordPress 7.1 trên máy rồi tự cài năm "dấu vết" vô hại, mô phỏng những thay đổi hay gặp khi site bị xâm nhập. Không có mã độc thật nào: mỗi tệp thêm vào chỉ in ra một câu. Chạy xong bốn phép kiểm không có nghĩa là site sạch 100%. Nó chỉ cho biết những chỗ mà bốn phép này nhìn tới.
Trước khi kiểm: làm trên bản sao
- Sao lưu đủ cơ sở dữ liệu và thư mục
wp-contentcủa site đang có vấn đề, theo bài Khôi phục website WordPress: sao lưu đủ hai phần. Bản sao lưu này là bằng chứng của hiện trạng, đừng ghi đè nó. - Dựng bản sao từ bản sao lưu đó và kiểm trên bản sao.
Lý do: các lệnh dọn dẹp ở cuối bài ghi đè tệp lõi, cài lại plugin và xoá tài khoản. Làm sai trên bản sao thì dựng lại bản sao là xong. Làm sai trên site thật thì bạn mất luôn dấu vết cần tìm.
Năm dấu vết mình cài để thử
- Thêm một dòng chú thích vào cuối tệp lõi
wp-includes/class-wp-embed.php. - Thêm một tệp lạ
wp-includes/wp-thu-la.php. - Thêm một tệp
wp-content/uploads/2026/09/cache.php. - Thêm một dòng chú thích vào tệp chính của plugin Query Monitor.
- Tạo thêm một tài khoản quản trị tên
quantri2.
Trước khi cài, cả bốn phép kiểm bên dưới đều sạch.
Kiểm 1: tệp lõi WordPress có bị sửa hay bị thêm không
wp core verify-checksumsLệnh này so từng tệp lõi với bản gốc của đúng phiên bản bạn đang chạy. Site sạch ra: "Success: WordPress installation verifies against checksums."
Sau khi cài dấu vết:
Warning: File doesn't verify against checksum: wp-includes/class-wp-embed.php
Warning: File should not exist: wp-includes/wp-thu-la.php
Error: WordPress installation doesn't verify against checksums.- Bắt được: dấu vết 1 (tệp lõi bị sửa) và dấu vết 2 (tệp lạ trong thư mục lõi).
- Bỏ lọt: tệp PHP trong
uploads. Lệnh này không nhắc gì tới nó, vìuploadskhông phải tệp lõi.
Kiểm 2: plugin có bị sửa không
wp plugin verify-checksums --allSite sạch ra "Success: Verified 3 of 3 plugins." Sau khi cài dấu vết:
query-monitor query-monitor.php Checksum does not match
Error: Only verified 2 of 3 plugins (1 failed).- Bắt được: dấu vết 4.
- Giới hạn: lệnh so với bản trên kho plugin của WordPress. Plugin mua ngoài hay tự viết thì không có bản gốc để so; mình chưa đo ca đó.
Kiểm 3: WordPress bị hack tạo tài khoản admin lạ
wp user list --role=administrator --fields=ID,user_login,user_registeredSite sạch chỉ có một dòng 1 demo 2026-09-07 03:55:28. Sau khi cài dấu vết, có thêm 2 quantri2 2026-09-17 03:22:02. Cột ngày tạo là chỗ nên nhìn: tài khoản quản trị sinh ra đúng quãng site có vấn đề là tài khoản đáng nghi nhất.
Một chi tiết dễ đọc nhầm: cột user_registered ghi theo giờ UTC. Mình tạo quantri2 lúc khoảng 10 giờ 22 sáng giờ Việt Nam, còn cột này ghi 03:22:02, lệch đúng 7 tiếng. Khi so với nhật ký hay thời điểm bạn nhận ra sự cố, nhớ cộng thêm 7 tiếng.
Trong wp-admin, trang Tài khoản cho thấy đúng điều đó:

- Bắt được: dấu vết 5.
Kiểm 4: tệp PHP nằm trong thư mục uploads
find wp-content/uploads -name "*.php"Thư mục uploads là chỗ chứa ảnh và tệp tải lên. Trên site sạch, lệnh này không ra dòng nào. Sau khi cài dấu vết, nó ra wp-content/uploads/2026/09/cache.php.
Đây là phép duy nhất trong bốn phép bắt được dấu vết 3. Và dấu vết này đáng lo nhất, vì mình gọi thử tệp đó qua trình duyệt thì máy chủ trả 200 và chạy nó thật:

Chặn PHP chạy trong uploads
Trên máy chủ Apache, tạo tệp wp-content/uploads/.htaccess với nội dung:
<FilesMatch "\.php$">
Require all denied
</FilesMatch>Gọi lại đúng tệp đó:

- Tệp PHP trong
uploads: 403. - Ảnh trong
uploads: vẫn 200.
Cách này chỉ áp dụng khi máy chủ là Apache và đọc tệp .htaccess. Mình chưa thử trên Nginx.
Cách xử lý website WordPress bị hack sau khi thấy dấu vết: đọc kỹ chữ Success
Mình dọn năm dấu vết và đo từng bước. Có hai chỗ dòng "Success" dễ làm bạn tưởng đã xong.
1. Cài lại plugin bị sửa
wp plugin install query-monitor --forceSau đó "Success: Verified 3 of 3 plugins", và plugin vẫn giữ trạng thái đang bật.
2. Tải lại lõi WordPress
wp core download --skip-content --force --version=7.1 --locale=viĐổi 7.1 và vi cho đúng phiên bản và ngôn ngữ site của bạn. Lần đầu lệnh báo "Error: Extracting a zip file requires ZipArchive." vì PHP dòng lệnh chưa bật extension zip. Mình chạy lại với php -d extension=zip thì được, mất 16.567 ms.
Kết quả:
- Tệp lõi bị sửa (dấu vết 1) được phục hồi, dòng chú thích biến mất.
- Tệp lạ
wp-thu-la.php(dấu vết 2) vẫn còn nguyên. Tải lại lõi chỉ ghi đè tệp gốc, không xoá tệp thêm vào.
Chạy lại kiểm 1 lúc đó:
Warning: File should not exist: wp-includes/wp-thu-la.php
Success: WordPress installation verifies against checksums.Dòng cuối là Success, dù tệp lạ vẫn nằm trong thư mục lõi. Đọc lướt dòng cuối là bỏ sót. Phải xoá tay tệp đó rồi chạy lại, đến khi không còn dòng Warning nào.
3. Xoá tệp PHP trong uploads và tài khoản lạ
rm wp-content/uploads/2026/09/cache.php
wp user delete 2 --reassign=1 --yes--reassign=1 chuyển bài viết (nếu có) của tài khoản bị xoá sang tài khoản số 1. Chạy lại cả bốn phép kiểm: tất cả sạch, trang chủ trả 200.
Tóm tắt: dấu vết nào, phép kiểm nào bắt
- Tệp lõi bị sửa: kiểm 1.
- Tệp lạ trong thư mục lõi: kiểm 1, nhưng sau khi tải lại lõi chỉ còn là một dòng Warning trước chữ Success.
- Tệp PHP trong uploads: chỉ kiểm 4.
- Plugin bị sửa: kiểm 2.
- Tài khoản quản trị lạ: kiểm 3.
Những gì mình chưa kiểm
- Chưa đụng mã độc thật, chưa thử plugin bảo mật hay dịch vụ quét nào.
- Chưa kiểm dấu vết nằm trong cơ sở dữ liệu, ví dụ đoạn mã chèn vào bài viết hay một tuỳ chọn lạ.
- Chưa kiểm theme, chưa thử Nginx, chưa đo plugin không có trên kho plugin của WordPress.
- Chưa đo chuyện khôi phục website WordPress bị hack từ bản sao lưu cũ. Ca đó cần chọn bản sao lưu được tạo trước khi site bị xâm nhập, và mình chưa có số liệu cho việc chọn đó.