wp_options. Kedua jenis celah ini bisa berujung sama: akun administrator baru yang tidak pernah dibuat oleh pemilik situs.
Kenapa akun seperti ini sering lolos dari perhatian
hacker123. Nama yang dipakai cenderung generik, seperti wpadmin, support, atau nama yang mirip developer. Di dashboard, tampilannya sama persis dengan akun lain.
Ada dua hal lain yang membuat dashboard kurang bisa dipercaya saat situs dicurigai disusupi. Pertama, layar daftar user secara default tidak menampilkan tanggal registrasi. Kedua, malware yang lebih rapi bisa menyembunyikan akunnya dari daftar user. Caranya dengan menaruh kode di plugin atau must-use plugin (mu-plugin, yaitu plugin di folder wp-content/mu-plugins yang selalu aktif dan tidak bisa dimatikan dari dashboard). Kode itu memasang filter pada query user, sehingga akun tertentu tidak pernah muncul di layar.
Karena itu, pengecekan sebaiknya dilakukan dari CLI dengan plugin dan tema tidak ikut dimuat. Kalau kamu belum terbiasa menjalankan WP-CLI dalam mode ini, dasar-dasarnya ada di artikel Cara Cek Plugin Penyebab White Screen WordPress Lewat WP-CLI Tanpa Buka Admin.
Daftar admin dan tanggal registrasinya
--allow-root. Tapi menjalankan kode dari situs yang dicurigai disusupi sebagai root bukan kebiasaan yang baik. Di server dengan banyak situs, sudo -u namauser wp ... biasanya lebih aman.
BASH
# Semua administrator, tanpa memuat plugin dan tema
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --skip-plugins --skip-themes
# Semua user diurutkan dari registrasi terbaru, untuk melihat akun baru dengan role apa pun
wp user list --fields=ID,user_login,roles,user_registered --orderby=registered --order=DESC --skip-plugins --skip-themes
# Khusus multisite: super admin punya kendali atas seluruh network
wp super-admin list --skip-plugins --skip-themes
# Detail satu akun yang mencurigakan (ganti 7 dengan ID-nya)
wp user get 7 --fields=ID,user_login,user_email,user_registered,roles --skip-plugins --skip-themesuser_registered adalah petunjuk utama. Akun admin yang tercatat dibuat beberapa hari lalu, padahal tidak ada yang merasa menambah orang, perlu dicurigai. Ingat juga bahwa nilai ini umumnya disimpan dalam UTC, bukan zona waktu situs. Kalau kamu mau mencocokkannya dengan access log server yang biasanya mencatat waktu lokal, hitung dulu selisih zona waktunya.
Ada satu jebakan di sini. Tidak semua serangan membuat akun baru. Celah privilege escalation bisa menaikkan role akun lama, misalnya subscriber yang mendaftar setahun lalu tiba-tiba jadi administrator. Tanggal registrasinya tetap lama, jadi akun itu tidak kelihatan baru. Karena itu, perintah kedua sengaja menampilkan semua role. Perhatikan akun lama yang role-nya tidak masuk akal. WordPress tidak mencatat kapan role seseorang berubah, jadi bagian ini harus dinilai manual oleh orang yang tahu siapa saja yang seharusnya punya akses.
Cek option yang sering diubah penyerang
users_can_register menjadi 1 supaya pendaftaran publik terbuka, lalu mengubah default_role menjadi administrator. Setelah itu, siapa pun yang mendaftar lewat form registrasi biasa langsung menjadi admin. Tidak perlu exploit lanjutan.
Yang membuat ini licin: tabel wp_options tidak menyimpan waktu perubahan. Kamu bisa melihat nilai sekarang, tapi tidak bisa melihat kapan nilai itu berubah. Jadi yang bisa kita lakukan adalah membandingkan nilai sekarang dengan nilai yang seharusnya.
BASH
# Instalasi standar: subscriber
wp option get default_role --skip-plugins --skip-themes
# 0 berarti pendaftaran publik ditutup
wp option get users_can_register --skip-plugins --skip-themes
# Email admin yang menerima notifikasi penting, pastikan masih milik kamu
wp option get admin_email --skip-plugins --skip-themes
# Kode yang tetap jalan walaupun plugin dimatikan dari dashboard
wp plugin list --status=must-use --skip-plugins --skip-themes
wp plugin list --status=dropin --skip-plugins --skip-themes
# Versi plugin dan ketersediaan update
wp plugin list --fields=name,status,version,update --skip-plugins --skip-themesdefault_role berisi administrator atau editor, sementara situs bukan platform yang memang butuh itu, anggap nilai itu diubah orang lain. Kalau users_can_register bernilai 1 padahal situs tidak punya fitur member, kombinasinya makin jelas. Situs toko online atau membership memang bisa membuka registrasi. Tapi role default-nya hampir selalu customer atau subscriber, bukan admin.
Periksa juga daftar mu-plugin dan dropin (file khusus seperti object-cache.php atau advanced-cache.php di wp-content). Banyak situs memang memakai keduanya untuk cache atau fitur dari hosting. Masalahnya kalau ada file yang namanya tidak dikenali, tidak terkait plugin apa pun yang terpasang, atau tanggal modifikasinya berdekatan dengan tanggal registrasi akun mencurigakan tadi.
Dari sisi support, pertanyaan seperti ini biasanya datang dari pemilik situs yang menerima email notifikasi user baru dan mengira itu spam. Email itu sebenarnya petunjuk yang berharga. Hanya saja, email tersebut sering sudah terhapus saat situs mulai dicek.
Menentukan plugin mana yang perlu di-patch duluan
wp plugin list dengan kolom update memberi daftar plugin yang punya versi lebih baru. Tapi tidak semua update sama mendesaknya. Kalau kamu sudah menemukan akun admin liar atau option yang berubah, prioritaskan plugin yang:
- Punya advisory keamanan terbaru dengan kategori authentication bypass, privilege escalation, atau arbitrary option update.
- Menyediakan endpoint yang bisa diakses tanpa login, misalnya lewat REST API atau
admin-ajax.php. Plugin migrasi, backup, form, dan manajemen situs sering masuk kategori ini. - Sudah lama tidak diperbarui di situs kamu, sehingga selisih versinya jauh.
user_registered dengan access log web server di sekitar waktu tersebut. Cari request POST ke wp-json, admin-ajax.php, atau path plugin tertentu dari IP yang sama. Lokasi log berbeda tergantung setup. Di cPanel, Nginx, dan LiteSpeed, path-nya tidak sama, jadi cek konfigurasi server kamu dulu.
Sebelum mempercayai file plugin dan core, verifikasi checksum-nya. Perintah ini membandingkan file di server dengan versi resmi dari WordPress.org.
BASH
# File core yang berubah atau ditambahkan
wp core verify-checksums
# Plugin dari direktori WordPress.org (plugin premium atau custom tidak tercakup)
wp plugin verify-checksums --all
# Paksa logout semua sesi aktif akun mencurigakan
wp user session destroy 7 --all
# Kembalikan option ke nilai aman, sesuaikan dengan kebutuhan situs
wp option update default_role 'subscriber'
wp option update users_can_register 0Urutan penanganan yang aman
- Ambil backup file dan database dalam kondisi sekarang, termasuk yang sudah terinfeksi. Backup ini berguna untuk analisis nanti.
- Update atau nonaktifkan plugin yang rentan supaya celahnya tertutup lebih dulu.
- Kembalikan
default_roledanusers_can_registerke nilai yang benar. - Hapus sesi akun mencurigakan, lalu hapus akunnya.
- Ganti password semua admin yang sah.
- Cek ulang mu-plugin, dropin, dan hasil checksum.
wp user delete bersifat permanen dan tidak bisa dibatalkan. Tanpa opsi --reassign=<ID>, semua post milik akun itu ikut terhapus. Biasanya akun liar tidak punya post. Tetap pastikan dulu, dan pakai --reassign ke akun admin yang sah kalau ragu.
Satu catatan lagi: menghapus akun tidak menjamin situs sudah bersih. Kalau penyerang sempat punya akses admin, ia bisa saja memasang plugin, mengedit file tema, atau menanam backdoor di wp-content. Pada kasus seperti ini, menganggap situs sudah aman hanya karena akunnya hilang adalah kesimpulan yang terlalu cepat.
Intinya, jangan menilai situs dari layar Users di dashboard saja. Jalankan daftar admin dengan --skip-plugins, perhatikan user_registered dan role akun lama, pastikan default_role dan users_can_register masih sesuai, lalu tutup celahnya sebelum membersihkan akun. Jadikan pengecekan ini rutin setiap kali ada advisory kritis untuk plugin yang kamu pakai. Lebih baik dicek sekarang daripada nanti saat email notifikasi user baru sudah terhapus.