In this this series of articles and videos, I will explore some PHP malware code that has been publicly published. All the samples discussed are derived from a GitHub repository maintained by marcocesarato.
The advice from Syspect CyberSecurity Consulting is to always maintain solid web-server security through hardened configuration and monitoring, and vulnerability scanning both internal and external surfaces with a tool such as CISOfy’s Lynis or Greenbone’s GVM. For an example of solid LAMP stack server security you can visit the Syspect’s VPS Deploy WordPress GitHub repository which is a tool for automatically deploying a WordPress website on a hardened Linux VPS Server. If you don’t want to secure your own WordPress installation, you can hire a trained security consultant such as Syspect CyberSecurity Consulting, or you can use another 3rd party managed hosting provider.
In Part 1, below we will look at the source code for simple web-shells. In Part 2 we will look at how attackers will encode or encrypt the payload code, making it easier to find by threat hunters.
Part 1 – Simple WebShells
Let’s gain an understanding of what a web-shell is and take a look at some simple web-shells. Firstly, a web-shell is a malicious piece of code installed within your website code that allows an unwanted attacker to execute system commands or arbitrary PHP functions. This allows an attacker to ingress files from an external source, egress files from the server, modify existing web-application source code files or other system files, and add malicious scheduled events to the server.
In order to have the commands executed, the web-shell code must be placed somewhere specific in the source code that will be either executed on every page load, or contained within a single page. The best place would depend on the type of web-shell used as we will discuss in the samples below. Commands will execute at the permission level of the server service application (Apache, Nginx) although other accessible commands may contain their own authorization, so it is critical to effectively limit the file permissions on the server to reduce the attack surface. Folders and files in Linux have 3 levels of permissions, owner, group and anyone. It is particularly important to remove ‘anyone’ read and write permissions from all files possible, but even read and write permissions for files owned by the web-server application can be configured to limit the damage that can be done by a web-shell.
Sample #1 – Uploader.php
An uploader is a simple web-shell that can be used to import additional malware on to a web-server. These tools can come in many shapes and forms of code, but they all have the same function. Once the imported file has been imported onto the server, a command based web-shell can be used to manipulate, move, or otherwise use the file for nefarious purposes.
Sample #2 – simple_cmd.php
In this example, we see the most basic form of a web-shell. A form embedded on the page that will allow the user to make a GET or POST request to the server and have the submitted command executed and the results printed to the screen. By setting the width of the form input to 1 pixel, the form input box can be made virtually invisible. Prepared commands can then be copied and pasted into the minimal text input box. If there is output from the command, it will be displayed on the web-page itself after the form has been submitted.
Sample #3 – simple-backdoor.php
In this example, we see another basic form of web-shell. This example does not need an HTML form to retrieve the user command. Instead of accessing the rouge command from an input form, this example takes the command directly from the url supplied. The url would normally not contain such a command string, but with this code in place, the command is extracted from the user supplied url. Spaces should be replaced with a ‘+’ character in the supplied url which can also optionally be url encoded.
Sample #4 – smart.php
This example is a compact one-liner that is a little more difficult to analyze immediately. The use of the extract command extracts all the contents of the $_REQUEST variable into PHP variables with the same name as the array key and also assigns the values to the newly created variables. In PHP the contents of $_REQUEST array contains all $_GET and $_POST array variables. If the same variable name is used in $_GET and $_POST, the $_POST variable will be the value found in $_REQUEST. In this case, the malicious code is looking for an ‘a’ and ‘b’. Next, the ‘@’ symbol is used to suppress any error output, and is not required, but keeps any errors from printing to the page screen itself.
Sample #5 – accept_lang.php
This final example is Part 1 of this review of PHP malware shows a different way to extract and execute the attacker’s commands from the communication between the user and server. In this case, a commonly used cookie ‘HTTP_ACCEPT_LANGUAGE’ is used to pass the command to the server. The ‘HTTP_ACCEPT_LANGUAGE’ cookie is commonly used by browsers to specify which language the user prefers and thus it would not be blocked by the server or web-application firewall (WAF).
PHP Shell Execution Functions
Below is a list of all functions in PHP used to execute shell system commands, and check out this PHP manual page which includes other program execution functions: https://www.php.net/manual/en/ref.exec.php.
- system() – Execute an external program and display the output
- exec() – Execute an external program
- shell_exec() – Execute command via shell and return the complete output as a string
- eval() – Evaluate a string as PHP code (which can include any of the shell command functions)
- passthru() – Execute an external program and display raw output
- popen() – Opens process file pointer
- escapeshellcmd() – Escape shell metacharacters
- pcntl_exec() – Executes specified program in current process space
- backtick operator – Backticks in PHP are used to encapsulate any code that should be run as shell code
The most effective way to protect your website source code from attacks is to protect the access controls and maintain a hardened server configuration. Another important factor is working with developers and secure hosting providers who are honest and trustworthy. If you believe your website has been hacked, you can scan the source code files for commands such as the ones used in this tutorial, but since it’s very likely that the malware infecting your website is hidden using encoding or encryption, this approach will not provide an exhaustive search of malicious code injections. Most attackers too smart (and motivated) to simply add un-encoded source code which would allow threat hunters to search for and find it. We will discuss this topic more in Part 2.
You may instead use other 3rd party tools to find malware in your WordPress site. Some examples of WordPress security plugins that include malware scanning capability include:
The final tutorial in this series will demonstrate how to scan your site for malicious code and remove it using these tools. Also, check out this post about other critical ways you need to protect your WordPress and other website applications.