Decoding PHP exploits and banning brute-force attackers



This post will discuss forensics on a Linux system and use basic forensics techniques to investigate two attacks made against a Linux web server. Specifically, this post is going to focus on reading and understanding information contained in log files. 
The first attack is an attempt by an adversary to gain un-authorised administrative access on a WordPress website by attacking the wp-login.php page.
The second attack is an obfuscated PHP script that, when decoded, attempts to find and exploit several PHP files commonly used by Joomla websites.


Before looking at either attack it is necessary to establish some prerequisite knowledge regarding Linux and how system events are logged.

                         
the '/var/log' directory on a Kali Linux system




Linux systems log all events in text files known simply as log files. There is no shortage of information to be found within these files; everything from kernel events, network events, SSH login attempts and even package upgrades/configurations are logged. Each event on a system is recorded and logged, with the log files themselves eventually being automatically rotated and compressed for archival purposes. The logs are a running history of the systems activity at any given moment in time. Unsurprisingly, these files are invaluable when forensic analysis of a system is required.

Log files are stored in the /var/log directory. Within this directory there are additional folders to help organise an otherwise overwhelming amount of files. Best practice dictates that anytime a log file is maintained, it should be kept somewhere within this directory. There are some occasions when this is not the case, but that is often the exception and not the norm. The contents of this directory may vary between Linux distributions and services installed.

Regularly checking log files is a good habit to develop. Often times system performance issues can be diagnosed by viewing process information as it is logged, and security incidents can be prevented when alerts are noticed and acted upon in a timely fashion. Active monitoring of log files allows for a 'finger on the pulse' approach to system administration.



Understanding which system events are logged to which file is the difference between finding the right information in a timely manner, or spending hours trudging through log files containing thousands of events. A few common examples are the following:

The syslog file contains a plethora of information. Many processes log to this file even if those same processes also log to a more specific file. An example of this are kernel events, which are logged to both the syslog and the kern.log file. Syslog is a great place to check at the start of any investigation into system behaviour or status.

The auth.log file contains information including (but not limited to) system power down events, system startup events and user session information.

A system power down event captured in the auth.log file


The dpkg.log file contains information regarding any package on the system that is upgraded, configured as part of an upgrade, installed, or uninstalled.

Python3 packages being upgraded. Version information is included in these log entries.


The kern.log file contains information regarding kernel events.

The Apache2 access.log and error.log files are specific to servers that have installed the Apache2 package. The access.log file contains information regarding any requests made for website resources hosted on the server, while the error.log file contains information regarding any Apache2 errors or warnings.


Reading a log file via the command line can be achieved with a combination of a few simple commands. These commands are: cat, tail, grep and less.
Cat is often used with grep to print data matching a user defined string directly to the terminal. The output can be 'piped' to less for easier viewing, if there is a lot of data to work with.
For following a log file and seeing live data as it is written, tail -f is used. Tail can also be combined with grep to only print lines matching a user defined string.
Opening and viewing the contents of a large log file can be achieved with the less command. This also allows the user to search for specific strings while navigating the file.

The tools themselves are simple and easy to use, but this does not make them any less useful over time. With experience using these tools it is possible to quickly and easily locate data of interest.

Examples of cat, tail, grep, less and wc.




Brute forcing is not subtle...

A common attack used against websites powered by WordPress is a brute force attack on the WordPress administration page. This page uses a predictable URL ending in /wp-login.php, making it a trivial task to find these pages online. Attackers will often automate the brute forcing process which generates dozens of login attempts per minute. Each login attempt is made using the HTTP POST method to the wp-login.php script located at http://website name here/wp-login.php. These attacks standout in the sites access log file:



Each log entry starts with the IP address being used by the attacker. This may be the address of a proxy server and not the attackers own connection.
A time stamp is the next piece of information in the log. The day, month, year, hour, minute and second of the request is logged precisely when it is received by the server.
The next piece of information is the HTTP method being used, and the specific resource data is being sent to. The POST method requests that the web server accept and process the data contained within the packet.
Next, we see a HTTP response code of '200' indicating the server accepted and successfully processed the data within the HTTP POST method. This does not indicate a successful login to the website but it does indicate a successful attempt at trying to login.
Finally, we see the total number of bytes that were transferred to the client. In each response from the server to the client, 3587 bytes were transferred.
Beyond the data included in the screenshot is additional information. The full URL of the web-page is listed, and information regarding the browser used to make the request with is also logged.

So how can we be sure this data is indicative of a brute forcing attack? The first clue is the number of attempts seen; in this case 221 from the same IP address. Another clue is the time frame of the attack; all 221 requests were received within a 35 minute period of time. A third clue is the IP address itself; the address range 195.22.124.0 - 192.22.127.255 is assigned to Poland, while the website and its developer are located in Australia.

This particular attack was stopped by adding the attackers IP address to IPtables with a 'drop' rule. The effectiveness of this approach can vary. If the attacker is using a proxy server to obfuscate his own IP address, than it would be trivial for him to use a new proxy and begin attacking again. If the attacker was using his own IP address without obfuscation, than blocking the address in IPtables is likely to be more effective.

IPtables will now 'drop' all received traffic from the listed IP address






Base64 encoding, PHP, and Joomla exploits...

The second attack begins with a heavily obfuscated HTTP GET request. The obfuscation used here has the specific purpose of making the malicious code contained within harder for a firewall to detect. This method may or may not work depending on the capabilities of the firewall. The flip side of that coin is that it is very obvious to a human that something is amiss - there is nothing normal about this request.

An HTTP GET request received by an unknown 3rd party. It includes a large amount of Base64 encoded data.



About half of the encoded content had to be removed to fit the entire request within the scope of a single screenshot. 
Immediately following this request were two responses from the web server indicating that two files, lol.php and css.php, were not found at the requested location: 

Web server responses sent back to the unknown 3rd party after processing the HTTP GET request.



The web servers response of '404' is reassuring that the attempted exploit has not succeeded. It is possible that the attacker is casting a wide net, hoping to find as many vulnerable servers as possible without performing any reconnaissance first. The web servers response includes the directory location '/libraries/joomla/'; it appears this exploit is written for Joomla.
The large string of text consisting of lowercase/uppercase letters and numerals, located at the 'eval(base64_decode' section, is Base64 encoded. Decoding this online with https://www.base64decode.org/ reveals the following:

Some of the malicious code is revealed; along with another layer of Base64 encoded data.



Revealed are the beginnings of a script, language as yet unknown, and more Base64 encoded text. Decoding the additional text reveals the final piece of this puzzle - a PHP script.

The first block of code from the PHP script. There are several more sections of code beyond this.



There are no more layers of obfuscation or other evasion methods being used now; the code can finally be analysed.

The script is written in PHP and begins by defining a function called 'http_get' (line 182). Within this function several parameters are set for a package named 'curl' to use when data is sent via HTTP. The function also requires that an argument, '($url)', is passed to it when it is called.

Next, the variable '$check' is declared (line 191) and given a value equal to the servers root path + '/libraries/joomla/css.php'.

A variable named '$text' is now declared (line 192). '$text's value is a call to the 'http_get' function with the argument '(http://IPaddress/~blessup/j/css.txt)'. This section of code appears to be making an HTTP GET request to what is presumably a server controlled by the attackers for the resource 'css.txt' located in the directory '~blessup/j/' on the server. The contents of this particular resource are not known.

Next, the variable '$open' is declared (line 193) and given the value 'fopen($check, 'w')'. The '$open' variable appears to open the file specified in the location of the '$check' variable declared earlier with write permissions. 

At this point only a function and three variables have been declared. The next few lines of code reveal more about the actual workflow of the script.


'fwrite($open, $text)' is the first line of code that is not a variable declaration or a function definition (line 195). It opens the file in '$open' which at this point contains the contents of the '$check' variable. It then attempts to write the contents of the '$text' variable into this file. The file is then closed with 'fclose($open)' (line 196).

Next, an if statement is presented (line 198). Beginning with 'if(file_exists($check)){', the if statement checks to see whether the file at the path specified in '$check' is present. If the file exists at the specified location the 'echo $check. "</br>"' code is executed. If the file is not present, the '}else echo "not exits"; echo "done.\n."; code is executed.


The remaining sections of code beyond this point all perform very similar functions. The extra 6 sections of code all amounted to variations of the following:

Additional code from the PHP script



The script finally comes to an end with an interesting block of code that reveals a bit about the attackers themselves. Several variables are declared which essentially amount to an email message being created and sent to the following addresses:

controllerjob1992@gmail.com
david@ama-ex.com

A personal touch; these email addresses appear to be controlled by the attackers

The email message, "Shellz: http://: . $_server", indicates that the end goal of this exploit is to obtain a command line shell on the exploited web server.

By looking at the IP addresses present in each of the arguments to the 'http_get' function it is possible to determine the servers being used by the attackers. It is reasonable to assume that any communication to the IP addresses 74.208.235.48 and 104.238.96.12 would indicate potential compromise of a web server. Additionally, any emails being sent from the web server to either 'controllerjob1992@gmail' or 'david@ama' would equally indicate a potential compromise.




The usefulness and importance of checking a servers log files cannot be overstated. Aside from their use in forensic activities, the log files are exceptionally useful when troubleshooting day-to-day problems, checking the server's overall health and generally making sure a server is doing what it should be doing.

Check your logs!






Comments

Popular posts from this blog

Exploiting OpenSSH 4.7 / OpenSSL 0.9.8 (Metasploitable 2)

Reverse engineering a simple C program part 1: Strings, ltrace, hexdump

Reverse engineering a simple C program part 2 : GDB