Detecting malware on a WordPress site from the command prompt can be a useful method for webmasters and security professionals who prefer command-line interfaces. In this blog post, we will discuss different terminal commands that can be used to detect malware on a WordPress site.
Requirements
To make the most of the following article, we expect that you have the following:
- A web hosting account or server with SSH access.
- A SSH client already installed in your computer.
- You have basic PHP knowledge.
In this tutorial we will be using the following services & tools:


iTerm2 for MacOS as our SSH client
Kinsta as our Premium Managed hosting provider for WordPress , iTerm2 for MacOS as our SSH client.
Step 1: Connect to the Server
First, you need to connect to the server hosting the WordPress site using an SSH client. You will need to provide your credentials to log in. Once logged in, navigate to the WordPress site directory.
Step 2: Check for Suspicious Files
You can use the following commands to check for suspicious files on your WordPress site:
- List all files and directories in the current directory:
ls -la
This command will list all files and directories in the current directory, including hidden files.
Please be aware that WordPress by default has 3 different folders: wp-admin, wp-content & wp-includes. This means that any other folder contained there might be suspicious if you did not create it.
Below an example on how a clean installation should look like:
$ ls -la
total 331
drwxrwxr-x 5 wpmechanicsblog wpmechanicsblog 21 Apr 28 21:34 .
drwxr-xr-x 8 wpmechanicsblog wpmechanicsblog 30 Apr 28 21:33 ..
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 405 Apr 28 21:34 index.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 19915 Apr 28 21:34 license.txt
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 7402 Apr 28 21:34 readme.html
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 7205 Apr 28 21:34 wp-activate.php
drwxrwxr-x 9 wpmechanicsblog wpmechanicsblog 101 Apr 28 21:34 wp-admin
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 351 Apr 28 21:34 wp-blog-header.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 2338 Apr 28 21:34 wp-comments-post.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 3013 Apr 28 21:34 wp-config-sample.php
drwxrwxr-x 4 wpmechanicsblog wpmechanicsblog 5 Apr 28 21:34 wp-content
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 5536 Apr 28 21:34 wp-cron.php
drwxrwxr-x 28 wpmechanicsblog wpmechanicsblog 251 Apr 28 21:34 wp-includes
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 2502 Apr 28 21:34 wp-links-opml.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 3792 Apr 28 21:34 wp-load.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 49330 Apr 28 21:34 wp-login.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 8541 Apr 28 21:34 wp-mail.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 24993 Apr 28 21:34 wp-settings.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 34350 Apr 28 21:34 wp-signup.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 4889 Apr 28 21:34 wp-trackback.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 3238 Apr 28 21:34 xmlrpc.php
Sometimes malware is easy to spot on this step, here are some simple Indicators of Compromise to have in mind:
- The main file index.php size should be between 405 and 420 bytes. Any other size on this file, means that the file was intentionally modified. So be sure to check it contents with your favorite text editor such as vim, nano or using other terminal commands such as cat, less or more.
- Folders with random names is another good indication that you have malware. See the example below that contains 3 directories with random names 7kafDso, af6jdh & Dog7ndw:
$ ls -la
total 332
drwxrwxr-x 8 wpmechanicsblog wpmechanicsblog 24 Apr 28 21:40 .
drwxr-xr-x 8 wpmechanicsblog wpmechanicsblog 30 Apr 28 21:33 ..
drwxrwxr-x 2 wpmechanicsblog wpmechanicsblog 2 Apr 28 21:40 7kafDso
drwxrwxr-x 2 wpmechanicsblog wpmechanicsblog 2 Apr 28 21:40 af6jdh
drwxrwxr-x 2 wpmechanicsblog wpmechanicsblog 2 Apr 28 21:40 Dog7ndw
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 405 Apr 28 21:34 index.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 19915 Apr 28 21:34 license.txt
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 7402 Apr 28 21:34 readme.html
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 7205 Apr 28 21:34 wp-activate.php
drwxrwxr-x 9 wpmechanicsblog wpmechanicsblog 101 Apr 28 21:34 wp-admin
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 351 Apr 28 21:34 wp-blog-header.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 2338 Apr 28 21:34 wp-comments-post.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 3013 Apr 28 21:34 wp-config-sample.php
drwxrwxr-x 4 wpmechanicsblog wpmechanicsblog 5 Apr 28 21:34 wp-content
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 5536 Apr 28 21:34 wp-cron.php
drwxrwxr-x 28 wpmechanicsblog wpmechanicsblog 251 Apr 28 21:34 wp-includes
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 2502 Apr 28 21:34 wp-links-opml.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 3792 Apr 28 21:34 wp-load.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 49330 Apr 28 21:34 wp-login.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 8541 Apr 28 21:34 wp-mail.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 24993 Apr 28 21:34 wp-settings.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 34350 Apr 28 21:34 wp-signup.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 4889 Apr 28 21:34 wp-trackback.php
-rw-rw-r-- 1 wpmechanicsblog wpmechanicsblog 3238 Apr 28 21:34 xmlrpc.php
- There can also be filenames with random names that could be malware, be sure that all WordPress core files that sit on the public directory start with wp-, if you have files with other naming convention, then they should be easy to spot just by doing the directory listing. In the example below there is a file called options.php. This file is not part of WordPress because it does not start with wp- and it’s not WordPress main index.php file.
$ ls -la
total 337
drwxrwxr-x 8 malwador malwador 25 Apr 28 21:45 .
drwxr-xr-x 8 malwador www-data 30 Apr 28 21:33 ..
drwxrwxr-x 2 malwador malwador 2 Apr 28 21:40 7kafDso
drwxrwxr-x 2 malwador malwador 2 Apr 28 21:40 af6jdh
drwxrwxr-x 2 malwador malwador 2 Apr 28 21:40 Dog7ndw
-rw-rw-r-- 1 malwador malwador 405 Apr 28 21:34 index.php
-rw-rw-r-- 1 malwador malwador 19915 Apr 28 21:34 license.txt
-rw-rw-r-- 1 malwador malwador 1102 Apr 28 21:45 options.php
-rw-rw-r-- 1 malwador malwador 7402 Apr 28 21:34 readme.html
-rw-rw-r-- 1 malwador malwador 7205 Apr 28 21:34 wp-activate.php
drwxrwxr-x 9 malwador malwador 101 Apr 28 21:34 wp-admin
-rw-rw-r-- 1 malwador malwador 351 Apr 28 21:34 wp-blog-header.php
-rw-rw-r-- 1 malwador malwador 2338 Apr 28 21:34 wp-comments-post.php
-rw-rw-r-- 1 malwador malwador 3013 Apr 28 21:34 wp-config-sample.php
drwxrwxr-x 4 malwador malwador 5 Apr 28 21:34 wp-content
-rw-rw-r-- 1 malwador malwador 5536 Apr 28 21:34 wp-cron.php
drwxrwxr-x 28 malwador malwador 251 Apr 28 21:34 wp-includes
-rw-rw-r-- 1 malwador malwador 2502 Apr 28 21:34 wp-links-opml.php
-rw-rw-r-- 1 malwador malwador 3792 Apr 28 21:34 wp-load.php
-rw-rw-r-- 1 malwador malwador 49330 Apr 28 21:34 wp-login.php
-rw-rw-r-- 1 malwador malwador 8541 Apr 28 21:34 wp-mail.php
-rw-rw-r-- 1 malwador malwador 24993 Apr 28 21:34 wp-settings.php
-rw-rw-r-- 1 malwador malwador 34350 Apr 28 21:34 wp-signup.php
-rw-rw-r-- 1 malwador malwador 4889 Apr 28 21:34 wp-trackback.php
-rw-rw-r-- 1 malwador malwador 3238 Apr 28 21:34 xmlrpc.php
- List all files and directories in the current directory sorted by modification time:
ls -lat
This command will list all files and directories in the current directory, sorted by modification time, with the most recently modified files listed first.
See the example below:
# ls -lat
total 337
drwxrwxr-x 8 malwador malwador 25 Apr 28 22:13 .
-rw-rw-r-- 1 malwador malwador 4024 Apr 28 22:13 wp-load.php
-rw-rw-r-- 1 malwador malwador 1102 Apr 28 21:45 options.php
drwxrwxr-x 2 malwador malwador 2 Apr 28 21:40 7kafDso
drwxrwxr-x 2 malwador malwador 2 Apr 28 21:40 Dog7ndw
drwxrwxr-x 2 malwador malwador 2 Apr 28 21:40 af6jdh
-rw-rw-r-- 1 malwador malwador 7402 Apr 28 21:34 readme.html
-rw-rw-r-- 1 malwador malwador 7205 Apr 28 21:34 wp-activate.php
drwxrwxr-x 9 malwador malwador 101 Apr 28 21:34 wp-admin
-rw-rw-r-- 1 malwador malwador 5536 Apr 28 21:34 wp-cron.php
-rw-rw-r-- 1 malwador malwador 34350 Apr 28 21:34 wp-signup.php
-rw-rw-r-- 1 malwador malwador 405 Apr 28 21:34 index.php
drwxrwxr-x 28 malwador malwador 251 Apr 28 21:34 wp-includes
-rw-rw-r-- 1 malwador malwador 2502 Apr 28 21:34 wp-links-opml.php
-rw-rw-r-- 1 malwador malwador 24993 Apr 28 21:34 wp-settings.php
-rw-rw-r-- 1 malwador malwador 19915 Apr 28 21:34 license.txt
-rw-rw-r-- 1 malwador malwador 351 Apr 28 21:34 wp-blog-header.php
-rw-rw-r-- 1 malwador malwador 49330 Apr 28 21:34 wp-login.php
-rw-rw-r-- 1 malwador malwador 8541 Apr 28 21:34 wp-mail.php
-rw-rw-r-- 1 malwador malwador 4889 Apr 28 21:34 wp-trackback.php
drwxrwxr-x 4 malwador malwador 5 Apr 28 21:34 wp-content
-rw-rw-r-- 1 malwador malwador 2338 Apr 28 21:34 wp-comments-post.php
-rw-rw-r-- 1 malwador malwador 3013 Apr 28 21:34 wp-config-sample.php
-rw-rw-r-- 1 malwador malwador 3238 Apr 28 21:34 xmlrpc.php
drwxr-xr-x 8 malwador www-data 30 Apr 28 21:33 ..
On this example we can see that on top we have the wp-load.php, which is a core WordPress file and having such file recently modified is never good news.
Below are some Indicators of Compromise to consider when you’re reviewing timestamps:
- All core WordPress files should have the same time-stamp. If any has a different one, it means it was manually modified and it will require our review. The only file that its usual to have a different time-stamp is wp-config.php, this is because this file is edited after WordPress was installed since the last step is to add the MySQL database credentials.
- Review all the most recent edited files.
- Depending on your server or hosting provider, you can use the command stat to gather further information about the file. in the example below you can see further information about changes along with its timestamps.
# stat wp-load.php
File: wp-load.php
Size: 4024 Blocks: 9 IO Block: 4096 regular file
Device: 100078h/1048696d Inode: 547415 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/wpmechanicsblog) Gid: ( 1003/wpmechanicsblog)
Access: 2023-04-28 22:13:15.047832117 +0000
Modify: 2023-04-28 21:18:40.953886652 +0000
Change: 2023-04-28 21:18:40.953886652 +0000
Birth: -
- List all PHP files in the current directory:
find . -name "*.php"
This command will list all PHP files in the current directory and its subdirectories.
- Check for files that have been modified in the last 24 hours:
find . -type f -mtime -1 -ls
This command will list all files in the current directory and its subdirectories that have been modified in the last 24 hours.
- Check for files that have been modified in the last 24 hours and have the
.php
extension:
find . -type f -name "*.php" -mtime -1 -ls
This command will list all PHP files in the current directory and its subdirectories that have been modified in the last 24 hours.
Step 3: Check for Suspicious Code
Once you have identified suspicious files, you can use the following commands to check for suspicious code:
- Search for a specific string of code in a file:
grep -r "string" /path/to/directory
This command will search for the specified string of code in all files in the specified directory and its subdirectories.
- Search for a specific string of code in all PHP files in a directory:
grep -r "string" --include="*.php" /path/to/directory
This command will search for the specified string of code in all PHP files in the specified directory and its subdirectories.
- Search for a specific string of code in all PHP files in a directory and output the results to a file:
grep -r "string" --include="*.php" /path/to/directory > output.txt
This command will search for the specified string of code in all PHP files in the specified directory and its subdirectories and output the results to a file named output.txt
.
Conclusion
Using the command prompt to detect malware on a WordPress site can be an effective method for webmasters and security professionals. By using the above-mentioned commands, you can quickly and easily identify suspicious files and code on your site, which can help you take action to remove any malware and protect your website from further attacks.