How to scan for malware via SSH?

by May 1, 2023Malware, WordPress Security0 comments

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:

Kinsta – Premium WordPress Hosting
iTerm2 for MacOS
iTerm2 for MacOS

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:

  1. 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
  1. 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: -
  1. 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.

  1. 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.

  1. 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:

  1. 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.

  1. 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.

  1. 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.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments